桌面控件是通过 Broadcast 的形式来进行控制的,因此每个桌面控件都对应于一个BroadcastReceiver。为了简化桌面控件的开发,Android 系统提供了一个 AppWidgetProvider类 , 它 就 是 BroadcastReceiver 的 子 类 , 也 就 是 说 开 发 者 开 发 桌 面 控 件 只 要 继 承
AppWidgetProvider 类即可。

为了开发桌面控件,开发者只要开发一个继承 AppWidgetProvider 的子类,并重写AppWidgetProvider 不同状态的生命周期方法即可。AppWidgetProvider 里提供如下 4 个不同的生命周期方法。

  • onUpdate():负责更新桌面控件的方法;实现桌面控件通常会考虑重写该方法。
  • onDeleted():当一个或多个桌面控件被删除时回调该方法。
  • onEnabled():当接收到ACTION_APPWIDGET_ENABLED Broadcast 时回调该方法。
  • onDisabled():当接收到 ACTION_APPWIDGET_DISABLED Broadcast 时回调该方法。

一般来说,开发桌面控件只需要定义一个 AppWidgetProvider 的子类,并重写它的onUpdate()方法即可,重写该方法按如下步骤进行。

  1. 创建一个 RemoteViews 对象,创建该对象时可以指定加载指定的界面布局文件。
  2. 如果需要改变上一步所加载的界面布局文件的的内容,可通过 RemoteViews 对象进行修改。
  3. 创建一个 ComponentName 对象。
  4. 调用 AppWidgetManager 更新桌面控件。

 

如下代码简单的将一张图片作为部件放到桌面上:

public class DesktopApp extends AppWidgetProvider
{
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
// 加载指定界面布局文件,创建RemoteViews对象
RemoteViews remoteViews = new RemoteViews(
context.getPackageName(),
R.layout.main); //①
// 为show ImageView设置图片
remoteViews.setImageViewResource(R.id.show
, R.drawable.logo); //②
// 将AppWidgetProvider子类实例包装成ComponentName对象
ComponentName componentName = new ComponentName(
context, DesktopApp.class); //③
// 调用AppWidgetManager将remoteViews添加到ComponentName中
appWidgetManager.updateAppWidget(componentName
, remoteViews); //④
}
}

为了实现一个液晶时钟的桌面组件,开发者需要在程序界面上定义 8 个 ImageView,其中 6 个 ImageView 用于显示小时、分钟、秒钟的数字,另外两个 ImageView 用于显示小时、分钟、秒钟之间的冒号。

为了让桌面组件实时地显示当前时间,程序需要每隔 1 秒更新一次程序界面上的 6 个ImageView,让它们显示当前小时、分钟、秒钟的数字即可。

LED电子时钟桌面部件依赖如下代码实现:

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<!-- 定义5个ImageView来显示液晶数字 -->
<ImageView
android:id="@+id/img01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/img02"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/img03"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/su00"
/>
<ImageView
android:id="@+id/img04"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/img05"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/img06"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/su00"
/>
<ImageView
android:id="@+id/img07"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
<ImageView
android:id="@+id/img08"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
/>
</LinearLayout>

Manifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="org.crazyit.desktop"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="17" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name">
<receiver
android:name=".LedClock"
android:label="@string/app_name">
<!-- 将该BroadcastReceiver当成桌面控件 -->
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<!-- 指定桌面控件的meta-data -->
<meta-data
android:name="android.appwidget.provider"
android:resource="@xml/my_clock" />
</receiver>
</application>
</manifest>

my_clock.xml

<?xml version="1.0" encoding="utf-8"?>
<!-- 指定该桌面组件的基本配置信息:
minWidth:桌面控件的最小宽度。
minWidth:桌面控件的最小高度。
updatePeriodMillis:更新频率
initialLayout:初始时显示的布局 -->
<appwidget-provider
xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="800px"
android:minHeight="30px"
android:updatePeriodMillis="1000"
android:initialLayout="@layout/main"/>

