登录 / 注册
  • IT168首页
  • 手机
  • 整机
  • DIY硬件
  • 摄影
  • 消费数码
  • 数字家电
  • 企业IT
  • 企业商用
  • 办公
  • 互动
  • 社区
  • 全部频道
IT168技术开发频道

IT168首页 > 技术开发 > 技术开发技术 > 正文

从零开始创建一个Android主屏幕Widget

0条评论

2009-12-23 07:00    IT168网站原创  作者: IT168 黄永兵 编辑: 景保玉

  【IT168技术】当最基本的控件,如Clock和Picture Frame Home Screen ,随第一款Android手机的发布后,Android用户就开始尝试编写各种应用Widget(小工具)了,随着Widget API的公开,为开发人员带来了全新有趣的开发模式,除了传统的电话应用外,还可以做其它方面的应用开发。开发人员可以使用Widget API(包含在Android 1.5中,最新版本已经到Android 2.0了)创建简单的控件,然后在新的Widget中显示和使用这些控件。

  本文向你介绍如何从零开始创建一个主屏幕应用Widget,通过使用AlarmManager接口,以用户设定的时间间隔更新图片。你将看到如何创建一个Widget,以及如何随机地从一组图片中选择一张图片显示,根据用户设定的时间间隔周期性改变显示的图片。

  创建一个简单的Widget包括以下几个步骤:

  1、创建一个RemoteView,由它为Widget提供用户界面;

  2、将RemoteView绑定一个Activity(行为)实现AppWidgetProvider接口;

  3、在Android manifest配置文件中提供Widget的关键配置信息。

  项目准备

  一个Widget就是一个处理特定行为的BroadcastReceiver,AppWidgetProvider接口为开发人员提供了一个框架来简化处理这些行为,它包括以下方法:

  1、onEnabled():创建第一个Widget时调用,如果可以,应在这里进行全局初始化。

  2、onDisabled():它和onEnabled()相反,创建最后一个Widget时才调用它,如果可以,应在这里进行全局清理。

  3、onUpdate():当Widget需要更新它的View时调用,用户第一次创建Widget时也需要调用它。

  4、onDeleted():当Widget的一个特定实例被删除时调用,清理特定实例应放在这里进行。

  5、onReceive():此方法默认情况下处理BroadcastReceiver行为,并调用上面的方法(警告:根据相关文档记载,需要开发人员自己处理某些特殊情况,更多信息请看下面的说明)。

  作者注:点击此链接(http://groups.google.com/group/android-developers/browse_thread/thread/365d1ed3aac30916/e405ca19df2170e2?pli=1)检查有关AppWidget框架的缺陷信息,讨论内容包括解决此问题的代码(也可从本文下载示例代码,http://www.developer.com/img/2009/08/3833306_appwidget_code.zip),如果它们并不存在,可以将Widget标识符传递给onUpdate()方法。

  为了让Android识别Widget,需要在manifest文件中加入一个标准的标记,下面的代码片段显示了一个示例:

1 <receiver android:name="ImagesWidgetProvider">
2    <intent-filter>
3    <action
4    android:name="android.appwidget.action.APPWIDGET_UPDATE" />
5    </intent-filter>
6    <meta-data
7    android:name="android.appwidget.provider"
8    android:resource="@xml/imageswidget_info" />
9 </receiver>
10

 

  你可能已经注意到,和常见的定义不一样,小节引用了一个XML文件资源,这个文件为Widget定义了额外的数据,与AppWidgetProviderInfo类一致,这里定义的信息是不变的,因此这个例子不包括updatePeriodMillis的值,因为这个程序允许用户修改与更新时间,如果你在这里分配updatePeriodMillis,它就不能这样做。下面是imageswidget_info.xml文件的完整代码:

1 <?xml version="1.0" encoding="utf-8"?>
2 <appwidget-provider 
3    xmlns:android="http://schemas.android.com/apk/res/android"
4    android:minWidth="146dp"
5    android:minHeight="146dp"
6    android:initialLayout="@layout/widget"
7    android:configure=
8       "com.mamlambo.imageswidget.ImagesWidgetConfiguration" />
9

  标记定义了Widget的大小,默认布局和创建Widget实例时的启动行为配置,为了让Widget在主屏幕上更好地显示,Widget必须保持一定的大小,主屏幕分为特定大小的单元格,Google提供的基本原则是用你想占用的单元格数量乘以74,再减去2。在这个例子中,Widget应该是一个正方形,长和宽都各占两个单元格,因此大小就是74*2-2=146.

  实现onUpdate()

  不显示内容的Widget是没有用的,幸好这个Widget的RemoteView对象很容易实现,它使用一组存储在应用程序的drawable资源目录下的图片,程序使用R.drawable.[imagename]引用这些图片资源,代码需要创建一个数组容纳图片的名字,这样从这些图片名字中随机选择一个就可以了。下面的代码片段显示了onUpdate()的实现,它随机显示一张图片: 

1 @Override
2 public void onUpdate(Context context,
3    AppWidgetManager appWidgetManager,
4    int[] appWidgetIds) {
5    for (int appWidgetId : appWidgetIds) {
6       int imageNum = (new
7          java.util.Random().nextInt(IMAGES.length));
8       RemoteViews remoteView = new
9          RemoteViews(context.getPackageName(),
10          R.layout.widget);
11       remoteView.setImageViewResource(
12          R.id.image, IMAGES[imageNum]);
13       appWidgetManager.updateAppWidget(
14          appWidgetId, remoteView);
15    }
16 }
17

  注意onUpdate()方法使用Widget实例列表作为最后的参数,每个实例必须分开处理,由于App Widget框架的现有缺陷,有些实例可能不可见或不能启用,但在这个例子中可以忽略这些问题。请记住,你自己在实现时可能想跟踪哪个Widget是真正激活的。

  你可以下载本文提供的代码(http://www.developer.com/img/2009/08/3833306_appwidget_code.zip),查看其中的R.layout.widget XML布局定义,它基本上只是一个ImageView,RemoteViews只能使用一组有限的View对象,包括Button,ImageButton,ImageView,TextView,AnalogClock,Chronometer和ProgressBar,并且只能在FrameLayout,LinearLayout或RelativeLayout内使用。请保持RemoteView简单,因为访问是通过setImageViewResource() 和 setTextViewText()方法控制的,它们的目的是在另一个进程内画一个View,因此你的应用程序比正常布局要少些控制。

  自此,Widget最基本的部分完成了,但为了让用户配置图片更新之间的时间间隔,你必须要实现配置Activity,然后处理RemoteView更新的调度问题。

  实现Widget的Activity配置

  和manifest 文件中定义的ImagesWidgetConfiguration类似,任何Activity配置都有两个特殊情况:

  1、只要一启动,它的目的就是返回结果,因此必须要调用setResult()方法返回一个适当的结果(结果要么是RESULT_CANCELED或RESULT_OK)。

  2、在设置结果时,Widget标识值必须放在额外引用的AppWidgeManager.EXTRA_APPWIDGET_ID中。

  下面的代码片段显示了如何处理这两个例外,如果用户中途退出Activity,调用setResult()将默认值设为RESULT_CANCELED。

1 Bundle extras = launchIntent.getExtras();
2 if (extras != null) {
3    appWidgetId = extras.getInt(
4       AppWidgetManager.EXTRA_APPWIDGET_ID,
5       AppWidgetManager.INVALID_APPWIDGET_ID);
6    Intent cancelResultValue = new Intent();
7    cancelResultValue.putExtra(
8       AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
9    setResult(RESULT_CANCELED, cancelResultValue);
10 }
11

    除了这两个限制外,你可能还要实现你喜欢的Activity配置,图1显示了这个例子的简单Activity配置,如果你RESULT_CANCELED,Widget不会显示给用户,如果你返回RESULT_OK,用户才看得见Widget,你可以使用任意存储机制保存Widget实例的配置数据,这个例子使用的是SharedPreferences接口,存储Widget标识更新之间的时间,你可以下载本文配套的代码查看完整的实现(http://www.developer.com/img/2009/08/3833306_appwidget_code.zip)。

  

  图 1 配置界面:这个简单的配置界面让用户设置图片刷新间隔时间

  实现更新调度

  正如前面提到的,AppWidgetProviderInfo类中的配置值是不变的,因为updateTimeMillis值就在这个类中,任何有AppWidgetProviderInfo的Widget实例,只要设置了这个值,Widget就会根据其频率更新,没有办法修改它,因为这个应用程序应该让用户配置Widget中图片刷新的频率,因此你必须自动动手实现。

  AlarmManager类是最常用的更新机制,因为它支持重复通知,这些通知是将被触发的简单的PendingIntent对象。

  你可能会想你可以创建一个具有AppWidgetManager.ACTION_APPWIDGET_UPDATE的Intent对象,然后给特定的Widget标识符设置额外的值,接着你就可以通过调用AlarmManager的setRepeating()方法,采用调度机制反复地更新,遗憾的是,这种做法行不通,Android系统反复使用Intents匹配行为和方案值,那些“额外的”值是不会拿去对比的。实际上,解决方案非常简单:首先为你的Widget定义一个方案,然后用它定义唯一的Intent实例。下面的代码片段显示如何实现这个目标:

1 Intent widgetUpdate = new Intent();
2 widgetUpdate.setAction(
3    AppWidgetManager.ACTION_APPWIDGET_UPDATE);
4 widgetUpdate.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, 
5    new int[] { appWidgetId });
6 // make this pending intent unique
7 widgetUpdate.setData(
8    Uri.withAppendedPath(Uri.parse(
9    ImagesWidgetProvider.URI_SCHEME + "://widget/id/"), 
10    String.valueOf(appWidgetId)));
11 PendingIntent newPending = PendingIntent.getBroadcast(
12     getApplicationContext(), 0, widgetUpdate, 
13     PendingIntent.FLAG_UPDATE_CURRENT);
14 // now schedule it
15 AlarmManager alarms = (AlarmManager) getApplicationContext().
16    getSystemService(Context.ALARM_SERVICE);
17 alarms.setRepeating(AlarmManager.ELAPSED_REALTIME, 
18    SystemClock.elapsedRealtime(), updateRateSeconds * 1000, 
19    newPending);
20

  在ImagesWidgetConfiguration Activity中你会发现前面的代码,manifest文件显示块处理这个特定的scheme,你也需要在AppWidgetProvider接口的onDeleted()方法内停止重复的警报。最后,当手机重启后,更新调度也必须重启。

  在AppWidgetProvider的onReceive()方法内提供了一个简单的解决方案,首先,检查更新行为,如果它是一个更新,确保它不包含scheme值,如果它不是更新,那么调度AlarmManager 的PendingIntent不会触发这个行为,在这种情况下,检查每个Widget标识符是否有一个配置选项值,如果没有,那么在配置Widget之前,你知道这个更新行为被接收到。但如果选项值有效,那么你知道可以调度PendingIntent,在onReceive()方法中你可以看到完整的逻辑实现。

  这个方案允许多个Widget同时显示,如图2所示。更新也可以以不同的频率进行,每个显示的图片是从图片集中随机选择的。

  

  图 2 多个Widget实例:这里显示了两个不同的同时运行的实例

  至此,你已经看到了如何在Android平台上创建一个基本的Widget,每个Widget实例按独立的方式调度,由用户自行配置,但App Widge框架不直接支持,因此需要自动动手编码实现。以后我将在此Widget基础上讲解如何从互联网上下载图片,以及如何直接在屏幕上控制图片,敬请期待吧!

标签: Android , 移动开发 , 移动开发平台
分享到:

0 个人觉得赞+1

相关文章

Widget移动开发平台移动开发android

广告

网友评论

已有0条评论

猜您喜欢
  • 本月新机汇总:索尼XZP与三星S8的对决
  • 劲爽!2015“妹子杯”LOL大赛火爆开启
  • 因众筹爆红 乐凡Core M平板3月18日发布
  • 安卓平台最强旗舰 三星Galaxy S6评测
  • 制冷效果好 海尔统帅三门冰箱仅1299元
  • 屏占比飙升 小米Note3渲染图曝光
  • 薄至4.9mm 小米电视4 65英寸首发评测
  • iOS8+指纹识别 iPhone5s国行3599冰点价
  • 这次有点狠 努比亚旗舰发布会看点汇总
  • 新低价 魅族MX4 Pro/1865 魅蓝/658元
  • 努比亚Z17评测:升级不单是加个摄像头
  • 7势磅礴?i7-7700HQ/6700HQ对比测试
  • 小米6真机图赏:这样的米6 美得不要不要!
  • 噱头or创新?曲面显示器到底值得买吗
  • 那个被写死的迪拜王子 你过的还好么?

  • IT168企业级
  • IT168文库

扫码送文库金币

文库文集
  • 别人的文案是怎样炼成的?经典文案合集
  • 关于数字营销研究与市场分析的25份资料
  • 渴望力量吗?权威公司25份互联网相关报
  • 16年的营销行业盘点 必备的25份资料
  • “微时代”下的危机公关应该怎么做?
  • 数字营销新趋势,全在这25份报告
  • 2016年VR/AR领域最具藏收价值的25份报告
  • 人人都在谈“区块链” 这25份报告必须要
  • 不看会后悔!来自京东内部的25份资料
  • 2月精选推荐高质量互联网相关资料报告集

一周热文
  • 从代码看Java和Kotlin有哪些区别?
  • Kotlin新框架发布,据说是Swift转换神器
  • 程序员应收藏的18款优秀Web工具及服务
  • 易进难出,“Vim退出”难住百万程序员
  • 2017年最佳JavaScript框架,库和工具
  • 盘点谷歌最实用的10款营销工具
  • HTML5是否会成为现代Web技术的核心?

编辑推荐
  • 试客发言区:情不知所起,一往而深——我和小米的“孽缘”!
  • 试客发言区:买不起的双摄手机都是耍流氓,小辣椒双摄新品A1
  • 试客发言区:700元的大屏长续航酷比魔方iplay10平板畅玩王者荣耀
  • 试客发言区:盲目崇拜AirPods?其实Nokia J早就玩过充电盒了
  • 每周都有免费试用

盛拓传媒简介关于IT168广告服务使用条款投稿指南诚聘精英联系我们网站导航往日回顾

北京皓辰网域网络信息技术有限公司. 版权所有 京ICP证:060528号 北京市公安局海淀分局网监中心备案编号:1101082001
广播电视节目制作经营许可证:(京) 字第1234号  中国互联网协会会员  测绘资质证书:乙测资字11005067  网络文化经营许可证:京网文[2012]0421-133号

从零开始创建一个Android主屏幕Widget相关推荐

  1. ultimate++使用_使用Ultimate Custom Widget个性化您的Android主屏幕

    ultimate++使用 Widgets are wonderfully versatile additions to your Android home screen. They can provi ...

  2. 如何组织Android主屏幕以实现最佳生产力

    It's nice to have plenty of applications in our Android phone, until we realize that these applicati ...

  3. 使用Tensorflow Lite创建一个Android AI应用

    目录 下一步 在这里,我们使用TensorFlow Lite解释器检查图像并产生其输出. 这是将神经网络与Android上的TensorFlow Lite结合使用的系列文章中的第三篇.在本系列的第2部 ...

  4. 从零开始创建一个uni-app项目

    从零开始创建一个uni-app项目 新建项目 目录说明 文件结构 安装uview 安装ucharts 新建项目 创建uni-app项目首先要下载HBuilder X,HBuilderX下载地址: 下载 ...

  5. android 主屏幕,如何重置Android主屏幕返回到默认启动

    一个关于最好的Android操作系统是,你可以给通过自定义您的Android体验,而无需Root权限的设备焕然一新. 而这一切都可以通过轻松完成Android启动 . 有很多发射应用程序上提供谷歌Pl ...

  6. android设置主题背景为壁纸_如何为每个Android主屏幕添加不同的壁纸 | MOS86

    Android设备有很多不同的主屏幕.问题是,当您选择一个图像作为背景墙纸,它横跨所有3有时候没关系大多数时候,您想要看到的图像的一部分就在屏幕之间的裂缝上. 为了解决这个问题,您可以使用Multip ...

  7. 使用Eclipse创建一个Android程序方法

    要编写Android程序,需要安装JDK.Eclipse和Android SDK. Android SDK的安装路径不要在program file或program file(x86)下,否则在debu ...

  8. python区块链框架_从零开始创建一个区块链应用(Python版)

    2018年什么最火?非区块链莫属! 一时间网上各种介绍区块链的文章层出不穷,但大多数都是从概念层面进行解释的,本文则从技术层面讲解,如何从零开始创建一个区块链应用. 本文使用Python开发,读者需要 ...

  9. 从零开始创建一个vue项目 1

    从零开始创建一个vue项目 创建空文件夹,存放相关目录,cmd进入命令行 vue init webpack token 创建项目(除eslint,其它都yes) 打包配置config下面的index. ...

最新文章

  1. ASP 代码给 ASP 页加密码保护
  2. 前端学习(3211):react中类中方法的this指向三
  3. 服务器图片加载慢_页面提高性能利器_懒加载
  4. 蓝屏代码PAGE_FAULT_IN_NONPAGED_AREA的解决方法
  5. 论文笔记_S2D.37_2015-TPAMI_使用深度卷积神经场从单目图像学习深度
  6. 税务计算机 试题分析,税务师考试方式、题型、计算器使用规定
  7. html5电路模拟器,仿真电路模拟器
  8. 前端Echarts数据可视化
  9. 皮亚杰的认知发展理论
  10. 【Uly】团队&团队博客成立典礼~~
  11. 卖猪还钱 法院拍卖被执行人300头生猪 40.5万成交
  12. 临沂最美乡村医生彭玉梅:救人遇车祸身亡
  13. 萌言萌语|测试工作日报及总结
  14. python基础以及面向对象
  15. 假设今天你开了一家经营生鲜品类的淘宝店,你怎么获取第一批用户, 并能够运营起来
  16. C::Mat取出指定区域的方法
  17. 金立(Gionee)金立M7 Power root 大金刚 GN5007 刷机TWRP 面具 XP框架 线刷包
  18. USB摄像头图片采集+QT显示(二)
  19. jq 数字转中文数字_阿拉伯数字 转换 中文大写
  20. Qt及Qt Quick开发实战精解项目二俄罗斯方块 items方法报错

热门文章

  1. python猜单词游戏
  2. GITHUB下载慢解决办法-插件解决
  3. 【数据结构】物流运输(最短路DP)
  4. Android开发面试经典题目
  5. linux 下文件夹无法删除(报:Device or resource busy),然后进入文件夹也无法创建新的文件夹(Permission denied)
  6. GameofMir引擎架设传奇服务器【2:登录器配置】
  7. Camera Tuning 常见缩写
  8. 一场积极的变革,期待着与5G的精彩邂逅
  9. kubernete编排技术五:DaemonSet
  10. 模型加速之openvino