Author: Xu jianxiang (netpirate@gmail.com)
Time: 2010/12/15
From: http://www.anymobile.org
Widgets: the earliest widgets are small window programs on the desktop of the PC; the pioneers on the Web seem to be Yahoo !; Of course, OPhone also has a set of widgets, HTML + CSS stuff.
The so-called Widget we are talking about here is a Window Widget. The Android SDK supports AppWidget framework from version 1.5. The return framework allows developers to develop Widgets, these Widgets can be added by users by means of Long-pressed desktops to interact with applications.
Requirements:
Develop a Widget on the desktop to display the status update changes of the IM software in real time. You can click the left and right buttons to view the last or lower update content.
(Reference)
Design Concept:
(Refer to the design sequence diagram)
Code:
Java:
/Src/org. anymobile. demo. Globals // Intent. action Declaration
/Src/org. anymobile. demo. service. UpdateService extends Service // synchronize and update the Widget layout data.
/Src/org. anymobile. demo. widget. UpdateAppWidgetProvider extends AppWidgetProvider // Widget, receiver
XML:
/Res/layout/update_appwidget.xml // layout Design
/Res/values/strings. xml // constant Declaration
/Res/xml/update_appwidget_info.xml // app widget Definition
AndroidManifest. xml
# AndroidManifest. xml
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <manifest xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> package = "org. anymobile. demo "<br/> Android: versioncode =" 1 "<br/> Android: versionname =" 1.0 "> <br/> <application Android: icon = "@ drawable/icon" Android: Label = "@ string/app_name"> </P> <p> <Cycler Android: Name = ". widget. updateappwidgetprovider "<br/> Android: Label =" @ string/app_widget_label "> <br/> <intent-filter> <br/> <action Android: Name =" android. appwidget. action. appwidget_update "/> <br/> </intent-filter> <br/> <meta-data Android: Name =" android. appwidget. provider "<br/> Android: Resource =" @ XML/update_appwidget_info "/> <br/> </receiver> </P> <p> <service android: name = ". service. updateService "Android: Label =" @ string/app_name "> <br/> <intent-filter> <br/> <action Android: Name =" org. anymobile. demo. service. imm_update_service "/> <br/> <category Android: Name =" android. intent. category. default "/> <br/> </intent-filter> <br/> </service> <br/> </Application> <br/> </manifest>
# Strings. xml
<? Xml version = "1.0" encoding = "UTF-8"?> <Br/> <resources> <br/> <string name = "app_name"> AnymobileDemo </string> </p> <string name = "app_widget_label"> AnymobileDemo widget </string> <br/> <string name = "app_widget_title"> Updates </string> <br/> <string name = "app_widget_error_message"> No messages, please check to login. </string> </p> </resources> <br/>
# Update_appwidget_info.xml
<? Xml version = "1.0" encoding = "UTF-8"?> <Br/> <appwidget-provider xmlns: android = "http://schemas.android.com/apk/res/android" <br/> android: minWidth = "294dip" <br/> android: minHeight = "120dip" <br/> android: updatePeriodMillis = "0" <br/> android: initialLayout = "@ layout/update_appwidget"> <br/> </appwidget-provider>
# Update_appwidget.xml
<? XML version = "1.0" encoding = "UTF-8"?> <Br/> <linearlayout xmlns: Android = "http://schemas.android.com/apk/res/android" <br/> Android: Orientation = "vertical" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent"> <br/> <linearlayout <br/> Android: id = "@ + ID/app_widget_top" <br/> Android: gravity = "center_vertical" <br/> Android: Orientation = "horizontal" <br/> Android: background = "@ drawable/widget_titlebar" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content"> <br/> </linearlayout> </P> <p> <linearlayout <br/> Android: id = "@ + ID/app_widget_body" <br/> Android: Orientation = "horizontal" <br/> Android: Background = "@ drawable/widget_body" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "100dip"> <br/> <linearlayout <br/> Android: id = "@ + ID/app_widget_message" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "fill_parent"> <br/> <textview <br/> Android: Id = "@ + ID/widget_message" <br/> Android: TEXT = "@ string/app_widget_error_message" <br/> Android: paddingright = "5dip" <br/> Android: paddingleft = "5dip" <br/> Android: layout_width = "wrap_content" <br/> Android: layout_height = "wrap_content"> <br/> </textview> <br/> </linearlayout> </P> <p> <linearlayout <br/> Android: id = "@ + ID/app_widget_bottom" <br/> Android: gravity = "right" <br/> Android: layout_width = "fill_parent" <br/> Android: layout_height = "wrap_content"> <br/> </linearlayout>
# Globals. java
Package org. anymobile. demo; <br/> public final class Globals <br/> {<br/> public static final String ACTION_APP_WIDGET_SERVICE = "org. anymobile. demo. service. IMM_UPDATE_SERVICE "; </p> <p> public static final String ACTION_APP_WIDGET_PREV =" org. anymobile. demo. intent. action. APP_WIDGET_PREV "; <br/> public static final String ACTION_APP_WIDGET_NEXT =" org. anymobile. demo. intent. action. APP_WIDGET_NEXT "; </p> <p> public static final String ACTION_APP_WIDGET_RELOAD =" org. anymobile. demo. intent. action. APP_WIDGET_RELOAD "; </p> <p >}< br/>
# UpdateService. java
Package Org. anymobile. demo. service; <br/> Import Java. util. arraylist; <br/> Import android. app. service; <br/> Import android. appwidget. appwidgetmanager; <br/> Import android. content. broadcastreceiver; <br/> Import android. content. componentname; <br/> Import android. content. context; <br/> Import android. content. intent; <br/> Import android. content. intentfilter; <br/> Import android. OS. ibinder; <br/> import Droid. util. log; <br/> Import android. view. view; <br/> Import android. widget. remoteviews; <br/> Import Org. anymobile. demo. globals; <br/> Import Org. anymobile. demo. r; <br/> Import Org. anymobile. demo. widget. updateappwidgetprovider; <br/> public class UpdateService extends service <br/> {<br/> Public static final string tag = "ANYMOBILE-DEMO -- UpdateService "; </P> <p> private arraylist <string> MList; <br/> privat E int mcount; <br/> private int mid; </P> <p> private broadcastreceiver mintentreceiver = new broadcastreceiver () <br/>{< br/> @ override <br/> Public void onreceive (context, intent) <br/>{< br/> string action = intent. getaction (); <br/> log. D (TAG, "onreceive ()" + action); </P> <p> If (action. equals (globals. action_app_widget_reload) <br/>{< br/> doreload (); <br/>}< br/>}; <br/> @ Override <br/> Public void oncreate () <br/> {<br/> log. D (TAG, "oncreate ()"); <br/> super. oncreate (); </P> <p> reloadqueue (); </P> <p> intentfilter filter = new intentfilter (); <br/> filter. addaction (globals. action_app_widget_reload); <br/> registerreceiver (mintentreceiver, filter); <br/>}</P> <p> @ override <br/> Public void onstart (intent, int startid) <br/>{< br/> super. onstart (intent, startid); <br/> String action = intent. getaction (); <br/> log. D (TAG, "onstart ()" + action); <br/> If (action. equals (globals. action_app_widget_prev) <br/>{< br/> doprev (); <br/>}< br/> else if (action. equals (globals. action_app_widget_next) <br/>{< br/> donext (); <br/>}< br/> else // If (action. equals (globals. action_app_widget_service) <br/>{< br/> yywidget (); <br/>}</P> <p> private void policywi DGET () <br/>{< br/> log. D (TAG, "yywidget ()"); </P> <p> componentname widget = new componentname (this, updateappwidgetprovider. class); <br/> remoteviews updateviews = buildupdate (this); </P> <p> appwidgetmanager manager = appwidgetmanager. getinstance (this); <br/> manager. updateappwidget (widget, updateviews); <br/>}< br/> @ override <br/> Public void ondestroy () <br/>{< br/> log. D (TAG, "ondestroy ()"); </P> <P> unregisterreceiver (mintentreceiver); </P> <p> super. ondestroy (); <br/>}< br/> @ override <br/> Public ibinder onbind (intent) <br/>{< br/> log. D (TAG, "onbind ()"); <br/> return NULL; <br/>}</P> <p> private remoteviews buildupdate (context) <br/>{< br/> remoteviews updateviews = <br/> New remoteviews (context. getpackagename (), R. layout. update_appwidget); <br/> string item = NULL; </P> <p> If (mcount> 0) <br/>{< br/> item = MList. Get (MID); <br/> If (item! = NULL) <br/>{< br/> updateviews. setviewvisibility (R. id. app_widget_content, view. gone); <br/> updateviews. setviewvisibility (R. id. app_widget_message, view. visible); </P> <p> // updateviews. setviewvisibility (R. id. app_widget_content, view. visible); <br/> // updateviews. setviewvisibility (R. id. app_widget_message, view. gone); <br/> // updateviews. setimageviewresource (R. id. update_appwidget_icon, item. gettyp Eiconid (); <br/> // updateviews. settextviewtext (R. id. update_appwidget_name, item. getnickname (); <br/> // updateviews. settextviewtext (R. id. update_appwidget_time, item. getmodifytime (); <br/> // updateviews. settextviewtext (R. id. update_appwidget_content, item. getmessage (); </P> <p> updateviews. settextviewtext (R. id. widget_message, item); <br/>}< br/> If (item = NULL) <br/>{< br/> updateviews. setviewvi Sibility (R. id. app_widget_content, view. gone); <br/> updateviews. setviewvisibility (R. id. app_widget_message, view. visible); </P> <p> updateviews. settextviewtext (R. id. widget_message, <br/> context. gettext (R. string. app_widget_error_message); <br/>}< br/> log. D (TAG, "buildupdate: layoutid =" + updateviews. getlayoutid () + <br/> "; Count =" + mcount + "; id =" + mid); </P> <p> return updateviews; <br/>}</P> <P> private void doreload () <br/>{< br/> log. D (TAG, "doreload ()"); <br/> reloadqueue (); </P> <p> yywidget (); <br/>}</P> <p> private void reloadqueue () <br/>{< br/> MList = new arraylist <string> (); <br/> string [] arr = {"AA", "BB", "cc", "DD" };< br/> for (INT I = 0; I <arr. length; I ++) <br/>{< br/> MList. add (ARR [I]); <br/>}</P> <p> If (MList! = NULL) <br/>{< br/> mcount = MList. size (); <br/>}< br/> else <br/>{< br/> mcount = 0; <br/>}< br/> mid = 0; </P> <p> // todo check login and poll updates from buddie list <br/>}</P> <p> private void doprev () <br/>{< br/> log. D (TAG, "doprev ()"); <br/> mid-= 1; <br/> If (mid <0) <br/>{< br/> mid = mcount-1; <br/>}< br/> yywidget (); <br/>}</P> <p> private void donext () <br/>{< br/> log. D (TAG, "donext ()"); <br/> mid + = 1; <br/> If (mid> mcount-1) <br/>{< br/> mid = 0; <br/>}< br/> yywidget (); <br/>}< br/>
# UpdateAppWidgetProvider. java
Package org. anymobile. demo. widget; </p> <p> import android. app. pendingIntent; <br/> import android. appwidget. appWidgetManager; <br/> import android. appwidget. appWidgetProvider; <br/> import android. content. componentName; <br/> import android. content. context; <br/> import android. content. intent; <br/> import android. util. log; <br/> import android. view. view; <br/> import android. widget. remoteViews; </p> <p> import Org. anymobile. demo. globals; <br/> import org. anymobile. demo. r; <br/> import org. anymobile. demo. service. updateService; </p> <p> public class UpdateAppWidgetProvider extends AppWidgetProvider <br/>{< br/> public static final String TAG = "ANYMOBILE-DEMO-UpdateAppWidgetProvider "; </p> <p> public static final String APP_WIDGET_UPDATE = "appwidgetupdate"; <br/> public static final ComponentName APPWIDGET_COMP ONENT_NAME = <br/> new ComponentName ("org. anymobile. demo ", <br/>" org. anymobile. demo. widget. updateAppWidgetProvider "); <br/> @ Override <br/> public void onReceive (Context context, Intent intent) <br/>{< br/> Log. d (TAG, "onReceive ()" + intent. getAction (); <br/> super. onReceive (context, intent); <br/>}< br/> @ Override <br/> public void onEnabled (Context context) <br/>{< br/> Log. d (TAG, "onEnabled ()"); <Br/> super. onEnabled (context); <br/>}< br/> @ Override <br/> public void onDisabled (Context context) <br/>{< br/> Log. d (TAG, "onDisabled ()"); <br/> super. onDisabled (context); <br/>}< br/> @ Override <br/> public void onUpdate (Context context, AppWidgetManager appWidgetManager, int [] appWidgetIds) <br/>{< br/> Log. d (TAG, "onUpdate ()"); </p> <p> defaappappwidget (context, appWidgetIds); </p> <p> context. startSe Rvice (new Intent (Globals. ACTION_APP_WIDGET_SERVICE); <br/>}</p> <p> private void defaultAppWidget (Context context, int [] appWidgetIds) <br/>{< br/> final RemoteViews views = <br/> new RemoteViews (context. getPackageName (), R. layout. update_appwidget); </p> <p> views. setViewVisibility (R. id. app_widget_content, View. GONE); <br/> views. setViewVisibility (R. id. app_widget_message, View. VISIBLE); </p> <p> // Link Actions buttons to intents <br/> linkButtons (context, views); </p> <p> pushUpdate (context, appWidgetIds, views ); <br/>}</p> <p> private void linkButtons (Context context, RemoteViews views) <br/>{< br/> Intent intent; <br/> PendingIntent pendingIntent; <br/> final ComponentName serviceName = new ComponentName (context, UpdateService. class); </p> <p> intent = new Intent (Globals. ACTION_APP_WIDGET_PREV); <br /> Intent. setComponent (serviceName); <br/> pendingIntent = PendingIntent. getService (context, <br/> 0/* no requestCode */, intent, 0/* no flags */); <br/> views. setOnClickPendingIntent (R. id. widget_btn_prev_page, pendingIntent); <br/> intent = new Intent (Globals. ACTION_APP_WIDGET_NEXT); <br/> intent. setComponent (serviceName); <br/> pendingIntent = PendingIntent. getService (context, <br/> 0/* no re QuestCode */, intent, 0/* no flags */); <br/> views. setOnClickPendingIntent (R. id. widget_btn_next_page, pendingIntent); <br/>}</p> <p> private void pushUpdate (Context context, int [] appWidgetIds, RemoteViews views) <br/>{< br/> final AppWidgetManager gm = AppWidgetManager. getInstance (context); <br/> if (appWidgetIds! = Null) <br/>{< br/> gm. updateAppWidget (appWidgetIds, views); <br/>}< br/> else <br/>{< br/> gm. updateAppWidget (APPWIDGET_COMPONENT_NAME, views); <br/>}</p> <p> void policychange (UpdateService service, String what) <br/>{< br/> // <br/>}< br/>
Logs:
# Init
12-15 19:23:09. 479 D/ANYMOBILE-DEMO -- UpdateAppWidgetProvider (585): onReceive () android. appwidget. action. APPWIDGET_UPDATE
12-15 19:23:09. 509 D/ANYMOBILE-DEMO -- UpdateAppWidgetProvider (585): onUpdate ()
12-15 19:23:09. 549 D/ANYMOBILE-DEMO -- UpdateService (585): onCreate ()
12-15 19:23:09. 579 D/ANYMOBILE-DEMO -- UpdateService (585): onStart ()
# Add widget
12-15 19:24:23. 780 D/ANYMOBILE-DEMO -- UpdateAppWidgetProvider (585): onReceive () android. appwidget. action. APPWIDGET_UPDATE
12-15 19:24:23. 780 D/ANYMOBILE-DEMO -- UpdateAppWidgetProvider (585): onUpdate ()
12-15 19:24:23. 850 D/ANYMOBILE-DEMO -- UpdateService (585): onStart ()
# Receive software event, reload and update widget
12-15 19:24:58. 150 D/ANYMOBILE-DEMO -- UpdateService (585): onReceive () Activation
12-15 19:24:58. 150 D/ANYMOBILE-DEMO -- UpdateService (585): doReload ()
12-15 19:24:58. 150 D/ANYMOBILE-DEMO -- UpdateService (585): yywidget ()
12-15 19:24:58. 200 D/ANYMOBILE-DEMO -- UpdateService (585): buildUpdate: layoutId = 2130903068; count = 11; id = 0
# Click widget button, new start the bind service
12-15 19:25:49. 260 D/ANYMOBILE-DEMO -- UpdateService (585): onStart ()
12-15 19:24:58. 150 D/ANYMOBILE-DEMO -- UpdateService (585): yywidget ()
12-15 19:24:58. 200 D/ANYMOBILE-DEMO -- UpdateService (585): buildUpdate: layoutId = 2130903068; count = 11; id = 0
OVER!
Refer:
Com. android. music/. MediaAppWidgetProvider
Com. android. music/. MediaPlaybackService