Android基础学习之AppWidget(桌面小部件)
Android桌面小部件,桌面时钟,天气预报,快速启动等等。是一种常驻程序。
分类:
1.快捷方式:程序快速入口
2.小部件(AppWidget):提醒,通知,控制后台服务,显示数据
3.实时文件夹(已过时)
4.壁纸
桌面小部件特点:
1.不同android设备操作不同
2.不同版本差异(版本分裂)
核心类:
AppWidgetProvider
java.lang.Object
android.content.BroadcastReceiver
android.appwidget.AppWidgetProvider 子类
管理类:
AppWidgetManager 类 为AppWidgetProvider服务的
void updateAppWidget(int appWidgetId, RemoteViews views) 更新小部件视图的
void updateAppWidget(ComponentName provider, RemoteViews views)
生命周期:
写法步骤:
1.定义AppWidgetProvider子类重写方法
2.定义布局文件 小部件的视图 注意用的RemoteViews视图
3.在清单文件中声明AppWidgetProvider子类,关联定义AppWidgetProvider的配置文件
4.定义AppWidgetProvider的配置文件(配置文件位置:工程目录/res/xml/xxx.xml) 用来关联小部件视图,尺寸,图标,更新周期,如下:
android:minWidth="72dp"
android:minHeight="72dp" //尺寸
android:updatePeriodMillis="86400000" //更新周期
android:previewImage="@drawable/creep003" //小部件图标
android:initialLayout="@layout/example_appwidget" //绑定的视图文件
android:configure="com.example.android.ExampleAppWidgetConfigure" //配置的活动界面
>
手动创建配置文件时,界面如下:
如果用导航创建,视图布局和配置文件则会自动创建,如下:
注:RemoteViews 是运行在另一个进程中,而不是应用所在的进程.
RemoteViews views=new RemoteViews(packageName, layoutId)
AppWidget可处理方法:
1.在指定时间执行
2.周期性执行
调用onUpdate() 需要设置属性设置周期时间android:updatePeriodMillis="xxx"
设置周期时间不得小于30分钟(1800000: 30 * 60 * 1000),否则无效。
小部件程序是常驻程序,后台运行占用CPU 频繁占用CPU会影响其他应用,小心资源消耗。
示例1:
由导航自动创建,视图布局比较简单,没贴。
1.AppWidgetProvider子类
public class MyAppWidget extends AppWidgetProvider {@Override//必须收到update广播才能执行public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {// There may be multiple widgets active, so update all of themfinal int N = appWidgetIds.length;//桌面小部件的id数组 指定需要更新的所有id(这里更新所有在桌面的小部件)for (int i = 0; i < N; i++) {updateAppWidget(context, appWidgetManager, appWidgetIds[i]);}}@Overridepublic void onEnabled(Context context) {// Enter relevant functionality for when the first widget is created}@Overridepublic void onDisabled(Context context) {// Enter relevant functionality for when the last widget is disabled}static void updateAppWidget(Context context,AppWidgetManager appWidgetManager, int appWidgetId) {CharSequence widgetText = new Date().toString();//获取系统时间// Construct the RemoteViews objectRemoteViews views = new RemoteViews(context.getPackageName(),R.layout.my_app_widget);//远程视图,绑定需要显示的视图views.setTextViewText(R.id.appwidget_text, widgetText);//修改views容器中textview// Instruct the widget manager to update the widgetappWidgetManager.updateAppWidget(appWidgetId, views);//更新对应id的小部件对象}}
2.配置文件,文件名my_app_widget_info.xml
<?xml version="1.0" encoding="utf-8"?>
3.清单文件AndroidManifest.xml注册声明
注:可以注册的动作,ACTION_APPWIDGET_UPDATE(必须),ACTION_APPWIDGET_DELETED,ACTION_APPWIDGET_ENABLED,ACTION_APPWIDGET_DISABLED
示例2:
因为如果设置更新周期最小只能30分钟,如果我们要更新很快怎么办,下面演示自定义更新时间。
自定义更新时间可以用发广播的形式配合线程或按钮隔一定时间发广播更新,也可以使用服务进行更新。
1.使用服务
这里实现了图片的轮播功能,布局xml中放了一个ImageView
1.写AppWidgetProvider子类
public class NewAppWidget extends AppWidgetProvider {public static AppWidgetManager appWidgetManager;//模拟的图片资源static int[] ids = { R.drawable.a1, R.drawable.a2, R.drawable.a3,R.drawable.a4, R.drawable.a5, R.drawable.a6, R.drawable.a7,R.drawable.a8, R.drawable.a9, R.drawable.a10, R.drawable.a11 };private static int index;//图片下标@Overridepublic void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) {// There may be multiple widgets active, so update all of themsuper.onUpdate(context, appWidgetManager, appWidgetIds);NewAppWidget.appWidgetManager = appWidgetManager;//管理器对象context.startService(new Intent(context, MyService.class));//启动服务}@Overridepublic void onEnabled(Context context) {// Enter relevant functionality for when the first widget is created}@Override// 小部件全部删除时动作public void onDisabled(Context context) {// Enter relevant functionality for when the last widget is disabledcontext.stopService(new Intent(context, MyService.class));//停止服务}/** * 用于更小部件的服务 * @author qinlang * */public static class MyService extends Service {private boolean active = false;//服务运行标识位,优化处理@Overridepublic IBinder onBind(Intent intent) {return null;}@Overridepublic void onCreate() {super.onCreate();active = true;new Thread() {public void run() {while (active) {// Construct the RemoteViews objectRemoteViews views = new RemoteViews(getPackageName(),R.layout.new_app_widget);//远程视图绑定布局视图views.setImageViewResource(R.id.imageView1, ids[index]);//设置对应views中的内容(图片)ComponentName provider = new ComponentName(MyService.this, NewAppWidget.class);//提供者appWidgetManager.updateAppWidget(provider, views);//更新视图index = (++index) % ids.length;// 取余,循环下标try {Thread.sleep(15 * 1000);// 15s刷新一次} catch (InterruptedException e) {e.printStackTrace();}}}}.start();}@Overridepublic void onDestroy() {super.onDestroy();active = false;}}}
2.配置文件,文件名new_app_widget_info.xml。 关键的一个地方,就是把更新周期设置为0。
<?xml version="1.0" encoding="utf-8"?>
3.清单文件注册声明,和注册服务
在onUpData()方法中,这样写。设置Intent(Intent这里是你的小部件子类对象),设置一个动作,然后绑定
给PendingIntent发广播(本身AppWidgetProvider类是广播的子类,所有没有另外创建广播类了),再绑定给远程视图上控件的点击事件。
//加载小部件的远程视图,并初始化事件处理,让appWidgetManager绘制到桌面上RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.face);Intent intent = new Intent(context,MyAppWidgetProvider.class);//intent对象intent.setAction(ACTION_MY_CLICK);//设置动作PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0);//pendingIntent对象是一个广播(可以是活动或服务)remoteViews.setOnClickPendingIntent(R.id.textRemote, pendingIntent);//设置视图上textRemoto控件的点击事件appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);
然后重写onReceiver()方法,用于接收广播,重新设置远程视图内容
@Overridepublic void onReceive(Context context, Intent intent) {super.onReceive(context, intent);//响应远程视图的事件处理if(ACTION_MY_CLICK.equals(intent.getAction())){//加载小部件的远程视图,让appWidgetManager绘制到桌面上RemoteViews remoteViews=new RemoteViews(context.getPackageName(),R.layout.face);//远程视图remoteViews.setTextViewText(R.id.textRemote, new Date().toString());//设置对应内容ComponentName provider=new ComponentName(context, MyAppWidgetProvider.class);//提供者AppWidgetManager manager=AppWidgetManager.getInstance(context);//小部件管理器manager.updateAppWidget(provider, remoteViews);//更新}}
更多相关文章
- Android(安卓)之Activity , Window和View的关系及一些细节
- Android(安卓)Studio文件分组插件
- Android之appWidget按钮事件
- Android(安卓)handler使用方法
- Android(安卓)解决方案:Caused by: java.lang.NullPointerExcepti
- Android(安卓)Studio升级提示 Connection failed. Please check
- Android中Fragment嵌套Fragment,切换Fragment时不显示视图的原因
- Effective Android(安卓)UI - MVP
- Android驱动开发知识储备(纯手打,更新:2018.4.11)