App Widget是一些桌面的小插件,比如说天气和某些音乐播放应用,放到桌面去的那部分;

例如:

实现步骤及代码如下:

(1)首先,在AndroidManifest.xml中声明一个App Widget;

(1)定义AppWidgetProviderInfo对象:为App Widget提供元数据,包括布局、更新频率等,这个对象定义在XML文件当中;

  在res/xml文件夹中定义一个名为example_appwidget_info.xml的文件;

(2)为App Widget指定样式和布局:

  定义一个新的布局文件example_appwidget.xml;

(3)实现AppWidgetProvider:定义了App Widget的基本生命周期函数;

  onUpdate:在到达指定的更新时间之后或当前用户向桌面添加App Widget时调用该方法;

  onDeleted:当App Widget被删除时,会调用该方法;

  onEnabled:当一个App Widget的实例第一次被创建时,会调用该方法;

  onDisabled:当最后一个App Widget实例被删除后,会调用该方法;

  onReveice:接收广播事件;

详细实现步骤可参考官方文档,讲解的十分详细:

http://android.toolib.net/guide/topics/appwidgets/index.html

http://developers.androidcn.com/guide/topics/appwidgets/index.html#Providers

代码:

AndroidManifest.xml中声明 App Widget:

<receiver android:name="ExampleAppWidgetProvider" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/example_appwidget_info" />
        </receiver>

res/xml目录下的example_appwidget_info.xml:

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/example_appwidget"
    android:minHeight="294dp"
    android:minWidth="72dp"
    android:updatePeriodMillis="86400000" >

</appwidget-provider>

新的布局文件 example_appwidget.xml:

<?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" >

    <TextView
        android:id="@+id/widgetTextId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#00FFCC"
        android:text="widget是一些桌面的小插件" />

</LinearLayout>

定义类ExampleAppWidgetProvider继承AppWidgetProvider:

package com.example.appwidgettest2;

import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        System.out.println("onUpdate");
        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        System.out.println("onDeleted");
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onDisabled(Context context) {
        System.out.println("onDisabled");
        super.onDisabled(context);
    }

    @Override
    public void onEnabled(Context context) {
        System.out.println("onEnabled");
        super.onEnabled(context);
    }
}

删除一个App Widget:

全部删除:

在此基础上,来看另一个例子:

给原先的App Widget添加一个按钮,点击后能跳转到另一个Activity;

实现方式为:

  使用PendingIntent和RemoteViews来实现;

(1)创建PendingIntent的方法有3种;

 

 getActivity(Context context, int requestCode, Intent intent, int flags)

 getBroadcast(Context context, int requestCode, Intent intent, int flags)

 getService(Context context, int requestCode, Intent intent, int flags)

(2)RemoteViews的作用:

  RemoteViews对象表示了一系列的View对象;

  RemoteViews所代表的对象运行在另外的线程当中;

(3)因为App Widget和我们的应用程序运行在不同的进程当中(App Widget当中的View运行在Home Screen进程当中),所以无法按照之前那种方式绑定监听器;

  而是应该使用remoteViews.setOnClickPendingIntent(R.id.widgetButtonId,pendingIntent)来实现;

TargetActivity.java

package com.example.appwidgettest2;

import android.app.Activity;
import android.os.Bundle;

public class TargetActivity extends Activity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.target_activity);
    }
}

target_activity.xml

<?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" >

    <TextView
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:textSize="20sp"
        android:gravity="center"
        android:text="跳转到这个Activity" />

</LinearLayout>

而ExampleAppWidgetProvider修改为:

package com.example.appwidgettest2;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.widget.RemoteViews;

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {
        System.out.println("onUpdate");

        for (int i = 0; i < appWidgetIds.length; i++) {
            System.out.println(appWidgetIds[i]);
            // 创建一个Intent对象
            Intent intent = new Intent(context, TargetActivity.class);
            // 创建一个PendingIntent
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0,
                    intent, 0);
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.example_appwidget);
            // 为按钮绑定事件处理器,
            // 第一个参数用来指定被绑定处理器控件的ID;
            // 第二个参数用来指定当事件发生时,哪个PendingIntent将会被指定;
            remoteViews.setOnClickPendingIntent(R.id.widgetButtonId,
                    pendingIntent);
            // 更新AppWidget
            appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
        }

        super.onUpdate(context, appWidgetManager, appWidgetIds);
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }
}

