文档章节

Android AppWidget开发

1071954237
 1071954237
发布于 2016/10/20 20:24
字数 1834
阅读 15
收藏 0

首先,声明您的应用程序的 AndroidManifest.xml 文件中的 AppWidgetProvider 类。例如︰

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

ExampleAppWidgetProvider是需要实现的APPWidgetProvider子类 Intent-filter指定了AppWidgetProvider要接收的广播事件是android.appwidget.action.APPWIDGET_UPDATE

AppWidgetProviderInfo 定义了应用程序部件,例如其最低的布局尺寸,其初始布局资源,如何经常来更新应用程序的小部件,以及 (可选) 配置活动在创建时间启动的必备素质。在使用 <appwidget-provider> 的单个元素的 XML 资源中定义的 AppWidgetProviderInfo 对象并将其保存在该项目的 res xml/文件夹。

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
    android:minWidth="40dp"
    android:minHeight="40dp"
    android:updatePeriodMillis="86400000"
    android:previewImage="@drawable/preview"
    android:initialLayout="@layout/example_appwidget"
    android:configure="com.example.android.ExampleAppWidgetConfigure" 
    android:resizeMode="horizontal|vertical"
    android:widgetCategory="home_screen">
</appwidget-provider>

1.InitialLayout 属性指向定义的应用程序部件布局布局资源。 配置属性定义活动推出当用户添加应用程序的小部件,以便他或她要配置的应用程序部件属性。 2.PreviewImage 属性指定的应用程序部件后它配置,用户可以看到当选择的应用程序构件的外观的预览。如果未提供,用户可以相反看到您的应用程序启动器图标。此字段对应于安卓系统︰ previewImage 属性在 AndroidManifest.xml 文件中的 <receiver>元素。 3.WidgetCategory 属性声明是否可以在主屏幕 (home_screen)、 锁定屏幕 (键盘锁),或两者上显示你的应用程序部件。只有 Android 版本低于 5.0 支持锁定屏幕小部件。对于 Android 5.0 和更高,只有 home_screen 是有效的。

为应用程序窗口小部件添加边距

小部件通常不应扩展至屏幕边缘和不直观地应冲洗与其他小部件,所以你应该添加边距四面环绕你小部件框架。

到安卓 4.0 中,应用程序窗口小部件就自动给定应用程序构件与构件框架的填充边界框可提供更好的协调与其他小部件和用户的主屏幕上的图标。要利用此强烈推荐行为,请将您的应用程序的 targetSdkVersion 设置为 14 或更高版本。

创建一个布局如下面,引用其边距维度资源︰

<FrameLayout
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  android:padding="@dimen/widget_margin">
  <LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal"
    android:background="@drawable/my_widget_background">
    …
  </LinearLayout>
</FrameLayout>

创建两个dimension resource,另一个在 res/value/ 中提供预安卓 4.0 自定义边距,在 res/值-v14 / 提供安卓 4.0 小部件没有额外的边距︰

res/values/dimens.xml:
<dimen name="widget_margin">8dp</dimen>
res/values-v14/dimens.xml:
<dimen name="widget_margin">0dp</dimen>

AppWidgetProvider 类作为一个方便的类来处理应用程序构件广播扩展应用。AppWidgetProvider 接收相关的应用程序部件,例如当应用程序部件是更新、 删除、 启用,和禁用的事件广播。这些广播的事件发生时,AppWidgetProvider 会收到下面的方法调用︰onUpdate()、onAppWidgetOptionsChanged()、onDeleted(Context, int[])、onEnabled(Context)、onDisabled(Context)、onReceive(Context, Intent)

最重要的 AppWidgetProvider 回调是 onUpdate(),因为它所谓每个应用程序插件添加到主界面(除非你使用一个配置活动) 时。如果您的应用程序小部件接受任何用户交互事件,那么您需要在此回调中注册事件处理程序。如果您的应用程序小部件不会创建临时文件或数据库,或者执行其他工作,需要清理,那么 onUpdate() 可能是唯一你需要定义的回调方法。例如,如果您希望应用程序构件能够启动Activity,你可以使用 AppWidgetProvider 下面的实现︰

public class ExampleAppWidgetProvider extends AppWidgetProvider {
    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
        final int N = appWidgetIds.length;
        // Perform this loop procedure for each App Widget that belongs to this provider
        for (int i=0; i<N; i++) {
            int appWidgetId = appWidgetIds[i];
            // Create an Intent to launch ExampleActivity
            Intent intent = new Intent(context, ExampleActivity.class);
            PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
            // Get the layout for the App Widget and attach an on-click listener
            // to the button
            RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.appwidget_provider_layout);
            views.setOnClickPendingIntent(R.id.button, pendingIntent);
            // Tell the AppWidgetManager to perform an update on the current app widget
            appWidgetManager.updateAppWidget(appWidgetId, views);
        }
    }
}

