本集实现的内容:点击桌面的Widget上的控件,实现App的某些功能,而不用打开App的Activity,如放在Home的播放器(播放、暂停)
一重要知识点:
1、要让widget通过接收广播发出反应,需要先在ExampleAppWidgetProvider中命名一个action常量,然后在Update中设置给intent (intent.setAction(UPDATE_ACTION);),并且在AndroidManifest.xml中声明,再然后就可以在OnReceive里通过if(action.equals(UPDATE_ACTION)来做出反应。
2、如何发送广播
3、如何接收广播
4、RemoteViews和ComponentName的区别
5、可以通过context得到AppWidgetManager
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
二实现步骤
1、新建res/xml/appwidget_info.xml 描述一个App Widget元数据,比如App Widget的布局,更新频率,指定在home中显示样式的布局文件。这个应该在XML里定义。
<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider
android:minWidth="60dp"
android:minHeight="60dp"
android:updatePeriodMillis="86400000"
android:initialLayout="@layout/appwidget_layout"
android:resizeMode="horizontal|vertical"
android:widgetCategory="home_screen|keyguard"
android:previewImage="@drawable/cat1"
xmlns:android="http://schemas.android.com/apk/res/android"/>
2、创建res/layout/appwidget_layout.xml,指定在Home上显示的样式
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/textId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="badcat"
android:textSize="5sp" />
<Button
android:id="@+id/bId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK" />
</LinearLayout>
<ImageButton
android:id="@+id/imagebId"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="#00000000"
android:src="@drawable/cat2" />
</LinearLayout>
3、在AndroidManifest.xml中声明
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.s02_e07_pendingintent3"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.s02_e07_pendingintent3.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="ExampleAppWidgetProvider">
<intent-filter >
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"/>
</intent-filter>
<intent-filter >//这个action是在ExampleAppWidgetProvider命名的,用于在update中设置在intent上,在OnReceive中接收识别后做出相应反应
<action android:name="jeans.appwidget.UPDATE_APP_WIDGET"/>
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/appwidget_info"/>
</receiver>
</application>
</manifest>
4、实现AppWidgetProvider的类,在onUpdate方法中写代码,用PendingIntent.getBroadcast发送广播
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println("点击反应");
//创建一个Intent对象
Intent intent=new Intent();
//为Intent对象设置Action
intent.setAction(UPDATE_ACTION);
//使用getBroadcast方法,得到一个PendingIntent对象,当该对象执行时,会发送一个广播
PendingIntent pendingIntent=PendingIntent.getBroadcast(context, 0, intent, 0);
RemoteViews remoteViews=new RemoteViews(context.getPackageName(), R.layout.appwidget_layout);
remoteViews.setOnClickPendingIntent(R.id.bId, pendingIntent);
appWidgetManager.updateAppWidget(appWidgetIds,remoteViews);
}
5、在OnReceive中写代码,实现接收广播后做出反应的功能
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
String action=intent.getAction();
//
if(action.equals(UPDATE_ACTION)){
//得到widget的所有控件
RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.appwidget_layout);
//修改widget图片的属性(这里可以是image,也可以是imageButton的图片)
remoteViews.setImageViewResource(R.id.imagebId, R.drawable.cat3);
//修改widget的文本属性
remoteViews.setTextViewText(R.id.textId, "成功了");
remoteViews.setTextViewText(R.id.bId, "好");
//在update里有appWidgetManager这个参数,但是onReceive里没有,可以通过context得到AppWidgetManager.getInstance(context);
AppWidgetManager appWidgetManager=AppWidgetManager.getInstance(context);
//ComponentName是整个widget对象,注意区别(RemoteViews是widget里的所有控件对象)
ComponentName componentName=new ComponentName(context, ExampleAppWidgetProvider.class);
//更新。
appWidgetManager.updateAppWidget(componentName, remoteViews);
}else{
super.onReceive(context, intent);
}
}