再来看另一个例子:使用RemoteViews对象更新AppWidget当中控件的状态;

效果如下:

点击按钮,更新状态:

不过需要注意的是:

(1)要更新控件的状态,需要用到广播机制,要使用getBroadcast来创建PendingIntent;

(2)在使用RemoteViews更新控件状态之后,需要使用AppWidgetManager通知AppWidget进行更新;

代码:

AndroidManifest.xml添加receiver:

  <receiver android:name="ExampleAppWidgetProvider" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <intent-filter>
                <action android:name="com.xiaozhang.UPDATE_APP_WIDGET" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/example_appwidget_info" />
        </receiver>

example_appwidget.xml

<?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" >

    <TextView
        android:id="@+id/widgetTextId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:background="#CCFFCC"
        android:textSize="20sp"
        android:text="right.png" />

    <ImageView
        android:id="@+id/imageId"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/right" />

    <Button
        android:id="@+id/widgetButtonId"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="button" />

</LinearLayout>

ExampleAppWidgetProvider.java

package com.example.appwidgettest2;

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;

public class ExampleAppWidgetProvider extends AppWidgetProvider {

    final static String UPDATE_ACTION = "com.xiaozhang.UPDATE_APP_WIDGET";

    @Override
    public void onUpdate(Context context, AppWidgetManager appWidgetManager,
            int[] appWidgetIds) {

        Intent intent = new Intent();
        intent.setAction(UPDATE_ACTION);
        // 创建一个PendingIntent
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, -1,
                intent, 0);

        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                R.layout.example_appwidget);
        // 为按钮绑定事件处理器,
        // 第一个参数用来指定被绑定处理器控件的ID;
        // 第二个参数用来指定当事件发生时,哪个PendingIntent将会被指定;
        remoteViews.setOnClickPendingIntent(R.id.widgetButtonId, pendingIntent);
        // 更新AppWidget
        appWidgetManager.updateAppWidget(appWidgetIds, remoteViews);

    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (UPDATE_ACTION.equals(action)) {
            RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
                    R.layout.example_appwidget);
            remoteViews.setImageViewResource(R.id.imageId, R.drawable.wrong);
            remoteViews.setTextViewText(R.id.widgetTextId, "wrong.png");
            AppWidgetManager appWidgetManager = AppWidgetManager
                    .getInstance(context);
            ComponentName componentName = new ComponentName(context,
                    ExampleAppWidgetProvider.class);
            appWidgetManager.updateAppWidget(componentName, remoteViews);
        } else {
            super.onReceive(context, intent);
        }
    }

    @Override
    public void onDeleted(Context context, int[] appWidgetIds) {
        super.onDeleted(context, appWidgetIds);
    }

    @Override
    public void onDisabled(Context context) {
        super.onDisabled(context);
    }

    @Override
    public void onEnabled(Context context) {
        super.onEnabled(context);
    }
}