创建App Widget Configuration Activity 如果你想用户配置设置,当他或她将添加一个新的应用程序部件时,你可以创建应用程序构件配置活动。本次活动由应用程序构件主机也会自动启动,并允许用户配置应用程序构件可用设置在创建时,例如应用程序构件颜色、 大小、 更新期间或其他功能设置。

活动应声明为 Android 清单中的正常活动的配置文件。然而,它将推出由应用程序构件主机与 ACTION_APPWIDGET_CONFIGURE 操作,因此该活动需要接受这种意图。例如︰

<activity android:name=".ExampleAppWidgetConfigure">
    <intent-filter>
        <action android:name="android.appwidget.action.APPWIDGET_CONFIGURE"/>
    </intent-filter>
</activity>

创建应用程序窗口小部件时,不会调用 onUpdate() 方法 (系统将不发送广播时活动启动配置的 ACTION_APPWIDGET_UPDATE)。它是配置活动首次创建应用程序窗口小部件时,从 AppWidgetManager 请求更新的责任。然而,onUpdate() 将呼吁后续更新 — — 它只跳过第一次。

Intent intent = getIntent();
Bundle extras = intent.getExtras();
if (extras != null) {
    mAppWidgetId = extras.getInt(
            AppWidgetManager.EXTRA_APPWIDGET_ID, 
            AppWidgetManager.INVALID_APPWIDGET_ID);
}

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);

RemoteViews views = new RemoteViews(context.getPackageName(),
R.layout.example_appwidget);
appWidgetManager.updateAppWidget(mAppWidgetId, views);

Intent resultValue = new Intent();
resultValue.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, mAppWidgetId);
setResult(RESULT_OK, resultValue);
finish();

构建还有列表的应用构件 加入列表控件

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">
    <StackView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/stack_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:loopViews="true" />
    <TextView xmlns:android="http://schemas.android.com/apk/res/android"
        android:id="@+id/empty_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:gravity="center"
        android:background="@drawable/widget_item_background"
        android:textColor="#ffffff"
        android:textStyle="bold"
        android:text="@string/empty_view_text"
        android:textSize="20sp" />
</FrameLayout>

列表设置remoteAdapter

public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {
    // update each of the app widgets with the remote adapter
    for (int i = 0; i < appWidgetIds.length; ++i) {
        
        // Set up the intent that starts the StackViewService, which will
        // provide the views for this collection.
        Intent intent = new Intent(context, StackWidgetService.class);
        // Add the app widget ID to the intent extras.
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetIds[i]);
        intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
        // Instantiate the RemoteViews object for the app widget layout.
        RemoteViews rv = new RemoteViews(context.getPackageName(), R.layout.widget_layout);
        // Set up the RemoteViews object to use a RemoteViews adapter. 
        // This adapter connects
        // to a RemoteViewsService  through the specified intent.
        // This is how you populate the data.
        rv.setRemoteAdapter(appWidgetIds[i], R.id.stack_view, intent);
        
        // The empty view is displayed when the collection has no items. 
        // It should be in the same layout used to instantiate the RemoteViews
        // object above.
        rv.setEmptyView(R.id.stack_view, R.id.empty_view);
        //
        // Do additional processing specific to this app widget...
        //
        
        appWidgetManager.updateAppWidget(appWidgetIds[i], rv);   
    }
    super.onUpdate(context, appWidgetManager, appWidgetIds);
}

列表创建RemoteView

