1.概念:
桌面工具(Widget)是Android系统的一大特色,通过桌面工具可以快速得到所需的信息,不必打开程序即可了解最新的内容,就好像是一个应用程序的快捷方式。Android系统自带了一些常用的桌面工具,其他一些经过定制的系统也带有具有特色的桌面工具,同时,有很多第三方程序也支持桌面工具。例如新浪微博提供的AppWidget:
在了解完AppWidget的概念后,我们就要开发一个类似的应用。首先来看个制作的效果:
2.代码部分:
新建个程序,并添加以下代码:
MainActivity.java
package com.example.lxxcaroline.myappwidget;
import android.app.Activity;
import android.os.Bundle;
/**
* 主程序入口类
* @author Linxuanxuan
*/
public class MainActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
MyAppWidget.java
package com.example.lxxcaroline.myappwidget;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;
/**
* Created by LxxCaroline on 2015/5/2.
*/
public class MyAppWidget extends AppWidgetProvider {
/**
* 接收到每个广播时都会被调用,而且在上面的回调函数之前。
* 你通常不需要实现这个方法,因为缺省的AppWidgetProvider实现过滤所有App Widget广播并恰当的调用上述方法。
* 注意: 在Android 1.5中,有一个已知问题,onDeleted()方法在调用时不被调用。
* 为了规避这个问题,你可以像Group post中描述的那样实现onReceive()来接收这个onDeleted()回调。
*/
@Override
public void onReceive(Context context, Intent intent) {
System.out.println("onReceive");
super.onReceive(context, intent);
}
/**
* 用来间隔的更新App Widget,间隔时间用AppWidgetProviderInfo里的updatePeriodMillis属性定义(单位为毫秒)。
* 注意:SDK1.5之后此android:updatePeriodMillis就失效了,要自己创建service更新。
* 这个方法也会在用户添加App Widget时被调用,因此它应该执行基础的设置,比如为视图定义事件处理器并启动一个临时的服务Service,如果需要的话。
* 但是,如果你已经声明了一个配置活动,这个方法在用户添加App Widget时将不会被调用,
* 而只在后续更新时被调用。配置活动应该在配置完成时负责执行第一次更新。
* 到达指定的更新时间或者当用户向桌面添加AppWidget时被调用.
*/
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
System.out.println("onUpdate");
/**
* RemoteViews类描述了一个View对象能够显示在其他进程中,可以融合layout资源文件实现布局。
*虽然该类在android.widget.RemoteViews而不是appWidget下面,但在Android Widgets开发中会经常用到它,
*主要是可以跨进程调用(appWidget由一个服务宿主来统一运行的)。
*/
RemoteViews myRemoteViews = new RemoteViews(context.getPackageName(), R.layout.my_appwidget_layout);
//为RemoteView上的按钮设置点击事件,点击桌面组件时进入主程序入口
Intent intent = new Intent(context, MainActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
myRemoteViews.setOnClickPendingIntent(R.id.contentBtn, pendingIntent);
//ComponentName和Intent很相似。
ComponentName myComponentName = new ComponentName(context,MyAppWidget.class);
//负责管理AppWidget,向AppwidgetProvider发送通知。提供了更新AppWidget状态,获取已经安装的Appwidget提供信息和其他的相关状态
AppWidgetManager myAppWidgetManager = AppWidgetManager.getInstance(context);
myAppWidgetManager.updateAppWidget(myComponentName, myRemoteViews);
super.onUpdate(context, appWidgetManager, appWidgetIds);
}
/**
* 当App Widget从宿主中删除时被调用。 删除一个AppWidget时调用
*/
@Override
public void onDeleted(Context context, int[] appWidgetIds) {
System.out.println("onDeleted");
super.onDeleted(context, appWidgetIds);
}
/**
* 当一个App Widget实例第一次创建时被调用。
* 比如,如果用户添加两个App Widget实例,只在第一次被调用。
* 如果你需要打开一个新的数据库或者执行其他对于所有的App Widget实例只需要发生一次的设置,那么这里是完成这个工作的好地方。
*/
@Override
public void onEnabled(Context context) {
System.out.println("onEnabled");
super.onEnabled(context);
}
@Override
public void onDisabled(Context context) {
System.out.println("onDisabled");
super.onDisabled(context);
}
}
res/layout/activity_main.xml:
res/layout/my_appwidget_layout.xml:
这里需要注意的是,appwidget的布局文件并不是支持所有的控件,在上述代码中已经看到使用的是RemoteViews,它并不支持所有控件。RemoteViews还用在notification中。
res/xml/my_appwidget.xml:
AndroidManifest.xml:
项目中用到的图片资源不再说明,读者可以随便贴几张png的图片放在drawable下面。
3.代码说明:
程序正常入口是进入到MainActivity里面去,显示的是activity_main.xml的页面内容。
当点击应用程序图标进入时,MyAppWidget中的代码并不会执行。
接下来为该应用程序创建应用桌面图标,即AppWidget。AppWidget的图样显示是由my_appwidget_layout.xml文件决定。而my_appwidget.xml文件只是说明了该AppWidget应该长什么样,指定AppWidget的布局文件等。
当然最重要的是MyAppWidget里面的代码,他继承自AppWidgetProvider。这个父类中有几个函数,分别是onUpdate()、onDeleted()、onEnabled()、onDisabled()、onReceive()。接下来分别解释这几个函数会在什么时候被执行到。
具体可以看一下两个博客:
http://www.cnblogs.com/qianlifeng/archive/2011/03/26/1996407.html
http://blog.csdn.net/thl789/article/details/7887968