Android桌面小部件AppWidget

本文的代碼實(shí)現(xiàn)的功能:假設(shè)桌面小部件只包含一個(gè)Button和一個(gè)TextView,當(dāng)點(diǎn)擊Button后,后臺(tái)啟動(dòng)一個(gè)服務(wù)(IntentService實(shí)現(xiàn)),該服務(wù)每個(gè)一秒發(fā)送一個(gè)簡(jiǎn)單的字符串消息數(shù)據(jù)data,然后將此消息數(shù)據(jù)更新到桌面小部件的TextView里面實(shí)時(shí)顯示。

這次,在Androidmanifest.xml有關(guān)receiver的定義中,與附錄文章1相比,將增加一個(gè)action:action_update。本例中,Button的按擊事件將觸發(fā)后臺(tái)啟動(dòng)服務(wù),后臺(tái)服務(wù)Service每隔一秒制造一個(gè)簡(jiǎn)單字符串?dāng)?shù)據(jù),然后將此數(shù)據(jù)實(shí)時(shí)的以廣播形式發(fā)給AppWidge,AppWidge收到后,就更新到桌面小部件的TextView里面。

(1)定義AppWidget。

先在Androidmanifest.xml里面定義APP widget的,以Android廣播形式:

[html]view plaincopy

android:name="android.appwidget.provider"

android:resource="@xml/appwidget"/>

兩個(gè)用于廣播接收的action:action_button和action_update,其中action_button用于在桌面小部件接收用戶的點(diǎn)擊事件,此action_button將隨即啟動(dòng)后臺(tái)服務(wù),而后臺(tái)啟動(dòng)的服務(wù)將發(fā)送廣播數(shù)據(jù),數(shù)據(jù)中的廣播過(guò)濾器即是:action_update。

涉及到的res/xml目錄下的appwidget.xml代碼文件:

[html]view plaincopy


android:initialLayout="@layout/appwidget_layout"

android:minHeight="20dip"

android:minWidth="300dip"

android:previewImage="@drawable/ic_launcher"

android:resizeMode="horizontal|vertical"

android:updatePeriodMillis="0"

android:widgetCategory="home_screen">

(2)上次Java代碼實(shí)現(xiàn)窗口小部件。

核心的AppWidget.java代碼:

[java]view plaincopy

packagezhangphil.widget;

importandroid.app.PendingIntent;

importandroid.appwidget.AppWidgetManager;

importandroid.appwidget.AppWidgetProvider;

importandroid.content.ComponentName;

importandroid.content.Context;

importandroid.content.Intent;

importandroid.util.Log;

importandroid.widget.RemoteViews;

publicclassAppWidgetextendsAppWidgetProvider?{

@Override

publicvoidonReceive(Context?context,?Intent?intent)?{

super.onReceive(context,?intent);

Log.d(this.getClass().getName(),"onReceive");

if(intent?==null)

return;

String?action?=?intent.getAction();

if(action.equals(Constants.ACTION_UPDATE))?{

String?data?=?intent.getStringExtra(Constants.KEY_DATA);

Log.d(Constants.KEY_DATA,?data);

RemoteViews?remoteViews?=newRemoteViews(context.getPackageName(),?R.layout.appwidget_layout);

remoteViews.setTextViewText(R.id.text,?data);

AppWidgetManager?appWidgetManager?=?AppWidgetManager.getInstance(context);

ComponentName?componentName?=newComponentName(context,?AppWidget.class);

appWidgetManager.updateAppWidget(componentName,?remoteViews);

}

//?點(diǎn)擊了按鈕,開(kāi)始啟動(dòng)一個(gè)后臺(tái)服務(wù)

if(action.equals(Constants.ACTION_BUTTON))?{

Intent?serviceIntent?=newIntent(context,?MyService.class);

context.startService(serviceIntent);

}

}

@Override

publicvoidonUpdate(Context?context,?AppWidgetManager?appWidgetManager,int[]?appWidgetIds)?{

Log.d(this.getClass().getName(),"onUpdate");

Intent?intent?=newIntent(Constants.ACTION_BUTTON);

PendingIntent?pendingIntent?=?PendingIntent.getBroadcast(context,0,?intent,0);

//?小部件在Launcher桌面的布局

RemoteViews?remoteViews?=newRemoteViews(context.getPackageName(),?R.layout.appwidget_layout);

//?事件

remoteViews.setOnClickPendingIntent(R.id.btn,?pendingIntent);

//?更新AppWidget

appWidgetManager.updateAppWidget(appWidgetIds,?remoteViews);

}

/**

*?刪除AppWidget

*/

@Override

publicvoidonDeleted(Context?context,int[]?appWidgetIds)?{

super.onDeleted(context,?appWidgetIds);

Log.d(this.getClass().getName(),"onDeleted");

}

@Override

publicvoidonDisabled(Context?context)?{

super.onDisabled(context);

Log.d(this.getClass().getName(),"onDisabled");

}

/**

*?AppWidget首次創(chuàng)建調(diào)用

*/

@Override

publicvoidonEnabled(Context?context)?{

super.onEnabled(context);

Log.d(this.getClass().getName(),"onEnabled");

}

}