<service android:name="StackWidgetService"
...
android:permission="android.permission.BIND_REMOTEVIEWS" />
public class StackWidgetService extends RemoteViewsService {
    @Override
    public RemoteViewsFactory onGetViewFactory(Intent intent) {
        return new StackRemoteViewsFactory(this.getApplicationContext(), intent);
    }
}
class StackRemoteViewsFactory implements RemoteViewsService.RemoteViewsFactory {
    private static final int mCount = 10;
    private List<WidgetItem> mWidgetItems = new ArrayList<WidgetItem>();
    private Context mContext;
    private int mAppWidgetId;
    public StackRemoteViewsFactory(Context context, Intent intent) {
        mContext = context;
        mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID,
                AppWidgetManager.INVALID_APPWIDGET_ID);
    }
    // Initialize the data set.
        public void onCreate() {
            // In onCreate() you set up any connections / cursors to your data source. Heavy lifting,
            // for example downloading or creating content etc, should be deferred to onDataSetChanged()
            // or getViewAt(). Taking more than 20 seconds in this call will result in an ANR.
            for (int i = 0; i < mCount; i++) {
                mWidgetItems.add(new WidgetItem(i + "!"));
            }
           ...
        }
        ...
    
        // Given the position (index) of a WidgetItem in the array, use the item's text value in 
        // combination with the app widget item XML file to construct a RemoteViews object.
        public RemoteViews getViewAt(int position) {
            // position will always range from 0 to getCount() - 1.
    
            // Construct a RemoteViews item based on the app widget item XML file, and set the
            // text based on the position.
            RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_item);
            rv.setTextViewText(R.id.widget_item, mWidgetItems.get(position).text);
    
            // Next, set a fill-intent, which will be used to fill in the pending intent template
            // that is set on the collection view in StackWidgetProvider.
            Bundle extras = new Bundle();
            extras.putInt(StackWidgetProvider.EXTRA_ITEM, position);
            Intent fillInIntent = new Intent();
            fillInIntent.putExtras(extras);
            // Make it possible to distinguish the individual on-click
            // action of a given item
            rv.setOnClickFillInIntent(R.id.widget_item, fillInIntent);
        
            ...
        
            // Return the RemoteViews object.
            return rv;
        }
    ...
    }

© 著作权归作者所有

1071954237
粉丝 3
博文 97
码字总数 36187
作品 0
程序员
私信 提问
浅谈如何给 appwidget 添加复杂 view

我们都知道android原生的widget只支持极少数几个简单的view,所以功能及其简单。很多人都希望在AppWidget添加ListView、GridView等复杂的view来实现更为复杂的功能。我们知道要在AppWidget里...

鉴客
2011/09/25
4.8K
0
Android --- App Widget 开发

概要: App Widget应用小控件,用户可以通过长按屏幕,然后添加小控件倒桌面,这些小控件一般都是为了显示一些信息在桌面上,同时方便用户通过点击桌面上的小控件来访问你的程序。 基础知识:...

Jumper_Woo
2013/04/06
756
0
Android开发指南-窗口小部件(App Widgets)

http://blog.csdn.net/iefreer/article/details/4626274# 应用程序窗口小部件App Widgets 应用程序窗口小部件(Widget)是微小的应用程序视图,可以被嵌入到其它应用程序中(比如桌面)并接收...

鲜鲜
2014/09/16
433
0
android之appwidget(一)简单appwidget

什么是appwidget? 即application widget。 应用程序控件,就是在桌面显示的控件。AppWidget就是我们平常在桌面上见到的那种一个个的小控件,利用这个小控件可以给用户提供一些方便快捷的操作...

守夜之星
2012/08/10
390
0
android.appwidget类解析

随着Android 1.5的普及很多网友发现SDK中多出了appwidget这个框架。作为使用Java语言设计的Widget相比目前主流的W3C Widget有更好的运行效率和底层控制能力,今天我们就Android平台上的Widge...

华宰
2011/09/15
748
0

没有更多内容

加载失败,请刷新页面

加载更多

OSChina 周一乱弹 —— 人生,还真是到处是意外

Osc乱弹歌单(2019)请戳(这里) 【今日歌曲】 @这次装个文艺青年吧 :#今日歌曲推荐# 分享lil peep的单曲《High School》 《High School》- lil peep 手机党少年们想听歌,请使劲儿戳(这里...

小小编辑
16分钟前
1
0
Spring使用ThreadPoolTaskExecutor自定义线程池及实现异步调用

多线程一直是工作或面试过程中的高频知识点,今天给大家分享一下使用 ThreadPoolTaskExecutor 来自定义线程池和实现异步调用多线程。 一、ThreadPoolTaskExecutor 本文采用 Executors 的工厂...

CREATE_17
今天
6
0
CSS盒子模型

CSS盒子模型 组成: content --> padding --> border --> margin 像现实生活中的快递: 物品 --> 填充物 --> 包装盒 --> 盒子与盒子之间的间距 content :width、height组成的 内容区域 padd......

studywin
今天
7
0
修复Win10下开始菜单、设置等系统软件无法打开的问题

因为各种各样的原因导致系统文件丢失、损坏、被修改,而造成win10的开始菜单、设置等系统软件无法打开的情况,可以尝试如下方法解决 此方法只在部分情况下有效,但值得一试 用Windows键+R打开...

locbytes
昨天
8
0
jquery 添加和删除节点

本文转载于:专业的前端网站➺jquery 添加和删除节点 // 增加一个三和一节点function addPanel() { // var newPanel = $('.my-panel').clone(true) var newPanel = $(".triple-panel-con......

前端老手
昨天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部