LedClock.java

package org.crazyit.desktop;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask; import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.os.Handler;
import android.os.Message;
import android.widget.RemoteViews; /**
* Description:
* <br/>site: <a href="http://www.crazyit.org">crazyit.org</a>
* <br/>Copyright (C), 2001-2014, Yeeku.H.Lee
* <br/>This program is protected by copyright laws.
* <br/>Program Name:
* <br/>Date:
* @author Yeeku.H.Lee kongyeeku@163.com
* @version 1.0
*/
public class LedClock extends AppWidgetProvider
{
private Timer timer = new Timer();
private AppWidgetManager appWidgetManager;
private Context context;
// 将0~9的液晶数字图片定义成数组
private int[] digits = new int[]
{
R.drawable.su01,
R.drawable.su02,
R.drawable.su03,
R.drawable.su04,
R.drawable.su05,
R.drawable.su06,
R.drawable.su07,
R.drawable.su08,
R.drawable.su09,
R.drawable.su10,
};
// 将显示小时、分钟、秒钟的ImageView定义成数组
private int[] digitViews = new int[]
{
R.id.img01,
R.id.img02,
R.id.img04,
R.id.img05,
R.id.img07,
R.id.img08
};
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds)
{
System.out.println("--onUpdate--");
this.appWidgetManager = appWidgetManager;
this.context = context;
// 定义计时器
timer = new Timer();
// 启动周期性调度
timer.schedule(new TimerTask()
{
public void run()
{
// 发送空消息,通知界面更新
handler.sendEmptyMessage(0x123);
}
}, 0, 1000);
} private Handler handler = new Handler()
{
public void handleMessage(Message msg)
{
if (msg.what == 0x123)
{
RemoteViews views = new RemoteViews(context
.getPackageName(), R.layout.main);
// 定义SimpleDateFormat对象
SimpleDateFormat df = new SimpleDateFormat(
"HHmmss");
// 将当前时间格式化成HHmmss的形式
String timeStr = df.format(new Date());
for(int i = 0 ; i < timeStr.length() ;i++)
{
// 将第i个数字字符转换为对应的数字,charAt函数返回的是ASCII编码,1的ASCII编码是49,所以需要减去偏移量48。
int num = timeStr.charAt(i) - 48;
// 将第i个图片的设为对应的液晶数字图片
views.setImageViewResource(digitViews[i], digits[num]);
}
// 将AppWidgetProvider子类实例包装成ComponentName对象
ComponentName componentName = new ComponentName(context,
LedClock.class);
// 调用AppWidgetManager将remoteViews添加到ComponentName中
appWidgetManager.updateAppWidget(componentName, views);
}
super.handleMessage(msg);
}
};
}

效果:

