一、appwidget实现过程的分析:
appwidget是显示的桌面上的小窗口程序,在该实现中实际上是一种广播的方式。
1、实现步骤:
1、1创建布局文件:
首先在layout文件夹下创建一个appwidget的布局文件appwidgetlayout.xml,在这里可以添加一些需要在appWidget上显示的控件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/txtapp"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="#ffffff"
android:text="@string/bnt_name" >
</TextView>
</LinearLayout>
1、2配置appwidget的显示属性
先在xml文件中配置appwidget的显示属性,创建appwidget.xml,配置其相关属性 ,使用appwidget-provider
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialLayout="@layout/widget_layout"
android:minHeight="300dp"
android:minResizeHeight="90dp"
android:minResizeWidth="190dp"
android:resizeMode="horizontal|vertical"
android:minWidth="200dp">
</appwidget-provider>
- initialLayout :指定把appwidget放置在桌面上的时候的初始布局
- minHeight、minResizeHeight前一个是指定appwidget的最小高度,后一个指定允许重新测量,后一个值必须小于前一个值,否则会被忽略
- resizeMode:允许在哪些方向上重新测量,appwidget在桌面显示的时候会有横向和纵向上有多少格子。
- configure:指定appwidget第一次放置在桌面上的时候需要打开的Activity,若配置了这个属性则AppwidgetProvider中的onUpdate就不会在第一次被调用,以后的添加才执行改调用。
- previewImage:指定appwidget在预览界面的图片也就是我们选择appwidget的时候显示的界面,若不设置该属性,系统就会该app的icon图标作为预览、
- widgetCategory:用来设置appwidget可以在哎哪些情况下添加, 默认只能在home–screen上面显示,keyguard用来子锁屏的时候显示,searchbox在搜索页面添加。
- updatePeriodMillis:自动更新时间,最小是半小时。
1、1、3配置mainfest
需要在清单文件中配置receiver标签
<receiver android:name=".WidgetProviderClass"
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
<action android:name="com.xinxue.action.TYPE_BTN"></action>
<action android:name="com.xinxue.action.TYPE_LIST"></action>
</intent-filter>
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/widget_provider"></meta-data>
</receiver>
这里的是必须要写的,名字是固定的,resource就是创建的appwidget-privoder的位置,其中必须写的action:
<action android:name="android.appwidget.action.APPWIDGET_UPDATE"></action>
1、1、4创建类继承AppWidgetProvider
在实现时要重载以下函数:
- public void onDeleted(Context context,int[] appWid getIds)删除一个AppWidget时调用
- public void onDisabled(Context context) 最后一个appWidget时被删除时调用
- public void onEnabled(Context context)AppWidget的实例第一次被创建时调用
- public void onReceive(Context context,Intent intent)接受广播事件,可以接受系统的也可以接受自定义的
- public void onUpdate(Context context,AppWidgetManager appWidgetManager,int [] appwidgetIds)到达指定的更新时间或者当用户向桌面添加AppWidget时被调用
public class appWidgetActivity extends AppWidgetProvider {
/**
* 删除一个AppWidget时调用
*/
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onDeleted(context, appWidgetIds);
System.out.println("----------------onDeleted");
}
/**
* 最后一个appWidget被删除时调用
*/
@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
super.onDisabled(context);
System.out.println("----------------onDisabled");
}
/**
* AppWidget的实例第一次被创建时调用
*/
@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
System.out.println("----------------onEnabled");
}
/**
* 接受广播事件
*/
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
System.out.println("----------------onReceive");
}
/**
* 到达指定的更新时间或者当用户向桌面添加AppWidget时被调用
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println("----------------onUpdate");
// TODO Auto-generated method stub
}
}
二、如何通过appWidget启动一个Activity
2、1在appWidget的布局文件中添加一个按钮
<Button
android:id="@+id/btnSend"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Send" >
</Button>
2、2在appWidget上为按钮添加监听函数
通常在onUpdate方法中:
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
// TODO Auto-generated method stub
//遍历本程序启动的appWidget
for (int i = 0; i < appWidgetIds.length; i++) {
System.out.println("-----------appWidgetIds[] = " + appWidgetIds[i]);
// 创建一个Intent对象
Intent intent = new Intent(context, targetActivity.class); // 启动一个Activity
// 创建一个PendingIntent对象 打开一个Activity
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.appwidgetlayout);
// 为按钮绑定监听器
remoteViews.setOnClickPendingIntent(R.id.btnSend, pendingIntent);
// 更新App
appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
}
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
三、pendingInent中的getBroadcast方法
实现了如何通过广播Kauai更新appWidget上的信息,添加一个自定义的消息,并且在AndroidMainfest上注册:
<action android:name="com.example.appWidgetUpdate" >
</action>
广播的消息定义成了
private static final String UPDATE_RECEIVE=“com.example.appWidgetUpdate”;
重载AppWidgetProvider方法:
/**
* 接受广播事件
*/
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String Msg = intent.getAction();
//处理我们自定义的消息
if (Msg.equals(UPDATE_RECEIVE)) { // 判断广播如果为:com.qlf.appWidgetUpdate才处理
System.out.println("----------------onReceive");
// 只能通过远程对象来设置appwidget中的控件状态
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.appwidgetlayout);
//改变指定控件的值
remoteViews.setTextViewText(R.id.txtapp, "我变-hihi");
remoteViews.setImageViewResource(R.id.image, R.drawable.local_file);
// 获得appwidget管理实例,用于管理appwidget以便进行更新操作
AppWidgetManager appWidgetManager = AppWidgetManager
.getInstance(context);
// 相当于获得所有本程序创建的appwidget
ComponentName componentName = new ComponentName(context,
appWidgetActivity.class);
// 更新appwidget
appWidgetManager.updateAppWidget(componentName, remoteViews);
}
//处理系统发送的消息
else{
super.onReceive(context, intent);
}
}
/**
* 到达指定的更新时间或者当用户向桌面添加AppWidget时被调用
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println("----------------onUpdate");
// TODO Auto-generated method stub
// 创建一个Intent对象
Intent intent = new Intent();
intent.setAction(UPDATE_RECEIVE);
// 这里是getActivity,当然也可以是broadcastReceiver等 发送一个广播消息
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0,
intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.appwidgetlayout);
//为按钮绑定监听器
remoteViews.setOnClickPendingIntent(R.id.btnSend, pendingIntent);
// 更新Appwidget
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
四、getservice方法
首先创建一个Service子类,用来处理appWidget发送的命令:
package com.example.service;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
public class myService extends Service{
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// TODO Auto-generated method stub
System.out.println("--------------flags--------->" + flags);
System.out.println("--------------startId--------->" + startId);
System.out.println("----------------------->onStartCommand");
String value = intent.getStringExtra("hello");
System.out.println("value = " + value);
return super.onStartCommand(intent, flags, startId);
}
}
为按钮绑定监听器,当点击按钮时发送一个Service
/**
* 到达指定的更新时间或者当用户向桌面添加AppWidget时被调用
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
System.out.println("----------------onUpdate");
// TODO Auto-generated method stub
// 创建一个Intent对象
Intent intent = new Intent(context, myService.class);
intent.putExtra("hello", "我是一个Service");
// 这里是getActivity,当然也可以是broadcastReceiver等 发送一个广播消息
PendingIntent pendingIntent = PendingIntent.getService(context, 0,
intent, 0);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
R.layout.appwidgetlayout);
//为按钮绑定监听器
remoteViews.setOnClickPendingIntent(R.id.btnSend, pendingIntent);
// 更新Appwidget
appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
}
还需要在Mainfest中对于Service进行一个注册
<service android:name="com.example.service.myService" >