`
貌似掉线
  • 浏览: 260504 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

桌面小部件AppWidget的使用

阅读更多
在android平台中,显示在HOME界面的一些挂件,即桌面小部件,被称为AppWidget。在自己的程序中适当地加入AppWidget,不但使用户更方便,也能从一定程序上提高本程序的留存率。

下面通过我所写的一个课表应用来说明如何使用AppWidget。
我所写的AppWidget最终结果如下图:



1.首先在res/layout下编写AppWidget的布局文件。
我的代码如下:
appwidget_small.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="60dp"
    android:background="@drawable/appwidget_bg" >

    <Button
        android:id="@+id/widget_small_refresh"
        android:layout_width="60dp"
        android:layout_height="40dp"
        android:layout_alignParentRight="true"
        android:text="@string/widget_small_refrest"
        android:textAppearance="@android:style/TextAppearance.Medium" />

    <TextView
        android:id="@+id/widget_small_day"
        android:layout_width="60dp"
        android:layout_height="match_parent"
        android:layout_alignParentRight="true"
        android:layout_below="@id/widget_small_refresh"
        android:gravity="center"
        android:textAppearance="@android:style/TextAppearance.Small" />

    <include
        android:id="@+id/widget_small_content"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_marginBottom="2dp"
        android:layout_marginLeft="2dp"
        android:layout_marginTop="2dp"
        android:layout_toLeftOf="@id/widget_small_refresh"
        layout="@layout/main_list_item"
        android:background="@drawable/appwidget_list_bg" />

</RelativeLayout>

其中include的是课表信息部分的布局,它在我的MainActivity还用到,这里没有另外编写,直接使用include标签将它引用进来。
main_list_item.xml的代码如下:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:orientation="horizontal" >

    <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="vertical" >

        <TextView
            android:id="@+id/list_item_class"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:singleLine="true"
            android:textAppearance="@android:style/TextAppearance.Medium" />

        <TextView
            android:id="@+id/list_item_time"
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:gravity="center"
            android:singleLine="true"
            android:textAppearance="@android:style/TextAppearance.Small" />
    </LinearLayout>

    <LinearLayout
        android:layout_width="fill_parent"
        android:layout_height="wrap_content" >

        <LinearLayout
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/list_item_course"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:singleLine="true"
                android:textAppearance="@android:style/TextAppearance.Medium" />

            <TextView
                android:id="@+id/list_item_teacher"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:singleLine="true"
                android:textAppearance="@android:style/TextAppearance.Medium" />
        </LinearLayout>

        <LinearLayout
            android:layout_width="120dp"
            android:layout_height="wrap_content"
            android:layout_weight="2"
            android:orientation="vertical" >

            <TextView
                android:id="@+id/list_item_room"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:singleLine="true"
                android:textAppearance="@android:style/TextAppearance.Medium" />

            <TextView
                android:id="@+id/list_item_week"
                android:layout_width="fill_parent"
                android:layout_height="wrap_content"
                android:gravity="center"
                android:singleLine="true"
                android:textAppearance="@android:style/TextAppearance.Medium" />
        </LinearLayout>
    </LinearLayout>

</LinearLayout>

在这里说明一下,对于appWidget的布局文件的根标签如果设置宽高为match_parent(fill_partent),则在HOME界面改变它的大小时它也会自动扩张,否则无论将它占的空间拉伸到多大,它都不会扩张。

2.在/res/xml下编写这个appwidget的信息文件。
widget_small_provider_info.xml代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:initialLayout="@layout/appwidget_small"
    android:minHeight="60dp"
    android:minWidth="240dp"
    android:updatePeriodMillis="1800000" >

</appwidget-provider>

上面initialLayout即初始的布局,minHeight和minWidth即最小的宽高,updatePeriodMillis为更新周期。
需要注意的是关于这个更新周期,在我本机G14,android4.0.3上发现它并没有用,百度之后发现它存在着BUG,在有些系统有效,有些则没效。所以如果想在任何机型都能自动更新的话,还要自己写一个service去更新。这个可参考android SDK中的例子。

3.接下来需要编写一个类,继承自AppWidgetProvider。
代码如下:
/*
 * @(#)TableWidgetProvider.java		       Project:UniversityTimetable
 * Date:2013-2-11
 *
 * Copyright (c) 2013 CFuture09, Institute of Software, 
 * Guangdong Ocean University, Zhanjiang, GuangDong, China.
 * All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.lurencun.cfuture09.universityTimetable.appwidget;

import java.util.Calendar;

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.database.Cursor;
import android.util.Log;
import android.widget.RemoteViews;

import com.lurencun.cfuture09.universityTimetable.R;

/**
 * @Author Geek_Soledad (66704238@51uc.com)
 * @Function
 */
public class TableSmallWidgetProvider extends AppWidgetProvider {
	private static final String TAG = "TableSmallWidgetProvider";
	public static final String ACTION_UPDATE = "cfuture09.universityTimetable.action.TIMETABLE.APPWIDGET_SMALL_UPDATE";
	@Override
	public void onDeleted(Context context, int[] appWidgetIds) {
		super.onDeleted(context, appWidgetIds);
		Log.d(TAG, "onDeleted");
	}

	@Override
	public void onDisabled(Context context) {
		super.onDisabled(context);
		Log.d(TAG, "onDisable");
	}

	@Override
	public void onEnabled(Context context) {
		super.onEnabled(context);
		Log.d(TAG, "onEnabled");
	}

	@Override
	public void onReceive(Context context, Intent intent) {
		super.onReceive(context, intent);
		Log.d(TAG, "onReceive");
	}

	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		Log.d(TAG, "update");
	}
}

上面onEnabled在第一次创建AppWidget中执行。
在HOME界面中是可以多次插入同一个AppWidget的,每次插入一个AppWidget,onReceive和onUpdate都会被执行,这一次可以自己去做试验了解它的生命周期,在这里不赘述。

4.在Manifest中声明。
        <receiver
            android:name=".appwidget.TableSmallWidgetProvider"
            android:label="@string/widget_small_4_1" >
            <intent-filter>
                <action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
            </intent-filter>
            <intent-filter>
                <action android:name="cfuture09.universityTimetable.action.TIMETABLE.APPWIDGET_SMALL_UPDATE" />
            </intent-filter>

            <meta-data
                android:name="android.appwidget.provider"
                android:resource="@xml/widget_small_provider_info" />
        </receiver>
其中label中引用的字符串即在插入Appwidget时出现的那个名字,如这里为"大学课程表(4*1)",如果不添加,默认为你的程序名,即在application标签中声明的label。然后加入的intent-filter,为其接收的广播,这里还定义了自己的一个action,它将在下面的例子中用到,因为我希望还能手动更新appwidget的数据。

在上面的例子中,一个简单的AppWidget就完成了。

但是我需要的还不够,我还希望这个AppWidget的控件内容是可以改变的,而不是写死在布局文件中的,这就需要用到RemoteViews了。
因为在android中,AppWidget与你的主程序是运行在不同的进程当中的,在这里需要用RemoteViews来进行它们之间的通信,而不是像在Activity中那样方便。
而对于RemoteViews在不同版本的API中,支持的控件(亦其提供的方法)也不同,越往后支持的越多,在2.2中,貌似还不支持AbsListView控件的更新,也只提供了简单的onclick事件绑定的方法。

首先创建一个RemoteViwews对象,RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.appwidget_small);
然后可以通过它的setTextViewText方法设置AppWidget中的TextView的内容,传入的参数为要设置的textview的id和内容。
如果想点击它而打开你的程序的activity,或者更新控件,则也如下面代码所示。
	@Override
	public void onUpdate(Context context, AppWidgetManager appWidgetManager,
			int[] appWidgetIds) {
		super.onUpdate(context, appWidgetManager, appWidgetIds);
		Log.d(TAG, "onUpdate");
		for (int i = 0; i < appWidgetIds.length; i++) {
			RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
					R.layout.appwidget_small);
			// 设置星期几
			remoteViews.setTextViewText(R.id.widget_small_day,
					arrayWeeks[currentDay]);
			// 打开程序
			PendingIntent startIntent = PendingIntent.getActivity(context, 0,
					new Intent(context, MainActivity.class), 0);
			remoteViews.setOnClickPendingIntent(R.id.widget_small_content,
					startIntent);
			// 更新控件的事件绑定
			Intent intent = new Intent();
			intent.setAction(ACTION_UPDATE);
			// 以发送广播消息的方式创建PendingIntent.
			PendingIntent pending_intent = PendingIntent.getBroadcast(context,
					0, intent, 0);
			remoteViews.setOnClickPendingIntent(R.id.widget_small_refresh,
					pending_intent);
			appWidgetManager.updateAppWidget(appWidgetIds[i], remoteViews);
		}
	}

在更新控件中,由于它是发送了一个广播,onReceive将会被执行,但不会执行onUpdate方法,所以这里还需要再修改onReceive方法,否则无法达到更新的目的。
	@Override
	public void onReceive(Context context, Intent intent) {
		Log.d(TAG, "onReceive");
		if (ACTION_UPDATE.equals(intent.getAction())) {
			RemoteViews remoteViews = new RemoteViews(context.getPackageName(),
					R.layout.appwidget_small);
			// 设置星期几
			remoteViews.setTextViewText(R.id.widget_small_day,
					arrayWeeks[currentDay]);
			// 更新节课
			updateWidgetViews(remoteViews, dto);
			PendingIntent startIntent = PendingIntent.getActivity(context, 0,
					new Intent(context, MainActivity.class), 0);
			remoteViews.setOnClickPendingIntent(R.id.widget_small_content,
					startIntent);

			ComponentName componentName = new ComponentName(context,
					TableSmallWidgetProvider.class);
			AppWidgetManager.getInstance(context).updateAppWidget(
					componentName, remoteViews);
		} else {
			super.onReceive(context, intent);
		}
	}
  • 大小: 397.5 KB
0
0
分享到:
评论

相关推荐

    Android桌面小组件(AppWidget)

    1. **AppWidget介绍**:AppWidget是Android系统提供的一个特性,它允许开发者将应用程序的功能以小部件的形式展示在用户的桌面,提升用户体验。用户可以直接在主屏幕上添加、删除和调整小组件的大小。 2. **...

    android之appwidget(一)简单appwidget

    当然,AppWidget的功能远不止于此,你可以实现更复杂的功能,如自定义小部件服务(AppWidgetService)、接收数据更新(通过BroadcastReceiver或ContentProvider)等。继续深入学习,你就能构建出更加丰富的桌面组件...

    android 桌面组件 App widget的使用 AppWidgetProvider

    这包括设置其类名以及关联的 `&lt;appwidget-provider&gt;` 元素,定义小部件的大小、更新间隔、初始布局等属性。 ```xml &lt;action android:name="android.appwidget.action.APPWIDGET_UPDATE" /&gt; android:name=...

    Android之AppWidget(桌面小部件)开发浅析

    AppWidget 即桌面小部件,也叫桌面控件,就是能直接显示在Android系统桌面上的小程序,先看图:   图中我用黄色箭头指示的即为AppWidget,一些用户使用比较频繁的程序,可以做成AppWidget,这样能方便地使用。典型...

    Android高级应用源码-Android小部件AppWidget.zip

    在Android平台上,AppWidget是应用程序可以提供的一种桌面小部件,让用户在主屏幕上获得快速的交互体验,无需打开完整的应用程序。这个“Android高级应用源码-Android小部件AppWidget.zip”包含了一个关于如何创建和...

    Android小部件AppWidget

    - **AppWidget布局**: 使用XML定义的小部件视图,类似于Activity的布局文件,但专门为AppWidget设计。 - **AppWidgetProviderInfo**: 描述AppWidget的元数据,包括大小、最小尺寸、更新间隔等信息,用于设置和展示...

    Android应用源码之Android小部件AppWidget.zip

    Android小部件(AppWidget)是Android系统提供的一种特殊类型的用户界面组件,允许开发者在用户的主屏幕上添加可交互的微型应用程序视图。这个压缩包“Android应用源码之Android小部件AppWidget.zip”包含了一个用于...

    安卓Android源码——安卓Android小部件AppWidget.rar

    在安卓平台上,AppWidget是Android系统提供的一种轻量级组件,允许开发者在用户的主屏幕上创建交互式的迷你应用程序,也就是我们通常所说的桌面小部件。这个压缩包"安卓Android源码——安卓Android小部件AppWidget....

    Android 桌面组件【app widget】 进阶项目--心情记录器

    在这个进阶项目“Android桌面组件【app widget】—心情记录器”中,我们将深入探讨如何创建一个能够帮助用户便捷记录和展示心情的小部件。 首先,我们需要理解App Widget的基本构成。一个App Widget通常包含以下几...

    android 桌面控件appwidget

    Android 桌面控件(AppWidget)是Android操作系统提供的一种独特功能,允许开发者创建可以在用户主屏幕上显示的小型应用程序组件。这些控件通常提供快速访问应用的核心功能或展示实时信息,如天气预报、日历事件或...

    Android代码-Android小部件AppWidget.rar

    在Android平台上,AppWidget是应用程序可以提供的一种小型用户界面组件,它们可以在用户的主屏幕上显示,类似于桌面小部件。这些小部件通常用于提供快速访问或控制应用程序的功能,无需真正打开应用程序。"Android...

    android appwidget使用说明及示例程序

    Android AppWidget是Android系统提供的一种轻量级组件,允许开发者在用户的主屏幕上创建小型应用程序,通常称为小部件或快捷方式。这些小部件不需要用户启动应用,就能直接在主屏幕上显示和交互,为用户提供便捷的...

    Android小部件AppWidget-IT计算机-毕业设计.zip

    【Android小部件AppWidget】是Android操作系统中的一种特殊组件,它允许用户在主屏幕上放置小型的应用程序界面元素,提供快捷的操作或显示实时信息。在Android应用开发中,AppWidget是扩展应用程序功能的一种方式,...

    Android-Android桌面小部件widget日签Or日历可作为桌面日历

    在Android平台上,开发者可以利用Android桌面小部件(Widget)功能为用户提供便捷的桌面服务,比如“Android桌面小部件widget日签Or日历可作为桌面日历”就是一个很好的例子。这个应用设计巧妙,不仅展示了日期,还...

    AppWidget桌面小控件

    AppWidget桌面小控件是Android操作系统提供的一种独特功能,它允许开发者将应用程序的部分功能或信息直接展示在用户的手机或平板电脑的主屏幕上,无需打开应用即可进行交互。AppWidget不仅提升了用户体验,还增加了...

    AppWidget

    AppWidget是Android系统提供的一种组件,它允许开发者在用户的主屏幕上创建自定义的小部件,无需用户启动应用程序。这种功能极大地增强了用户体验,使用户能够快速访问或控制应用的功能,而无需打开应用本身。本文将...

    安卓Android源码——安卓Android小部件AppWidget.zip

    在安卓平台上,AppWidget是应用程序提供给用户桌面的一种小型交互式UI组件。它们类似于iOS中的小工具,允许用户在主屏幕上查看和操控应用程序的部分功能,而无需打开应用本身。通过分析这份"安卓Android源码——安卓...

    android appwidget全面解析

    AppWidget,即桌面小部件,是Android系统提供的一种允许应用程序在主屏幕放置动态更新的组件,用户无需打开完整应用即可查看信息或进行简单交互。本文将全面解析AppWidget的工作原理、生命周期、启动运行过程以及...

Global site tag (gtag.js) - Google Analytics