2012年4月20日 星期五

[Android AppWidget]Taiwan Gold Price Widget 台灣地區銀樓即時黃金牌價



Android Home Screen App Widget 設計流程:
  1. 規劃App Widget的大小以及更新時間,在res/xml/裡新增一份XML文件,命名為 appwidget_provider.xml (可以自行命名)
  2. 規劃App Widget 的UI,修改 res/layout/main.xml
  3. 撰寫 App Widget 主程式
  4. 編輯 AndroidManifest.xml,設定 App Widget 的更新事件: android.appwidget.action.APPWIDGET_UPDATE

摘要說明,設計一個最基本的App Widget至少需要以下4個檔案:
  1. res/xml/appwidget_provider.xml (可以自行命名)
  2. res/layout/main.xml
  3. src// App Widget 主程式.java
  4. AndroidManifest.xml

<TWGoldGroupWidget.java> --- App Widget 主程式
   1: package com.android.twgoldgroupwidget;
   2:  
   3: import java.io.BufferedReader;
   4: import java.io.InputStreamReader;
   5: import java.net.HttpURLConnection;
   6: import java.net.URL;
   7: import java.util.Timer;
   8: import java.util.TimerTask;
   9:  
  10: import android.appwidget.AppWidgetManager;
  11: import android.appwidget.AppWidgetProvider;
  12: import android.content.ComponentName;
  13: import android.content.Context;
  14: import android.util.Log;
  15: import android.widget.RemoteViews;
  16: import android.widget.Toast;
  17:  
  18: public class TWGoldGroupWidget extends AppWidgetProvider {
  19:        
  20:     int start, end, counter; 
  21:     URL url;
  22:     HttpURLConnection httpUrlconnection;
  23:     String TWGoldGroupWebURL = "http://www.gck99.com.tw/gold.asp";
  24:     String urlData, informationDate, askPrice, bidPrice, goldPrice;
  25:     RemoteViews remoteViews;
  26:     int appWidgetId;
  27:             
  28:     @Override
  29:     public void onDeleted(Context context, int[] appWidgetIds) {
  30:            Log.i("onDeleted", "OK");
  31:         Toast.makeText(context, "Gold Widget onDeleted()", Toast.LENGTH_LONG).show();
  32:     }
  33:     
  34:     
  35:     @Override
  36:     public void onDisabled(Context context) {
  37:         // 當最後一個  AppWidget 被刪除時,會執行 onDisabled
  38:         Log.i("onDisabled", "OK");
  39:         super.onDisabled(context);
  40:         android.os.Process.killProcess(android.os.Process.myPid());
  41:     }
  42:     
  43:     
  44:     @Override
  45:     public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
  46:            Timer timer = new Timer();
  47:            timer.scheduleAtFixedRate(new MyTimerTask(context, appWidgetManager), 0, 3600000L);
  48:         super.onUpdate(context, appWidgetManager, appWidgetIds);
  49:     }
  50:  
  51:     
  52:     private class MyTimerTask extends TimerTask {
  53:         // MyTimerTask 定時執行動作
  54:         AppWidgetManager appWidgetManager;
  55:         RemoteViews remoteViews;
  56:         ComponentName thisWidget;        
  57:         
  58:         public MyTimerTask(Context context, AppWidgetManager appWidgetManager) {
  59:                 
  60:             Log.i("MyTimerTask","OK");
  61:             this.appWidgetManager = appWidgetManager;
  62:             remoteViews = new RemoteViews(context.getPackageName(), R.layout.main);
  63:             thisWidget = new ComponentName(context, TWGoldGroupWidget.class);
  64:                 
  65:         }
  66:             
  67:         public void run() {
  68:             // 顯示台灣地區銀樓即時黃金牌價
  69:             getTWGoldGroupResults();
  70:             remoteViews.setTextViewText(R.id.showTextView,
  71:                                         "台灣地區銀樓即時黃金牌價\n"+
  72:                                         "賣出 "+askPrice+" 元/台錢\n"+
  73:                                         "買進 "+bidPrice+" 元/台錢\n"+
  74:                                         informationDate);                        
  75:             appWidgetManager.updateAppWidget(thisWidget, remoteViews);
  76:         }
  77:     }
  78:         
  79:  
  80:     public void getTWGoldGroupResults() {
  81:           // 顯示台灣地區銀樓即時黃金牌價
  82:            // 讀取網頁資料,並將資料存放在於 urlData
  83:         urlData = GetURLData(TWGoldGroupWebURL , 20*1024);
  84:         // 剖析 urlData,擷取黃金存摺牌價資料
  85:         TWGoldGroupParser(urlData);
  86:     }
  87:  
  88:  
  89:     public String GetURLData(String WebURL, int ReadSize){
  90:            // 讀取網頁資料,並將資料存放在 urlData 
  91:            urlData = null; 
  92:            try { 
  93:                url = new URL(WebURL); 
  94:                httpUrlconnection = (HttpURLConnection) url.openConnection(); 
  95:                httpUrlconnection.setDoInput(true); 
  96:                httpUrlconnection.setDoOutput(true); 
  97:                httpUrlconnection.connect();
  98:                BufferedReader bufReader = new BufferedReader(
  99:                                            new InputStreamReader(httpUrlconnection.getInputStream())); 
 100:                String decodedString; 
 101:                while ((decodedString = bufReader.readLine()) != null) { 
 102:                    urlData += decodedString;
 103:                    if (urlData.length() > ReadSize)
 104:                        break;
 105:                } 
 106:                bufReader.close();
 107:                httpUrlconnection.disconnect();
 108:            } 
 109:            catch(Exception e){ 
 110:                Log.e("ERROR", e.toString()); 
 111:            } 
 112:            return urlData;   
 113:     } 
 114:         
 115:         
 116:     public void TWGoldGroupParser( String urlData ){
 117:         // 剖析 GCK urlData,擷取黃金牌價資料
 118:         String temp = null;
 119:         // 擷取【掛牌時間】
 120:         end = 0; 
 121:         start =  urlData.indexOf("<font size=\"1\">", end+1);
 122:         end =  urlData.indexOf("</font>", start+1);
 123:         informationDate = urlData.substring(start+17, end);
 124:         // 擷取黃金牌價資料
 125:         end = 0;
 126:         for (counter = 1 ; counter <= 6 ; counter++)
 127:         {
 128:             start =  urlData.indexOf("font-size:9pt;", end+1); 
 129:             
 130:             switch (counter) {
 131:             case 3:
 132:                 end =  urlData.indexOf("</span>", start+1);
 133:                 temp = urlData.substring(start+19, end);
 134:                 askPrice = temp;
 135:                 break;
 136:                 
 137:             case 6:
 138:                 end =  urlData.indexOf("</span>", start+1);
 139:                 temp = urlData.substring(start+19, end);
 140:                 bidPrice = temp;
 141:                 break;
 142:                 
 143:             default:
 144:                 end =  start + 16;
 145:                 break;
 146:             }
 147:         }
 148:      }
 149:         
 150: }

