Android项目实践:黄金报价
来源:互联网 发布:c语言的发展历程 编辑:程序博客网 时间:2024/04/27 20:32
最近和朋友合作给别人写了一个APP,该APP功能比较简单,主要实现了一下功能:从网络获取黄金的现价,展示在主界面并实现自动播报该价格,并不断循环这个过程。现在开始逐步分析各个功能该如何实现。
一、从网络获取黄金的现价
1、下面先完成执行网络请求的工具类:GetUtil.java
<span style="font-size:14px;">public class GetUtil { public static String sendGet(String url) { String result=""; BufferedReader in=null; try{ String urlName=url; URL realUrl=new URL(urlName); //打开和URL之间的连接 URLConnection conn=realUrl.openConnection(); //设置通用的请求属性 conn.setRequestProperty("accept", "*/*"); conn.setRequestProperty("connection", "Keep-Alive"); conn.setRequestProperty("user-agent", "Mozilla/4.0 (compatible;MSIE 6.0;Windows NT 5.1;SV1)"); //建立实际连接 conn.connect(); //定义BufferedReader输入流来读取URL响应 in=new BufferedReader(new InputStreamReader(conn.getInputStream())); String line; //逐行读取数据,如果数据不为空,则放入result中 while((line=in.readLine())!=null) { result+="\n"+line; } } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { //如果网络异常,获取数据失败,返回空 result=""; return result; //e.printStackTrace(); } finally { //释放资源 try{ if(in!=null) { in.close(); } } catch (IOException e) { e.printStackTrace(); } } return result; }}</span>2、对特定网页进行解析,由于黄金的实时价格在某个网站上实时刷新,所以我们可以抓取这个网页的html源码,然后利用正则表达式匹配出需要提取的内容:
这里给出一个网页:http://www.sincerehk.com/zh-hk/index.aspx
对其HTML源码进行分析:
<td width=22% height=18 valign=top class=big> <div align=left>港金</div> </td> <td width=35% valign=top class=big_b> <div align=left>11,376<!--買 / 賣--></div>
<td width=22% height=18 valign=top class=big> <div align=left>倫敦金</div> </td> <td width=35% valign=top class=big_b> <div align=left>1225.40<!--買 / 賣--></div>我们需要提取的是其中的数字,所以正则表达式可以写成这样:
<.*?>\\w*金<.*?><.*?> <.*?><.*?>(.*?)<!--.*?/.*?--><.*?>
得到正则表达式后,我们可以利用java的Pattern类和Matcher类实现匹配,代码片段如下:
Pattern p = Pattern.compile("<.*?>\\w*金<.*?><.*?> <.*?><.*?>(.*?)<!--.*?/.*?--><.*?>");Matcher m = p.matcher(response); //response为获取的数据字符串while (m.find()) { MatchResult mr = m.toMatchResult(); gold[i] = mr.group(1); //将匹配成功的字符串放进一个字符串数组 i++; }3、由于网路操作是耗时操作,所以我们需要在子线程完成以上操作:以下是部分的MainActivity.java:
thread = new Thread() { @Override public void run() { while (true){ try { lock.lock(); //对该线程进行加锁 int i = 0; gold = new String[2]; response = GetUtil.sendGet("http://www.sincerehk.com/zh-hk/index.aspx"); //如果获取数据失败 if(response=="") { handler.sendEmptyMessage(0x123); break; //直接跳出循环 } //正则表达匹配数据 Pattern p = Pattern.compile("<.*?>\\w*金<.*?><.*?> <.*?><.*?>(.*?)<!--.*?/.*?--><.*?>"); Matcher m = p.matcher(response); while (m.find()) { MatchResult mr = m.toMatchResult(); gold[i] = mr.group(1); i++; } //发送通知,告诉主线程刷新数据以及播报语音 handler.sendEmptyMessage(0x123); //阻塞该线程,等待通知 cond.await(); }catch (InterruptedException e){ e.printStackTrace(); }catch (JSONException e) { e.printStackTrace(); }finally { lock.unlock(); } } } };thread.start();
二、语音播报获取的数据
这里使用百度语音在线合成的API,先去百度语音开放平台注册成为开发者,然后他会有详细教程,这里不再赘述。导入所需的sdk包后,在MainActivity.java文件里面,只需写下如下代码即可:
speechSynthesizer = new SpeechSynthesizer(getApplicationContext(),"holder" ,MainActivity.this);speechSynthesizer.setApiKey("TBSiHQcwMTsAmDUzh386tash", "40cd364811b4933b2133ff3qw313ceff");speechSynthesizer.speak(floatGoldPrice); //这里传入需要读出的内容三、循环
为了实现播放完语音后,自动开始获取新的数据并且再次刷新以及播报,我们需要在主线程和子线程之间进行通信,思路如下:在子线程获取数据结束后,即如上面代码所示,将该线程await()阻塞,然后在Handler中,写刷新数据和播报语音的代码,由于播报语音使用了百度在线语音合成的SDK,该SDK提供了一个监听语音的接口:SpeechSynthesizerListener,实现该接口以及其未完成的方法,其中有一个方法是onSpeechFinish(SpeechSynthesizer synthesizer)用于实现朗读完成后的方法,所以我们可以在这个方法内写入如下代码:@Overridepublic void onSpeechFinish(SpeechSynthesizer synthesizer) { try{ lock.lock(); //加锁 cond.signalAll(); //唤醒子线程 lock.unlock(); //释放锁 }catch (Exception e){ e.printStackTrace(); } }以上,就是完成该项目的全部思路和流程,下面附上完整的MainActivity.java,由于UI界面过于简单,只有两个按钮,一个文本框,所以就不提供了。package org.gold.goldpriceplay;import android.annotation.TargetApi;import android.os.Build;import android.os.Bundle;import android.os.Handler;import android.os.Message;import android.speech.tts.TextToSpeech;import android.speech.tts.UtteranceProgressListener;import android.support.v7.app.AppCompatActivity;import android.util.Log;import android.view.View;import android.widget.Button;import android.widget.TextView;import android.widget.Toast;import com.baidu.speechsynthesizer.SpeechSynthesizer;import com.baidu.speechsynthesizer.SpeechSynthesizerListener;import com.baidu.speechsynthesizer.publicutility.SpeechError;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;import java.math.BigDecimal;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import java.util.regex.MatchResult;import java.util.regex.Matcher;import java.util.regex.Pattern;//import com.baidu.tts.client.SpeechError;//import com.baidu.tts.client.SpeechSynthesizer;//import com.baidu.tts.client.SpeechSynthesizerListener;public class MainActivity extends AppCompatActivity implements SpeechSynthesizerListener { Button get; Button stop ; TextToSpeech tts; private SpeechSynthesizer speechSynthesizer; // 0代表执行抓取 boolean flag = false ; private final Lock lock = new ReentrantLock(); private final Condition cond = lock.newCondition(); Thread thread; TextView London; //代表服务器响应的字符串 String response; String[] gold = new String[2]; Handler handler=new Handler() { @TargetApi(Build.VERSION_CODES.LOLLIPOP) @Override public void handleMessage(Message msg) { if(msg.what==0x123) { if(response=="") { get.setEnabled(true); stop.setEnabled(false); Toast.makeText(MainActivity.this,"您的网络连接有问题,请重试",Toast.LENGTH_SHORT).show(); }else { speechSynthesizer.speak(gold[0]); London.setText(gold[0]); } } } }; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.content_main); get= (Button) findViewById(R.id.start); stop = ( Button )findViewById(R.id.stop); stop.setEnabled(false); speechSynthesizer = new SpeechSynthesizer(getApplicationContext(),"holder" ,MainActivity.this); speechSynthesizer.setApiKey("TBSiHQcwMTsAmDUzh386t7hh", "40cd364811b4933b2133ff35d313ceff"); London= (TextView) findViewById(R.id.LondonPrice); get.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { get.setEnabled(false); flag = true; stop.setEnabled(true); thread = new Thread() { @Override public void run() { while (flag){ try { lock.lock(); int i = 0; gold = new String[2]; response = GetUtil.sendGet("http://www.sincerehk.com/zh-hk/index.aspx"); if(response=="") { handler.sendEmptyMessage(0x123); break; } Pattern p = Pattern.compile("<.*?>\\w*金<.*?><.*?> <.*?><.*?>(.*?)<!--.*?/.*?--><.*?>"); Matcher m = p.matcher(response); while (m.find()) { MatchResult mr = m.toMatchResult(); gold[i] = mr.group(1); i++; } handler.sendEmptyMessage(0x123); cond.await(); }catch (InterruptedException e){ e.printStackTrace(); } catch (JSONException e) { Log.d("chenyu", "json错误"); e.printStackTrace(); }finally { lock.unlock(); } } } }; thread.start(); } }); stop.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { flag = false; get.setEnabled(true); stop.setEnabled(false); } }); } @Override public void onStartWorking(SpeechSynthesizer synthesizer) {// logDebug("开始工作,请等待数据..."); } @Override public void onSpeechStart(SpeechSynthesizer synthesizer) {// logDebug("朗读开始"); } @Override public void onSpeechResume(SpeechSynthesizer synthesizer) {// logDebug("朗读继续"); } @Override public void onSpeechProgressChanged(SpeechSynthesizer synthesizer, int progress) { // TODO Auto-generated method stub } @Override public void onSpeechPause(SpeechSynthesizer synthesizer) {// logDebug("朗读已暂停"); } @Override public void onSynthesizeFinish(SpeechSynthesizer arg0) { // TODO Auto-generated method stub } @Override public void onSpeechFinish(SpeechSynthesizer synthesizer) {// logDebug("朗读已停止"); try{ lock.lock(); cond.signalAll(); lock.unlock(); }catch (Exception e){ e.printStackTrace(); } } @Override public void onBufferProgressChanged(SpeechSynthesizer synthesizer, int progress) { // TODO Auto-generated method stub } @Override public void onCancel(SpeechSynthesizer synthesizer) {// logDebug("已取消"); } @Override public void onError(SpeechSynthesizer synthesizer, SpeechError error) {// logError("发生错误:" + error.errorDescription + "(" + error.errorCode + ")"); } @Override public void onNewDataArrive(SpeechSynthesizer synthesizer, byte[] audioData, boolean isLastData) {// logDebug("新的音频数据:" + audioData.length + (isLastData ? "(end)" : "")); }}
2 0
- Android项目实践:黄金报价
- 软件项目报价方法
- 软件项目报价方法
- UI项目报价
- Android APP报价参考
- 发电报价项目开发设想
- 浅谈软件外包项目报价
- 浅谈软件外包项目报价
- 浅谈软件外包项目报价
- 浅谈软件外包项目报价
- 软件项目开发报价指南
- Android项目实践
- android 项目实践分享
- zz浅谈软件外包项目报价
- 软件项目管理系统-报价管理
- Web开发项目估算报价的方法
- Android+SSH综合项目实践
- android实践项目三玩转listview
- 八数码之双广解决方法
- poj 1979 Red and Black
- 蓝桥杯 历届试题 加法变乘法
- 三分之一的程序猿之重新定义“创业”!
- CSS3 入门5
- Android项目实践:黄金报价
- struts2整合hibernate
- stack栈
- CSS3 入门6
- Java 中的 Random方法小结
- 如何分析业务问题
- Android Studio(AS)-->导入项目
- 程序开发中那些莫名奇妙的bug
- 软件开发Java之奇数最后一个字符输出乱码问题