AppWidget实例

来源:互联网 发布:deepin qq for ubuntu 编辑:程序博客网 时间:2024/06/03 23:47

1.概念:

桌面工具(Widget)是Android系统的一大特色,通过桌面工具可以快速得到所需的信息,不必打开程序即可了解最新的内容,就好像是一个应用程序的快捷方式。Android系统自带了一些常用的桌面工具,其他一些经过定制的系统也带有具有特色的桌面工具,同时,有很多第三方程序也支持桌面工具。例如新浪微博提供的AppWidget

 AppWidget


在了解完AppWidget的概念后,我们就要开发一个类似的应用。首先来看个制作的效果:

         

2.代码部分:

新建个程序,并添加以下代码:

MainActivity.java

<span style="font-size:18px;">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);    }}</span>


 MyAppWidget.java

<span style="font-size:18px;">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);    }}</span>

res/layout/activity_main.xml:

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:orientation="vertical"    android:layout_width="fill_parent"    android:layout_height="fill_parent">    <TextView        android:layout_width="fill_parent"        android:layout_height="wrap_content"        android:text="程序入口" /></LinearLayout></span>

res/layout/my_appwidget_layout.xml:

这里需要注意的是,appwidget的布局文件并不是支持所有的控件,在上述代码中已经看到使用的是RemoteViews,它并不支持所有控件。RemoteViews还用在notification中。

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?><LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"    android:layout_width="match_parent"    android:layout_height="match_parent"    android:orientation="vertical"    android:background="@drawable/background">    <Button        android:id="@+id/contentBtn"        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:layout_gravity="center"        android:text="点击进入主程序" />    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="控件其余内容"        android:textSize="20sp"        android:layout_gravity="center"        android:textColor="#000000"/>    <TextView        android:layout_width="wrap_content"        android:layout_height="wrap_content"        android:text="控件其余内容"        android:textSize="20sp"        android:layout_gravity="center"        android:textColor="#000000"/></LinearLayout></span>

res/xml/my_appwidget.xml:

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?><!-- AppWidgetProvderInfo: 描述AppWidget的大小、更新频率和初始界面等信息,以XML文件形式存在于应用的res/xml/目录下。注意:SDK1.5之后此android:updatePeriodMillis就失效了,要自己创建service更新 --><appwidget-provider    xmlns:android="http://schemas.android.com/apk/res/android"    android:minWidth="150dip"    android:minHeight="150dip"    android:updatePeriodMillis="1000"    android:layout_height="wrap_content"    android:layout_width="wrap_content"    android:initialLayout="@layout/my_appwidget_layout"/></span>

AndroidManifest.xml:

<span style="font-size:18px;"><?xml version="1.0" encoding="utf-8"?><manifest xmlns:android="http://schemas.android.com/apk/res/android"    package="com.example.lxxcaroline.myappwidget"    android:versionCode="1"    android:versionName="1.0">    <application        android:icon="@drawable/icon"        android:label="@string/app_name">        <activity            android:name="com.example.lxxcaroline.myappwidget.MainActivity"            android:label="主程序">            <intent-filter>                <action android:name="android.intent.action.MAIN" />                <category android:name="android.intent.category.LAUNCHER" />            </intent-filter>        </activity>        <!-- MyAppWidget类为一个广播接收器,因为MyAppWidget继承自AppWidgetProvider -->        <receiver            android:name="com.example.lxxcaroline.myappwidget.MyAppWidget"            android:label="添加桌面控件">            <intent-filter>                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />            </intent-filter>            <meta-data                android:name="android.appwidget.provider"                android:resource="@xml/my_appwidget" />        </receiver>    </application>    <uses-sdk android:minSdkVersion="7" /></manifest></span>

项目中用到的图片资源不再说明,读者可以随便贴几张png的图片放在drawable下面。

3.代码说明:

程序正常入口是进入到MainActivity里面去,显示的是activity_main.xml的页面内容。

当点击应用程序图标进入时,MyAppWidget中的代码并不会执行。

接下来为该应用程序创建应用桌面图标,即AppWidgetAppWidget的图样显示是由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

0 0