Download presentation
Presentation is loading. Please wait.
1
Chapter 13 Android 實戰演練
2
線上匯率查詢
3
線上匯率查詢 本節範例將實作一個簡單的線上費率查詢,利用Url查詢台灣銀行的即時匯率,欲查詢的網址為 此網頁中每隔幾分鐘會更新一次匯率,所以範例程式在一開啟時會抓取此網頁並將網頁內容解析後將匯率資料取出
4
線上匯率查詢 台灣銀行線上即時匯率查詢
5
線上匯率查詢 程式範例結果: 由於此網頁資訊為台幣與其他各幣值的匯率,所以範例程式當中以台幣為主來讓使用者選擇不同貨幣的幣值查詢,利用Spinner元件讓使用者選擇要查詢的貨幣,接著按下【匯率】按鈕後利用AlertDialog將結果顯示出來。 此程式設計上不會自動更新匯率資料,所以使用者若未重新啟動程式,顯示的資料會以開啟時的資料為主。
6
線上匯率查詢 res/values/arrays.xml 設定Spinner
<?xml version="1.0" encoding="UTF-8"?> <resources> <string-array name="money"> <item>美金</item> <item>港幣</item> <item>英鎊</item> <item>澳幣</item> <item>加拿大幣</item> <item>新加坡幣</item> <item>瑞士法郎</item> <item>日圓</item> <item>南非幣</item> <item>瑞典幣</item> <item>紐元</item> <item>泰幣</item> <item>菲國比索</item> <item>印尼幣</item> <item>歐元</item> <item>韓元</item> <item>越南盾</item> <item>馬來幣</item> <item>人民幣</item> </string-array> </resources> 設定Spinner
7
線上匯率查詢 res/layout/main.xml 設計程式外觀,在本範例中利用RelativeLayout來完成
<?xml version="1.0" encoding="utf-8"?> <RelativeLayout xmlns:android=" android:layout_width="fill_parent" android:layout_height="fill_parent" > <TextView android:text="台幣 換 " android:textSize="30sp" android:layout_marginTop="10px" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Spinner <Button android:text="匯率" android:textSize="22sp" android:layout_height="wrap_content" /> </RelativeLayout> 設計程式外觀,在本範例中利用RelativeLayout來完成
8
線上匯率查詢 程式部分則是利用HttpURLConnection將台灣銀行網頁資料讀進來做分析,抓取網頁的程式碼如下:
HttpURLConnection httpUrlconnection = null; // Web URL為上述台灣銀行匯率網址 URL url = new URL(WebURL); httpUrlconnection = (HttpURLConnection)url.openConnection(); httpUrlconnection.setRequestMethod("GET"); httpUrlconnection.setDoInput(true); httpUrlconnection.setDoOutput(true); httpUrlconnection.connect(); 先建立一個URL物件,WebURL為上述台灣銀行查詢匯率的網址,接著設定HttpURLConnection後建立連線,由於預設Request方法為GET,若要將Requet方法改成其他的方法只要將「【setRequestMethod("GET")】」中的GET改成如POST、HEAD、OPTIONS、PUT、DELETE和TRACE這幾個方法即可,最後利用connect()建立連線。
9
線上匯率查詢 建立連線後,程式必須將網頁資料讀進一個Buffer中,以便後續分析,程式如下
BufferedReader in = new BufferedReader( new InputStreamReader(httpUrlconnection.getInputStream())); String decodedString; while ((decodedString = in.readLine()) != null) { urlData += decodedString; } in.close(); 立一BufferReader物件,讀取目標為httpUrlconnection.getInputStream(),接著將網頁資料利用迴圈方式一行一行的將網頁資料儲存在自定義的urlData字串當中
10
線上匯率查詢 擷取的網頁原始碼 各個貨幣的匯率包在<td class= "decimal">…</td>中,而依序為美金現金匯率的買入和賣出、即期匯率的買入和賣出,接著為港幣現金匯率的買入和賣出、即期匯率的買入和賣出。
11
線上匯率查詢 分析網頁 start = urlData.indexOf("<td class=\"decimal\">", end+1); end = urlData.indexOf("</td>", start+1); temp = urlData.substring(start+20, end); if ( !temp.equals("-") ) buy_cash.add(temp); else buy_cash.add("無資料"); 所以我們將「【<td class= "decimal">】」設為起點,「【</td>】」設為終點,抓取中間的值依序以每四個為一貨幣存入我們定義的List當中 每次擷取利用indexOf方法依照我們設定的起點和終點將urlData的位置給存入start和end中,接著利用substring方法將起點和終點之間的字串,即匯率,儲存至List中。
12
擲骰子
13
擲骰子遊戲簡介 本節範例實作一擲骰子比大小遊戲,使用的感應器為加速感應器,經由程式計算出的加速度大於某一數值時就代表擲骰。
遊戲者分別擲骰進行大小比較之遊戲,骰子點數較大者勝,如遇平手則重新擲骰。 遊戲中也分成一顆骰子與兩顆骰子,可由使用者自行選擇,程式畫面如下頁圖所示。
14
擲骰子遊戲畫面-1
15
擲骰子遊戲畫面-2
16
擲骰子遊戲程式碼-1 程式一開始可選擇: 1. 開始遊戲 2. 離開遊戲 3. 說明。 啟動遊戲後,使用者需先選擇玩法,分別有一顆或兩顆骰子,此處透過Intent方式去啟動另一個活動,程式碼如下頁所示。
17
擲骰子遊戲程式碼-2 啟動遊戲程式碼: btnNewGame.setOnClickListener(new OnClickListener() { public void onClick(View v) setContentView(R.layout.dicenumber); btnOneDice = (Button) findViewById(R.id.btnOneDice); btnTwoDice = (Button) findViewById(R.id.btnTwoDice); btnOneDice.setOnClickListener(new /* 設定一顆骰子的Intent並傳送 */ Intent intent1 = new Intent(); intent1.setClass(DiceGameEX.this,OneDice.class); startActivity(intent1); } }); btnTwoDice.setOnClickListener(new OnClickListener() public void onClick(View v) { /* 設定兩顆骰子的Intent並傳送 */ Intent intent1 = new Intent(); intent1.setClass(DiceGameEX.this,TwoDice.class); startActivity(intent1); } });
18
擲骰子遊戲程式碼-2 離開遊戲程式碼: 離開遊戲則是使用警告視窗來提示使用者是否要離開
btnQuitGame.setOnClickListener(new OnClickListener() { public void onClick(View v) AlertDialog.Builder builder = new AlertDialog.Builder(DiceGameEX.this); builder.setIcon(R.drawable.alert_dialog_icon); builder.setTitle("離開程式"); builder.setMessage("是否確定要離開?"); builder.setPositiveButton("Yes", new DialogInterface.OnClickListener() public void onClick(DialogInterface dialog, int whichButton) finish(); } }); builder.setNegativeButton("No", builder.show(); 離開遊戲則是使用警告視窗來提示使用者是否要離開
19
擲骰子遊戲程式碼-3 onCreate程式碼:
/* 設定畫面不旋轉 */ setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_NOSENSOR); /* 初始化元件 */ btnOneStart =(Button) findViewById(R.id.btnOneStart); btnOneStop = (Button) findViewById(R.id.btnOneStop); btnOneReturn = (Button) findViewById(R.id.btnOneReturn); textPlay = (TextView) findViewById(R.id.textPlay); textWin = (TextView) findViewById(R.id.textWin); /* 使用SensorManager取得系統感應器 */ sensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE); /* 設定為加速度感應器 */ sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); /* 設定骰子旋轉動畫 */ diceAnimation = new RotateAnimation(0.0f, f, Animation.RELATIVE_TO_SELF, 2.0f, Animation.RELATIVE_TO_SELF, 2.0f); 在選擇完骰子數量後,首先程式會在【onCreate】中作設定及初始化元件的動作
20
擲骰子遊戲程式碼-4 返回及停止程式碼: protected void onResume() { /* 重新設定遊戲參數 */ playerTurn = 1; playerOne = 0; playerTwo = 0; count = 0; finish = false; textPlay.setText("開始擲骰"); textWin.setText(""); /* 向系統註冊感測器 */ sensorManager.registerListener (lsn, sensor, SensorManager.SENSOR_DELAY_UI ); super.onResume(); protected void onPause() /* 向系統註銷感測器 */ sensorManager.unregisterListener(lsn); super.onPause(); 在擲骰畫面中有三個按鈕,分別為【1. 開始】、【2. 返回】、【3. 停止】,其中【開始】與【返回】按鈕的功能分別撰寫於不同的函式中,【開始】按鈕功能為重新啟動新的一局;而【返回】按鈕則是直接呼叫系統函式【finish()】結束此活動、退回主選單。【停止】按鈕是將加速度感測器功能停止。
21
擲骰子遊戲程式碼-5 接著就是加速度感測器的部分,在【onSensorChanged】中設定感測Threshold值為800及搖動偵測時間間隔為1秒,利用Math.abs數學函式計算出加速度值。 並將遊戲規則寫於此函式內,使遊戲更為完整。 因程式碼過多在此就不列出,詳細考參考備註欄。 完整程式碼請自行參考光碟【Ch13\DiceGame】資料夾的DiceGameEX.java、 OneDice.java、TwoDice.java、Help.java等程式,佈局文件則請參考【Ch13\DiceGame\res\layout】資料夾下的 XML 檔案。
22
來電黑名單
23
來電黑名單 本節範例實作一個來電黑名單,只要在黑名單內的電話打來,程式會自動將其轉為靜音模式,而這些黑名單的資料會儲存在SD卡中的BlackList資料夾中 在程式中,我們也將黑名單註冊為Service,這樣即使退出了黑名單的程式也可以繼續保持黑名單功能。程式總共分為兩部分,第一部分為Activity,用來讀取電話連絡人資訊以及設定黑名單,第二部分為Service,當有電話來電時會去檢查此來電是否為名單上的電話號碼,若是則將此通電話鈴聲設為靜音。
24
來電黑名單 程式範例結果圖:
25
來電黑名單 程式一開始會抓取手機的連絡人資料並顯示在電話簿的Tab中,程式碼如下:
public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); // 抓取通訊錄的聯絡人資料 GetContact(); // 建立Tab CreateTab(); // 將連絡人資訊顯示在Tab1 CreatePhoneContactTab(); // 抓取SD卡中的黑名單列表 GetBlackList(); // 將黑名單資訊顯示在Tab2 CreateBlackListTab(); }
26
來電黑名單 利用ContentResolver來抓取系統中的連絡人資料:
ContentResolver cr = getContentResolver(); Cursor c = cr.query(Contacts.Phones.CONTENT_URI, null, null, null, null); phoneInfo_Name = new String[c.getCount()]; phoneInfo_Number = new String[c.getCount()]; ContactInfo = new ArrayList<String>(); // 先看抓取之 cusor 是否有資料 if (c.moveToFirst()) { int nameColumn = c.getColumnIndex(Phones.NAME); int phoneColumn = c.getColumnIndex(Phones.NUMBER); int index = 0; do { phoneInfo_Name[index] = c.getString(nameColumn); phoneInfo_Number[index] = c.getString(phoneColumn); ContactInfo.add((phoneInfo_Name[index] + " : " + phoneInfo_Number[index])); index++; } while (c.moveToNext()); Collections.reverse(ContactInfo); }
27
來電黑名單 接著顯示利用【Adapter】將【ContactInfo】顯示在電話簿的Tab中,如下: v_contact = (ListView)findViewById(R.id.contactList); adapterContact = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1, ContactInfo); lv_contact.setAdapter(adapterContact); // 設定lv_contact的itemClick事件 lv_contact.setOnItemClickListener(contact_Listener);
28
來電黑名單 檢查是否有黑名單的資料夾: String strDirectoy ="/sdcard/BlackList";
boolean success = (new File(strDirectoy)).mkdir(); if (success) { // Log } 接著系統去抓取在SD卡中是否有已存之黑名單列表,若有則讀取至黑名單Tab中,由於黑名單資料存放在SD卡中的【BlackList】資料夾下,故一開始必須檢查此資料夾是否存在,若不存在則要新建一資料夾
29
來電黑名單 檢查blackList.txt是否存在:
// 檢查SDCard中的BlackList資料夾內是否有blackList.txt檔案,若無則建立新檔案 File f; f = new File("/sdcard/BlackList/blackList.txt"); if( !f.exists() ){ f.createNewFile(); } // 將檔案中的黑名單讀取至file_BlackList中 FileReader fr = new FileReader( "/sdcard/BlackList/blackList.txt" ); BufferedReader br = new BufferedReader( fr ); String temp = br.readLine(); while( temp != null ) { file_BlackList.add(temp); temp = br.readLine(); 而我們將黑名單資料建立在【BlackList】資料夾下的blackList.txt中,所以接著檢查此檔案是否存在,若不存在則建立一個新檔案,若已有檔案存在則將檔案讀取至程式當中
30
來電黑名單 加入和移除黑名單: OnItemClickListener contact_Listener = new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { boolean hasRemoved = false; Iterator iterator = file_BlackList.iterator(); while(iterator.hasNext()) { if ( ContactInfo.get(arg2).equals(iterator.next().toString()) ) now_Remove = arg2; showDialog(REMOVE_BLACKLIST); hasRemoved = true; break; } if ( !hasRemoved ) now_Add = arg2; showDialog(ADD_BLACKLIST); }; 同電話簿一樣將其顯示在黑名單Tab中。在範例中只要點擊電話簿的號碼即可將此號碼加入或移除黑名單,當號碼非黑名單時,點擊為加入黑名單,當號碼已經在黑名當時點擊即可移除黑名單。而在黑名單部分的號碼點擊後即可移除黑名單。下列程式碼為點擊電話簿時程式碼部份:
31
來電黑名單 加入和移除黑名單: OnItemClickListener blackList_Listener = new OnItemClickListener(){ @Override public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) { // TODO Auto-generated method stub TextView temp = (TextView)arg1; String removeDate = temp.getText().toString(); int i = 0; Iterator iterator = ContactInfo.iterator(); while(iterator.hasNext()) { if ( removeDate.equals(iterator.next().toString())) now_Remove = i; showDialog(REMOVE_BLACKLIST); break; } i++; }; 程式判斷此號碼是否在黑名單內,若是則會呼叫【showDialog】來詢問使用者是否要將其移除黑名單,若否,則會詢問使用者是否要將此號碼加入黑名單。當使用者點擊黑名單Tab內的號碼時,則只有移除此號碼的功能
32
來電黑名單 加入和移除黑名單: @Override protected Dialog onCreateDialog(int id) {
switch (id) { case ADD_BLACKLIST: return new AlertDialog.Builder(BlackList.this) .setIcon(android.R.drawable.stat_sys_warning) .setTitle("是否將此號碼加入黑名單") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { file_BlackList.add(ContactInfo.get(now_Add)); UpdateBlackListFile(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { .create(); case REMOVE_BLACKLIST: return new AlertDialog.Builder(BlackList.this) .setIcon(android.R.drawable.stat_sys_warning) .setTitle("是否將此號碼移除黑名單") .setPositiveButton("確定", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int whichButton) { file_BlackList.remove(ContactInfo.get(now_Remove)); UpdateBlackListFile(); } }) .setNegativeButton("取消", new DialogInterface.OnClickListener() { .create(); return null; 自訂了兩個警告視窗
33
來電黑名單 更新黑名單狀態 public void UpdateBlackListFile() { // 將黑名單依照字母排序 Collections.sort(file_BlackList, String.CASE_INSENSITIVE_ORDER); // 更新黑名單的adapter adapterBlackList.notifyDataSetChanged(); try { FileWriter fw = new FileWriter( "/sdcard/BlackList/blackList.txt", false ); BufferedWriter bw = new BufferedWriter( fw ); Iterator iterator = file_BlackList.iterator(); while(iterator.hasNext()) { bw.write(iterator.next().toString()); bw.newLine(); } bw.close(); th.clearFocus(); catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); 當使用者選擇將號碼加入黑名單時就將此號碼加入【file_BlackList】當中,而當使用者選擇將號碼移除黑名單時則將此號碼至【file_BlackList】移除,由於加入以及移除都會更改黑名單的狀態,所以在此呼叫自定義的【UpdateBlackListFile()】來更新黑名單狀態
34
來電黑名單 Service部份 public class PhoneCallListener extends PhoneStateListener { public void onCallStateChanged(int state, String incomingNumber) super.onCallStateChanged(state, incomingNumber); AudioManager am = (AudioManager) getSystemService(Context.AUDIO_SERVICE); Log.i("INCOMING", incomingNumber); switch (state) case TelephonyManager.CALL_STATE_IDLE: if ( am != null ) am.setRingerMode(AudioManager.RINGER_MODE_NORMAL); } break; case TelephonyManager.CALL_STATE_RINGING: if ( IsInBlackList(incomingNumber) ) am.setRingerMode(AudioManager.RINGER_MODE_SILENT); Context context1 = getApplicationContext(); CharSequence text1 = "黑名單狀態"; int duration1 = Toast.LENGTH_LONG; // 設定停留長短 Toast.makeText(context1, text1, duration1).show(); default: 而設定靜音模式則需使用到AudioManager的setRingerMode來設定為NORMAL或是SILENT。而在收到為CALL_STATE_RINGING狀態時,則會去檢查號碼是否為黑名單
35
Q&A
Similar presentations