2011年10月30日 星期日

Android筆記,控制appwidget














透過按鈕讓桌面的小時鐘,暫停或顯示時間,上面是模擬器出現的畫面

原理用一個Thread讓service每秒啓動一次,更新view寫在onStart(service啓動時執行一次),當按下按鈕決定view是否要更新,這個Thread只在widget初始化時才newㄧ次


1.Clock_widget.java



package test.Clock_widget1;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import android.app.PendingIntent;
import android.app.Service;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.IBinder;
import android.os.Message;
import android.util.Log;
import android.widget.RemoteViews;
import android.widget.Toast;

//自定義clock_thread class 繼承Thread,s毫秒送出sendMessage
class clock_Thread extends Thread{
  //變數宣告
  Handler thandler;
  private int sc;
  private Message m;
  boolean paused;
  //建構子,初始化
  public clock_Thread(Handler h,int s){
  sc=s;//毫秒
  thandler =h;
  }

public void run(){
super.run();
try{
 while(true){
     Thread.sleep(sc);
   
   m=new Message();
     thandler.sendMessage(m);
   
      }//while
 }catch (Exception e) {
    Log.d("tag", "error");
    //  handle exception
   }//cttch
}//run
//set handler_

public void set_handler(Handler h){
this.thandler=h;
}
//set second
public void set_second(int s){
this.sc=s;
}

}//thread




public class Clock_widget extends AppWidgetProvider {



//變數宣告
//public Handler c_Handler;
public  static Handler w_handler;
private int[] sappWidgetIds;
    private AppWidgetManager sappWidgetManager;
    private static Context scontext;
    private clock_Thread cthread;
public static String CLICK_ACTION1 ;
public static String CLICK_ACTION2 ;
    static private boolean START_TIME;//是否顯示時間


   // 建構子初始化Clock_widget,能初始化盡量初始化
 
public  Clock_widget() {
//按鈕1字串
CLICK_ACTION1 = "test.widget_clock.CLICK1";
//按鈕2字串
CLICK_ACTION2 = "test.widget_clock.CLICK2";

START_TIME=true;
w_handler=null;
  //一開始handler null,1秒送出message
cthread=new clock_Thread(w_handler,1000);
//start thread
cthread.start();

}
@Override
public void onReceive(Context context, Intent intent) {
 super.onReceive(context, intent);
 final String action = intent.getAction();
 if(action.equals(CLICK_ACTION1)){
     
      //context.startService(intent1);
 START_TIME=true;
     
      Toast.makeText(context, "開時時間", Toast.LENGTH_LONG).show();
      }
 if(action.equals(CLICK_ACTION2)){
 START_TIME=false;
 Toast.makeText(context, "停止時間", Toast.LENGTH_LONG).show();
 }



}

   @Override
 
   public void onUpdate(final Context context,AppWidgetManager appWidgetManager, int[] appWidgetIds) {
 
    //onUpdate時放到全域變數
    sappWidgetManager = appWidgetManager;
    sappWidgetIds = appWidgetIds;
    scontext = context;
   
    //綁定Clock_widget注意androidmanifest receiver需註冊action
       final Intent refreshIntent1 = new Intent(scontext, Clock_widget.class);
       //set action字串
   refreshIntent1.setAction(Clock_widget.CLICK_ACTION1);
    PendingIntent refreshPendingIntent1 = PendingIntent.getBroadcast(scontext, 0,refreshIntent1, PendingIntent.FLAG_UPDATE_CURRENT);
   //final PendingIntent refreshPendingIntent = PendingIntent.getService(cc, 0,refreshIntent, 0);
   RemoteViews updateViews1 = new RemoteViews( scontext.getPackageName(), R.layout.main);
       //設定button
   updateViews1.setOnClickPendingIntent(R.id.button1, refreshPendingIntent1);
       //update view
       sappWidgetManager.updateAppWidget(sappWidgetIds, updateViews1);
   
   
   
    //綁定Clock_widget注意androidmanifest receiver需註冊action
       final Intent refreshIntent2 = new Intent(scontext, Clock_widget.class);
       //set action字串
   refreshIntent2.setAction(Clock_widget.CLICK_ACTION2);
    PendingIntent refreshPendingIntent2 = PendingIntent.getBroadcast(scontext, 0,refreshIntent2, PendingIntent.FLAG_UPDATE_CURRENT);
   //final PendingIntent refreshPendingIntent = PendingIntent.getService(cc, 0,refreshIntent, 0);
   RemoteViews updateViews2 = new RemoteViews( scontext.getPackageName(), R.layout.main);
       //設定button
   updateViews2.setOnClickPendingIntent(R.id.button2, refreshPendingIntent2);
       //update view
       sappWidgetManager.updateAppWidget(sappWidgetIds, updateViews2);
   
       //new handler
 
   w_handler =new Handler(){
          public void handleMessage(Message msg) {
Intent intent = new Intent(scontext, MyService.class);
  //start service
   scontext.startService(intent);
}
};//Hamdler
//重設handler
cthread.set_handler(w_handler);
   
   }//onupdate
 