RemoteViews用到的appwidget_layout.xml,appwidget_layout.xml即是桌面小部件的布局文件:

[html]view plaincopy


android:layout_width="match_parent"

android:layout_height="wrap_content"

android:orientation="horizontal"

android:background="#33000000">

android:id="@+id/btn"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:text="啟動(dòng)后臺(tái)服務(wù)">

android:id="@+id/text"

android:text="text"

android:layout_width="wrap_content"

android:layout_height="wrap_content"/>

(3)后臺(tái)服務(wù)Service。

MyService.java代碼文件,此service是一個(gè)Android IntentService,具體實(shí)現(xiàn)也可以是Service。此service功能簡(jiǎn)單,是有桌面小部件的button按鈕觸發(fā),然后在后臺(tái)啟動(dòng),啟動(dòng)后在一個(gè)for循環(huán)里面循環(huán)產(chǎn)生一個(gè)簡(jiǎn)單的字符串?dāng)?shù)據(jù)通過(guò)廣播形式廣播出去,注意打進(jìn)去的廣播過(guò)濾器是:action_update。

[java]view plaincopy

packagezhangphil.widget;

importandroid.app.IntentService;

importandroid.content.Intent;

publicclassMyServiceextendsIntentService?{

privatestaticintID?=0;

publicMyService()?{

super("ZhangPhilService");

}

@Override

publicintonStartCommand(Intent?intent,intflags,intstartId)?{

returnsuper.onStartCommand(intent,?flags,?startId);

}

@Override

protectedvoidonHandleIntent(Intent?intent)?{

myLongTimeTask(ID++);

}

privatevoidmyLongTimeTask(intid)?{

for(inti?=0;?i?<5;?i++)?{

Intent?intent?=newIntent(Constants.ACTION_UPDATE);

intent.putExtra(Constants.KEY_DATA,"Zhang?Phil?@?CSDN?"+?id?+":"+?i);

sendBroadcast(intent);

try{

Thread.sleep(1000);

}catch(InterruptedException?e)?{

e.printStackTrace();

}

}

}

}

記得要將此service注冊(cè)到Androidmanifest.xml里面:

[html]view plaincopy

(4)公共變量的定義(次要)。

因?yàn)樯婕暗奖姸喙沧兞康膶懭牒妥x出,所以定義了一個(gè)單獨(dú)的Constants.java代碼類,專門定義公共的變量定義:

[java]view plaincopy

packagezhangphil.widget;

publicclassConstants?{

publicstaticfinalString?ACTION_BUTTON?="action_button";

publicstaticfinalString?ACTION_UPDATE?="action_update";

publicstaticfinalString?KEY_DATA?="data";

}

(5)完整的代碼結(jié)構(gòu)。

如圖所示:

最終,代碼運(yùn)行結(jié)果如圖所示:


http://blog.csdn.net/zhangphil/article/details/50461944

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Android桌面小部件AppWidget開(kāi)發(fā) 在Android我們經(jīng)常可以看到各種桌面小部件,比如時(shí)鐘、天氣、音...
    鄭旭澤閱讀 21,566評(píng)論 7 35
  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 179,021評(píng)論 25 709
  • 這是谷歌官方給我們提供的一個(gè)兼容低版本安卓設(shè)備的軟件包,里面包囊了只有在安卓3.0以上可以使用的api。而view...
    Ten_Minutes閱讀 5,843評(píng)論 1 19
  • 意大利是古羅馬的發(fā)祥地。意大利是個(gè)半島,阿平寧山脈縱觀其境,稱阿平寧半島。是地中海北岸三大半島之一,氣候良好,雨水...
    麗克閱讀 982評(píng)論 0 0
  • 1. 錨定鄰域回歸 論文題目:Anchored Neighborhood Regression for Fast ...
    阿阿阿阿毛閱讀 3,544評(píng)論 0 2

友情鏈接更多精彩內(nèi)容