桌面小部件----LED电子时钟实现的更多相关文章

  1. 解决 三星Note3 桌面小部件不实时更新/不刷新 的问题

    机型及问题描述:我的是三星note3 (国行 SM-N9008V),已ROOT,安装了LBE安全大师.在桌面小部件中,有些不会实时更新.比如有 滴答清单(办过的事项无法勾选),百度云音乐(歌曲播放更新 ...

  2. Android 桌面小部件

    1. 添加AppWidgetProvider 实际上就是个带有界面的BroadcastReceiver public class SimpleWidgetProvider extends AppWid ...

  3. Android开发中实现桌面小部件

    详细信息请参考原文:Android开发中实现桌面小部件 在Android开发中,有时候我们的App设计的功能比较多的时候,需要根据需要更简洁的为用户提供清晰已用的某些功能的时候,用桌面小部件就是一个很 ...

  4. 桌面小部件AppWidgetProvider简单分析

    1.一般桌面小部件涉及到的类 AppWidgetProvider :BroadcastRecevier子类,用于接收更新,删除通知 AppWidgetProvderInfo:AppWidget相关信息 ...

  5. 桌面小部件Wight父类AppWidgetProvider的三个方法

    onUpdate()这个方法会在每次更新App Widget的时候调用,数据更新的逻辑都写在这个方法里边.而且要注意的是:在用户添加小部件的时候,会首先调用这个方法,应该在这个方法里进行初始化操作,比 ...

  6. 优质Android小部件:索尼滚动相册

    虽然骚尼手机卖的不怎么样,但是有些东西还是做的挺好的,工业设计就不用说了,索尼的相册的双指任意缩放功能也是尤其炫酷.其桌面小部件滚动相册我觉得也挺好的,比谷歌原生的相册墙功能好多了,网上搜了一下也没发 ...

  7. Android-RemoteView-桌面小部件

    Android-RemoteView-桌面小部件 学习自 <Android开发艺术探索> https://developer.android.google.cn/guide/topics/ ...

  8. 【Android界面实现】AppWidght全面学习之电量监控小部件的实现具体解释

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/bz419927089/article/details/35791047 前几天翻看之前下载的各种资料 ...

  9. Android简易实战教程--第十四话《模仿金山助手创建桌面Widget小部件》

    打开谷歌api,对widget小部件做如下说明: App Widgets are miniature application views that can be embedded in otherap ...

随机推荐

  1. foxmail客户端总是提示接收密码错误

    如上图所示. 我知道的一个原因是 发送太多邮件所致,导致发件服务器触发规则限制登录. 如果之前发的不是很多的话,可以在设置的帐号选项里删除这个账户,再重新建一个.

  2. slides 带手势的图片滑动效果(用于移动终端)

    slidesjs 是基于jQuery开发的一款功能强大,是简单的幻灯片插件,但是需要要应用于移动终端的话,还需要考虑手势滑动时候图片切换功能. 此次,我就在slidesjs基础上扩展了两个swipe属 ...

  3. SAP-MM:收货转储时提示 M7053“只能在公司代码 **** 的期间 2014/04 和 2014/03 中记账”

    错误信息   消息号M7053   解决方法 Step 1.使用MMPV进入"关闭账期"界面. Step 2.输入"公司代码"."期间".& ...

  4. [Angular 2] ng-class and Encapsulated Component Styles

    import {Input, Component, View, NgClass} from "angular2/angular2"; @Component({ selector: ...

  5. RSA体系 c++/java相互进行加签验签--转

    在web开发中,采用RSA公钥密钥体系自制ukey,文件证书登陆时,普遍的做法为:在浏览器端采用c++ activex控件,使用 c++的第三库openssl进行RAS加签操作,在服务器端采用java ...

  6. Linux 信号表

    信号 取值 默认动作 含义(发出信号的原因) SIGHUP 1 Term 终端的挂断或进程死亡 SIGINT 2 Term 来自键盘的中断信号 SIGQUIT 3 Core 来自键盘的离开信号 SIG ...

  7. 设计模式UML图

    1.简单工厂模式 2.工厂模式 工厂模式与简单工厂模式的不同在于,每个操作类都有自己的工厂,而且把逻辑判断交给了客户端,而简单工厂的逻辑判断在工厂类里边,当增加新的操作类时,简单工厂需要修改工厂类,而 ...

  8. VB php JAVA关于数据库连接数过多的解决方法

    这里讲解一个关于数据库连接多多的解决办法 一般都会在方法中进行数据库的开,利用和关 不过如果在一个循环里面使用的时候 这样数据库的连接数就会过多,如果是1万次的话,数据库服务器可能就会当机 PHP 中 ...

  9. 开源的Android开发框架-------PowerFramework使用心得(一)总体介绍

    PowerFramework是一款几乎囊括了所有Android基础功能的框架应用,这个框架目前是开源的,开发者可以在这个框架的基础上进行二次开发.结合开发者自己的UI设计,可以很快就能开发出具备基础应 ...

  10. Swift - 03 - 整数类型

    //: Playground - noun: a place where people can play import UIKit var str = "Hello, playground& ...