<main.xml> --- App Widget UI
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
   3:     android:layout_width="wrap_content"
   4:     android:layout_height="wrap_content"
   5:     android:background="@drawable/widget"
   6:     android:gravity="center"
   7:     android:orientation="vertical" >
   8:  
   9: <TextView
  10:     android:id="@+id/showTextView"
  11:     android:layout_width="wrap_content"
  12:     android:layout_height="wrap_content"
  13:     android:gravity="center"
  14:     android:text="@string/app_name"
  15:     android:textColor="@android:color/black"
  16:     android:textSize="11dp"
  17:     android:typeface="serif" />
  18:  
  19: </LinearLayout>

<appwidget.xml> --- 定義 appwidget-provider
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
   3:     android:minWidth="146dp"
   4:     android:minHeight="72dp"
   5:     android:initialLayout="@layout/main">
   6: </appwidget-provider>

<Android.Manifest.xml>
   1: <?xml version="1.0" encoding="utf-8"?>
   2: <manifest xmlns:android="http://schemas.android.com/apk/res/android"
   3:     package="com.android.twgoldgroupwidget"
   4:     android:versionCode="1"
   5:     android:versionName="1.0" android:installLocation="auto">
   6:  
   7:     <uses-sdk android:minSdkVersion="8" />
   8:  
   9:     <uses-permission android:name="android.permission.INTERNET"/>
  10:  
  11:     <application
  12:         android:icon="@drawable/gold"
  13:         android:label="@string/app_name" >
  14:                 <receiver android:name=".TWGoldGroupWidget" >
  15:                     <intent-filter>
  16:                         <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
  17:                     </intent-filter>
  18:                     <meta-data android:name="android.appwidget.provider"
  19:                             android:resource="@xml/appwidget" />
  20:                 </receiver>
  21:     </application>
  22:  
  23: </manifest>

沒有留言:

張貼留言