Android App Widget的简单使用的更多相关文章

  1. android app widget 创建调用周期

    1 ?Android widget 大小问题 2 ?RemoteViewService Android开发历程_15(AppWidget的使用) Appwidget就是手机应用中常常放在桌面(即hom ...

  2. Android app widget中实现跑马灯效果(非widget部件也实用)

    原文地址:http://blog.csdn.net/luoyebuguigen/article/details/37533631 关键是需要在TextView中嵌入requestForcus标签才会有 ...

  3. [安卓开发]App Widget开发入门指导

    本节所要讲的主要内容包括Android桌面小部件.App Widget的开发入门指导,并通过一个简单实例的形式来直观的讲解App Widget. 一.Widget .App Widget .Web A ...

  4. Android APP 简单高效的禁用横竖屏切换

    默认情况下,Android APP的界面会随着手机方向的改变而改变,当手机处于竖屏状态,APP的界面也处于竖屏状态,而当手机处于横屏状态,APP也会自动切换到横屏状态.一般情况下APP的界面都是为竖屏 ...

  5. Android 之窗口小部件高级篇--App Widget 之 RemoteViews - 跨到对岸去

    在之前的一篇博文( Android 之窗口小部件详解--App Widge t)中,已经介绍了App Widget的基本用法和简单实例.这篇主要讲解 App Widget 的高级内容,即通过 Remo ...

  6. Android 之窗口小部件高级篇--App Widget 之 RemoteViews

    Android 之窗口小部件高级篇--App Widget 之 RemoteViews 在之前的一篇博文(Android 之窗口小部件详解--App Widget)中,已经介绍了App Widget的 ...

  7. App Widget简单应用

    首先后台进程创建一个PendingIntent对象,其中PendingIntent中包含一个真正的Intent,创建完成后将此PendingIntent对象交给桌面控件所在的进程,当用户点击桌面控件或 ...

  8. Android 之窗口小部件详解--App Widget

    Android 之窗口小部件详解--App Widget  版本号 说明 作者 日期  1.0  添加App Widge介绍和示例  Sky Wang 2013/06/27        1 App ...

  9. Android开发之创建App Widget和更新Widget内容

    App WidgetsApp Widgets are miniature application views that can be embedded in other applications (s ...

随机推荐

  1. 使用strace查看C语言级别的php源码

    XCACHE XCache 是一个开源的 opcode 缓存器/优化器, 这意味着他能够提高您服务器上的 PHP 性能. 他通过把编译 PHP 后的数据缓冲到共享内存从而避免重复的编译过程, 能够直接 ...

  2. Linux网络配置相关

    路由相关 #添加到主机的路由 route add -host 192.168.1.2 dev eth0 route add -host 192.168.1.2 gw 192.168.1.1 注1:添加 ...

  3. (转)OS X Mountain Lion 系统配置 Apache+Mysql+PHP 详细教程

    如果你是一名 Web 开发者,很多时候都需要在本地搭建服务器测试环境,比如 Apache+Mysql+PHP 这样的环境.事实上 Mac OS X 中想要搭建这样的环境很简单,本文我们就会将详细的教程 ...

  4. 设计模式16---设计模式之组合模式(Composite)(行为型)

    1.场景模拟 使用软件模拟大树的根节点和树枝节点和叶子节点 抽象为两类,容器节点和叶子节点 2.不用模式的解决方案 package demo14.composite.example1; import ...

  5. 一步一步教你做ios推送

    最近在研究ios的推送问题,遇到了一些问题,最终整理了一下.放在这里和大家分享 APNS的推送机制 首先我们看一下苹果官方给出的对ios推送机制的解释.如下图 Provider就是我们自己程序的后台服 ...

  6. [React Testing] Element types with Shallow Rendering

    When you render a component with the Shallow Renderer, you have access to the underlying object. We ...

  7. 2d-x中Lua类型强转问题

    在Lua中,使用CCDictionary进行保存CCSprite对象,但是,在CCDictionary取出来的时候,此时是一个CCObject对象,无法调用子类精灵的一些方法.那只能进行强转的. 那么 ...

  8. Word02-隐藏回车换行符

    Word文档中每次输入回车后,会显示一个换行标志符,影响页面显示效果. 如下图,换行符隐藏前后: 设置方法:(选项-->显示-->段落标记前面的√去掉即可)

  9. Python 正则表达试

    字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在.比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦, ...

  10. 任务栈 启动模式 Flag taskAffinity

    关于任务栈Task 栈的概念 栈(Stack)是一种常用的数据结构,栈只允许访问栈顶的元素,栈就像一个杯子,每次都只能取杯子顶上的东西,而对于栈就只能每次访问它的栈顶元素,从而可以达到保护栈顶元素以下 ...