   //取得時間,宣告成static可值接用,不須new
   public static String get_date(){
   int c_Minutes; //分
   int c_Hour; //時
   int c_Second;
   int c_year; //時
   int c_month;
   final String str;
   long time=System.currentTimeMillis();
final Calendar c_Calendar = Calendar.getInstance();
c_Calendar.setTimeInMillis(time);
c_Hour=c_Calendar.get(Calendar.HOUR);
c_Minutes=c_Calendar.get(Calendar.MINUTE);
c_Second=c_Calendar.get(Calendar.SECOND);
c_month=c_Calendar.get(Calendar.MONTH);
c_year=c_Calendar.get(Calendar.YEAR);
 str="西元"+c_year+"年"+c_month+"月"+c_Hour+"時"+c_Minutes+"分"+c_Second+"秒";
   return str;
   }
 
 


//MyService服務程式 ,背景運作
 
 
   public static class MyService extends Service {
 
    //onStart階段service啓動只執行一次
       @Override
       public void onStart(Intent intent, int startId) {
        if(START_TIME){
           ComponentName thisWidget = new ComponentName(this, Clock_widget.class);
           AppWidgetManager manager = AppWidgetManager.getInstance(this);
           RemoteViews remoteViews = new RemoteViews(getPackageName(), R.layout.main);
            //Toast.makeText(this, "開時時間", Toast.LENGTH_LONG).show();
           remoteViews.setTextViewText(R.id.textView1, get_date());
         
           manager.updateAppWidget(thisWidget, remoteViews);
        Log.d("TAG","true") ;
}else{
Log.d("TAG","false") ;
}//if
       }
       @Override
       public IBinder onBind(Intent intent) {
           return null;
       }
   } //service

}//app class


2.AndroidManifest.xml


<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
      package="test.Clock_widget1"
      android:versionCode="1"
      android:versionName="1.0">
    <uses-sdk android:minSdkVersion="11" />

    <application android:icon="@drawable/icon" android:label="@string/app_name">
            <receiver android:name=".Clock_widget" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />

                <!--receiver註冊action-->
                <action android:name="test.widget_clock.CLICK1" />
                <action android:name="test.widget_clock.CLICK2" />

            </intent-filter>
            <meta-data android:name="android.appwidget.provider"
                android:resource="@xml/clockprovider" />
           </receiver>
           <service android:enabled="true" android:name=".Clock_widget$MyService">

            <intent-filter>
                <!--service註冊action,mark掉>
                                <action android:name="test.widget_clock.CLICK3" />
                                </-->
                        </intent-filter>

                </service>

    </application>
</manifest>


3.clockprovider.xml

<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider
  xmlns:android="http://schemas.android.com/apk/res/android"

    android:minWidth="100dp"
    android:minHeight="50dp"
    android:updatePeriodMillis="0"
    android:initialLayout="@layout/main"
  >

</appwidget-provider>

4.main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical" >

    <TextView
        android:id="@+id/textView1"
        android:layout_width="843dp"
        android:layout_height="wrap_content"
        android:text="TextView"
        android:textSize="18dp" >
</TextView>
    <LinearLayout android:id="@+id/linearLayout1" android:layout_height="wrap_content" android:layout_width="match_parent" android:layout_weight="0.13" android:weightSum="1">

    <LinearLayout
        android:id="@+id/linearLayout2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content" >

            <Button android:id="@+id/button1" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="顯示時間"></Button>
            <Button android:id="@+id/button2" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="暫停時間"></Button>
        </LinearLayout>
    </LinearLayout>


</LinearLayout>




沒有留言: