日本熟妇hd丰满老熟妇,中文字幕一区二区三区在线不卡 ,亚洲成片在线观看,免费女同在线一区二区

小組件開發(fā)最佳實踐(Android)

應用程序小組件是一個微型的應用程序視圖,可以嵌入其他應用程序(例如主屏幕)中并接收定期更新。本文檔介紹了如何使用App Widget provider發(fā)布Android小組件。

概述

應用程序視圖在用戶界面中稱為組件(Widget),您可以使用小組件提供程序(App Widget provider)發(fā)布這些視圖。能夠容納其他小組件的應用程序組件稱為App Widget宿主(如Launcher),下圖為時鐘和天氣的小組件示例,更多有關小組件設計規(guī)范的內容,請參見 App Widgets Overview

小組件示例

為了創(chuàng)建小組件,您還需要先了解以下信息。

  • AppWidgetProviderInfo

    描述應用程序小組件的元數(shù)據(jù),例如小組件的布局、更新頻率、指定AppWidgetProvider類等。

  • AppWidgetProvider

    用來處理小組件的廣播事件,當更新、啟用、禁用、刪除小組件時,您可以收到廣播。

  • View layout

    以XML定義的小組件的初始布局

  • 其他

    還可以為您的小組件配置活動。啟動活動后,允許用戶在該活動里修改小組件設置。

創(chuàng)建小組件

  1. 在應用程序的清單文件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>

    代碼配置說明如下。

    • receiver元素需要設置android:name屬性,該屬性指定App Widget使用的是AppWidgetProvider類。

    • intent-filter元素必須包含具有android:name屬性的action元素。此屬性指定AppWidgetProvider類接受的廣播類型為ACTION_APPWIDGET_UPDATE(這是您須明確聲明的唯一廣播)。AppWidgetManager根據(jù)用戶需要,自動將所有其他App Widget廣播發(fā)送到AppWidgetProvider。

    • meta-data元素指定AppWidgetProviderInfo資源,并需要設置以下屬性。

      • android:name指定元數(shù)據(jù)名稱,使用android.appwidget.provider將數(shù)據(jù)標識為AppWidgetProviderInfo描述符。

      • android:resource 指定AppWidgetProviderInfo的資源位置。

  2. 添加AppWidgetProviderInfo元數(shù)據(jù)。

    AppWidgetProviderInfo定義了小組件的基本配置(例如最小布局尺寸、初始布局資源、更新頻率、(可選)在創(chuàng)建時啟動的配置Activity等)。使用單個元素在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>

    代碼配置說明如下。

    • minWidthminHeight屬性指定默認情況下App Widget占用的最小尺寸(為了使您App的小組件適配多種屏幕,此處的最小尺寸不得大于4 x 4單元)。更多信息請參見應用程序小組件設計指南

    • updatePeriodMillis屬性定義App Widget框架通過調用onUpdate()回調方法從AppWidgetProvider請求更新的頻率。使用該值不能保證實際的更新會準時進行,我們不建議頻繁地更新(每小時不超過一次),以便節(jié)省電池電量。

    • initialLayout屬性指向定義App Widget布局的布局資源。

    • configure屬性(可選屬性)定義了用戶添加App Widget時要啟動的活動,以便配置App Widget屬性。

    • previewImage屬性指定配置后的應用小組件的預覽,用戶在選擇應用小組件時可見。如果未提供,用戶看到的為您應用程序的啟動器圖標。

    • resizeMode屬性指定可以調整窗口小組件大小的規(guī)則,例如水平、垂直或雙向調整大小等。

    • minResizeHeightminResizeWidth屬性指定窗口小組件可以調整大小的最小高度與最小寬度(單位為dp)。

    說明

    更多元素屬性的介紹請參見AppWidgetProviderInfo

  3. 創(chuàng)建小組件布局。

    使用XML為您的小組件定義初始布局,并將其保存在工程的res/layout目錄中。

    小組件布局基于RemoteViews,一個RemoteViews對象(通常就是一個小組件)可以支持以下布局類和視圖組件。

    • 布局類

      • FrameLayout

      • LinearLayout

      • RelativeLayout

      • GridLayout

      說明

      僅支持這些類,不支持這些類的子類。

    • 視圖組件

      • AnalogClock

      • Button

      • Chronometer

      • ImageButton

      • ImageView

      • ProgressBar

      • TextView

      • ViewFlipper

      • ListView

      • GridView

      • StackView

      • AdapterViewFlipper

    • 其他

      RemoteViews還支持ViewStub,這是一個不可見的零尺寸視圖,可用于在運行時延遲布局資源的渲染。

    下面以設計布局類FrameLayout為例介紹,更多信息請參見App Widget設計指南

    1. 進入res/layout/目錄,創(chuàng)建一個xml的布局文件(例如:appwidget_provider_layout.xml)。

    2. 添加布局類FrameLayout,相關代碼如下。

      <?xml version="1.0" encoding="utf-8"?>
      <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
          xmlns:tools="http://schemas.android.com/tools"
          android:layout_width="match_parent"
          android:layout_height="match_parent">
      
          <Button
              android:id="@+id/button"
              android:layout_width="wrap_content"
              android:layout_height="wrap_content"
              android:text="OK"
              tools:ignore="HardcodedText" />
      </FrameLayout>
  4. 添加小組件之間的距離。

    為了更好地提升用戶體驗,從Android 4.0及以上版本,系統(tǒng)會自動在小組件框架和應用小組件的邊界框之間提供填充。Android 4.0以下則需要開發(fā)者自行設置(由于目前市場上Android 4.0以下機型較少,此處不作介紹,可自行查找資料)。

  5. 創(chuàng)建AppWidgetProvider類。

    最后您還需要創(chuàng)建在清單中聲明的ExampleAppWidgetProvider類。例如,如果您想要一個用于單擊的按鈕小組件,使用AppWidgetProvider實現(xiàn)的示例代碼如下。

    /*
     * Copyright (C) 2008 The Android Open Source Project
     *
     * 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.
     */
    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);
                Intent intent = new Intent();
                PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
    
                // Get the layout for the App Widget and attach an on-click listener
                // to the button,其中appwidget_provider_layout為創(chuàng)建的xml布局文件名稱
                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);
            }
        }
    }

    代碼配置說明如下。

    此AppWidgetProvider僅定義onUpdate()方法,并定義啟動活動的PendingIntent,使用setOnClickPendingIntent(int,PendingIntent)將其添加到小組件的按鈕上。

    關于AppWidgetProvider的使用說明如下。

    • AppWidgetProvider類是BroadcastReceiver 的擴展,用來處理小組件的廣播。 AppWidgetProvider僅接收與小組件相關的事件廣播,例如何時更新,刪除,啟用和禁用小組件。當發(fā)生這些廣播事件時,AppWidgetProvider會收到以下方法調用:

    • AppWidgetProvider回調通過onUpdate()方法。如果您的小組件需要接受用戶的交互事件(此時您需要在此回調中注冊事件處理程序),并且您的小組件不需要創(chuàng)建臨時文件或數(shù)據(jù)庫,也不需要執(zhí)行其他清理的工作時,您無需關心除onUpdate()以外的生命周期回調。

      說明

      由于AppWidgetProvider是BroadcastReceiver的子類,因此不能保證您的進程在回調方法返回后仍能繼續(xù)運行(有關廣播生命周期的信息,請參見BroadcastReceiver)。如果您的小組件設置過程需要花費幾秒鐘的時間(可能是在執(zhí)行Web請求時),并且您要求設置過程繼續(xù)進行,請使用onUpdate()方法,通過在方法中啟動服務來處理耗時操作。您可以從服務內部對小組件執(zhí)行自己的更新,從而不必擔心AppWidgetProvider會由于Application Not Responding(ANR)而關閉。

請求接口

小組件開發(fā)過程中常用到的請求接口如下。

  • 獲取設備列表(已添加到小組件)

    path:/iotx/ilop/queryComponentProduct
    version:1.0.0
    params:@{}
  • 獲取設備屬性

    path:/iotx/ilop/queryComponentProperty
    version:1.0.0
    params = @{@"productKey":productKey,@"iotId":iotId,@"query":@{@"dataType":@"BOOL”, @"I18Language":@"zh-CN"}}
  • 更新設備屬性

     path:/iotx/ilop/updateComponentProduct
    version:1.0.0
    params:更改后的設備list
  • 獲取場景列表(已添加到小組件)

    path:/living/appwidget/list
    version:1.0.0
    params:@{}
  • 執(zhí)行場景

    path:/scene/fire
    version:1.0.1
    params:@{@"sceneId":sceneId}
  • 更新小組件場景

    path:/living/appwidget/create
    version:1.0.0
    params = @{@"sceneIds": @[]}

更多關于接口的說明請參見場景服務物的模型服務

監(jiān)聽設備屬性更新

如果您需要開發(fā)控制設備的小組件,通過小組件實現(xiàn)手機對設備的查看和控制。那么您還需要了解App端物模型(屬性、事件、服務)相關的知識點。下面以如何用物模型SDK監(jiān)聽設備屬性變更事件為例,提供相關的代碼示例供您參考。

下面以使用物模型SDK監(jiān)聽設備屬性變更事件為例,提供相關的代碼示例供您參考。更多內容請參見物模型SDK

PanelDevice panelDevice = new PanelDevice(iotId);
panelDevice.subAllEvents(new IPanelEventCallback() {
    @Override
    public void onNotify(String s, String s1, Object o) {
        Log.d(TAG, "onNotify: " + s);
        Log.d(TAG, "onNotify: " + s1);
        Log.d(TAG, "onNotify: " + JSON.toJSONString(o));
        // 更新界面
    }
}, new IPanelCallback() {
    @Override
    public void onComplete(boolean b, Object o) {
        /* */
    }
});
panelDevice.init(this, new IPanelCallback() {
    @Override
    public void onComplete(boolean b, Object o) {
        Log.e(TAG, "panelDevice.init:" + b);
    }
});