介绍
Android widget
也称为桌面插件,其是android系统应用开发层面的一部分,但是又有特殊用途,而且会成为整个android系统的亮点。Android中的AppWidget与google
widget和中移动的widget并不是一个概念,这里的AppWidget只是把一个进程的控件嵌入到别外一个进程的窗口里的一种方法。(复制粘贴都懂^_^)
废话不多说上来就是干,直接上一个widget
1、新建一个继承AppWidgetProvider类
public class NewAppWidget extends AppWidgetProvider {
private static String TAG = "NewAppWidget";
public static final String CLICK_ACTION = "com.example.action.CLICK";//自己定义的action
private static RemoteViews views;
static void updateAppWidget(Context context, AppWidgetManager appWidgetManager,
int appWidgetId) {
Intent intentClick = new Intent(context, NewAppWidget.class);
intentClick.setAction(CLICK_ACTION);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intentClick, 0);
CharSequence widgetText = context.getString(R.string.appwidget_text);//文字:状态很棒哦!
// Construct the RemoteViews object
views = new RemoteViews(context.getPackageName(), R.layout.new_app_widget);
// "窗口小部件"整个点击事件注册,只要点击了就会发送相应的广播
views.setOnClickPendingIntent(R.id.appwidget_RelativeLayout, pendingIntent);
views.setTextViewText(R.id.appwidget_text, widgetText);//设置文字
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.xiao);//笑的图片
views.setImageViewBitmap(R.id.appwidget_image, bitmap);//设置图片
ComponentName name = new ComponentName(context, NewAppWidget.class);
appWidgetManager.updateAppWidget(name, views);//更新widget
}
//接受到相应的广播
@Override
public void onReceive(final Context context, Intent intent) {
super.onReceive(context, intent);
Log.e(TAG, "onReceive : action = " + intent.getAction());
//这里判断是自己的action,做自己的事情
if (intent.getAction().equals(CLICK_ACTION)) {
Intent intent1 = new Intent(context, ControlActivity.class);
intent1.setFlags(FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent1);
}
}
// 刷新的时候执行
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int appWidgetId : appWidgetIds) {
updateAppWidget(context, appWidgetManager, appWidgetId);
}
}
// 第一个添加到屏幕上执行
@Override
public void onEnabled(Context context) {
//我这是开启一个服务
context.startService(new Intent(context, ConnectService.class));
}
// 最后一个widget从屏幕移除执行
@Override
public void onDisabled(Context context) {
}
// 从屏幕移除执行
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
super.onDeleted(context, appWidgetIds);
}
}
2、新建一个new_app_widget文件
相信看完上面的代码你就发现还需要一个布局文件,然后我们就做一个布局文件呗
代码我就不想贴了直接上图,自己写布局去
就是一个这样的样式了一个背景一个imageview一个textview
3在Manifest文件中声明
<receiver android:name=".NewAppWidget">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
<action android:name="com.example.action.CLICK" />
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/new_app_widget_info" />
</receiver>
然后你就会发现这就是一个receiver,没错这就是一个receiver,AppWidgetProvider 就是继承的BroadcastReceiver
添加Widget配置信息
看到清单文件是不是还少了一个叫new_app_widget_info的xml文件,没错,这个是widget的配置文件。
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/new_app_widget"
android:initialLayout="@layout/new_app_widget"
android:minHeight="40dp"
android:minWidth="250dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="86400000"
android:widgetCategory="home_screen"></appwidget-provider>
好了到了这里你就会发现可以创建一个widget了。但是怎么更新widget呢?
更新widget
调用一下代码
//使用RemoteViews
RemoteViews views = new RemoteViews(getPackageName(), R.layout.new_app_widget);
//获取AppWidgetManager
AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cry);//哭的图片
//相当于找id设置图片
views.setImageViewBitmap(R.id.appwidget_image, bitmap);
views.setTextViewText(R.id.appwidget_text, "状态不好哦!");
//更新widget
appWidgetManager.updateAppWidget(new ComponentName(context, NewAppWidget.class), views);
然后你就会发现换了一张图片,换了几个字
开发中的一些坑
1、appWidgetManager更新的两个方法
updateAppWidget(int[] appWidgetIds, RemoteViews views)
updateAppWidget(ComponentName provider, RemoteViews views)
我们使用的是第二个方法如图
但是我当时使用的是第一个方法如图
当你使用第二张图的方法时,你会发现一个问题在应用退出后,或是被第三方软件杀死,点击桌面widget就不会更新了。原因是updateid是用一个数组保存的,应用退出后,这个数组就被清空了,后面又换成了updateAppWidget(ComponentName)方法后就好了。
2、new_app_widget_info里的android:configure属性
一开始的时候照着官方文档在new_app_widget_info.xml文件里设置了这个属性,在添加到桌面上的时候总是不成功,将这个属性去掉就可以了,不知道这个属性具体怎么用,有知道的麻烦留个言,谢谢
3、在用setOnClickPendingIntent()方法设置点击事件发送Broadcast时,不能直接new Intent(acton)
Intent intentClick = new Intent(CLICK_ACTION);
views.setOnClickPendingIntent(R.id.appwidget_RelativeLayout, PendingIntent.getBroadcast(context, 0, intent, 0));
上面这种写法在应用退出后在有些手机上收不到广播,然后换成下面这种写法
Intent intentClick = new Intent(context, NewAppWidget.class);
intentClick.setAction(CLICK_ACTION);
views.setOnClickPendingIntent(R.id.appwidget_RelativeLayout, PendingIntent.getBroadcast(context, 0, intent, 0));