对于手机桌面小部件大家都不会模式,比如桌面上的时钟,天气,日历等等,都属于widget。
简单做个widget小部件,先看一下效果图。
只是在桌面显示个时间,每过一秒刷新一次。
接下来上代码:
首先需要在Layout中新建个布局widget.xml此布局为桌面上要显示的内容,在里面放个TextView
<?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <TextView android:id="@+id/time" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout>
新建WidgetProvider类继承AppWidgetProvider。其中AppWidgetProvider的父类是BroadcastReceiver。所以它也属于是广播。
public class WidgetProvider extends AppWidgetProvider { @Override public void onDeleted(Context context, int[] appWidgetIds) { super.onDeleted(context, appWidgetIds); //widget被从屏幕移除 } @Override public void onDisabled(Context context) { super.onDisabled(context); //最后一个widget被从屏幕移除 context.stopService(new Intent(context,TimerService.class)); } @Override public void onEnabled(Context context) { super.onEnabled(context); //widget添加到屏幕上执行 context.startService(new Intent(context,TimerService.class)); } @Override public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { super.onUpdate(context, appWidgetManager, appWidgetIds); //刷新的时候执行widget //remoteView AppWidgetManager } }
我们重写其中的一些方法,方法下面已经带注释了,在这里就不细说了,看方法名字就大概知道作用了。
因为要实时更新时间显示,所以我们在onEnabled方法中要开启一个服务,同时要在onDisabled中关闭服务。
新建个服务类TimerService继承Service
public class TimerService extends Service { private Timer mTimer; private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); @Nullable @Override public IBinder onBind(Intent intent) { return null; } @Override public void onCreate() { super.onCreate(); mTimer = new Timer(); mTimer.schedule(new TimerTask() { @Override public void run() { updata(); } }, 0, 1000); } private void updata() { String time = sdf.format(new Date()); RemoteViews rv = new RemoteViews(getPackageName(), R.layout.widget); rv.setTextViewText(R.id.time, time); AppWidgetManager manager = AppWidgetManager.getInstance(getApplicationContext()); ComponentName cn =new ComponentName(getApplicationContext(),WidgetProvider.class); manager.updateAppWidget(cn, rv); } @Override public void onDestroy() { super.onDestroy(); mTimer = null; } }
schedule (TimerTask task, long delay, long period)
这个方法有三个参数,第一个参数传递一个TimerTask,第二个参数是延迟执行,第三个参数是多长时间执行一次,
在这里我们是1s执行一次,无延迟。其中在TimerTask的run()方法中执行update()方法,在update方法中把获得到的时间传递给TextView。更新数据需要用RemoteViews和AppWidgetManager。
我们还需要个widget的配置文件,在res下面新建xml文件夹,里面新建一个widgetconfig.xml作为配置文件。
<?xml version="1.0" encoding="utf-8"?> <appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android" android:initialLayout="@layout/widget" android:minHeight="40dp" android:minWidth="100dp" android:updatePeriodMillis="45000"> </appwidget-provider>
其中包含最小高度,最小宽度的属性,android:initialLayout为管理的布局文件。其中updatePeriodMillis为更新widget的时间间隔,Android系统为了节省电量的原因,默认刷新时间最小为30分钟,如何设置的时间小于30分钟的话,也是30分钟刷新一次。
现在就剩最后在AndroidManifest中配置信息了,需添加一个服务和一个广播
<service android:name=".TimerService"/> <receiver android:name=".WidgetProvider"> <intent-filter> <action android:name="android.appwidget.action.APPWIDGET_UPDATE"/> </intent-filter> <meta-data android:name="android.appwidget.provider" android:resource="@xml/widgetconfig"/> </receiver>
好了,接下来运行程序,然后在窗口小部件中就能找到我们要显示的widget。如文章刚开始的图。这个是最简单的使用例子。