Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android系統教程 >> 安卓省電與加速 >> Android N 多窗口布局 省電模式 全新通知功能

Android N 多窗口布局 省電模式 全新通知功能

編輯:安卓省電與加速

今年google 16 i/o 強勢推出 android n
迄今為止還沒有給他命名、有興趣的可以登錄網站 https://www.android.com/versions/name-n/
會中提到android N 運行環境有很大提升,30%到600%提升。應用安裝提速75%。
AndroidN 新增Vulkan 現代3D圖形API、實現高幀率游戲,即時應用

OK、好東西用了才知道、那麼如何運行Android N呢

會學到什麼

多窗口布局互動
確保後台服務繼續工作,而打盹模式激活
更新通知,以利用新功能

需要什麼

Android的工作室版本2.1+
示例代碼
測試設備(或仿真器)與Android N和谷歌的API
使用USB線連接你的測試設備

獲取示例代碼

通過命令行從github上clone

$ git clone https://github.com/googlecodelabs/getting-ready-for-android-n

因為該實例需要使用OpenWeatherMap 獲取天氣數據、多以在運行代碼之前要獲取OpenWeatherMap API密鑰 獲取鏈接 https://home.openweathermap.org/

運行示例應用程序

OK 打開你下載好的項目、
重要提醒:將你的 OpenWeatherMap API key 添加到 app/build.gradle
Important: Add your OpenWeatherMap API key to app/build.gradle,
將這行代碼替換 .
運行程序、驗證示例程序可以顯示天氣

支持多窗口布局

個人覺得最酷炫的是支持multi-window layouts

支持多窗口首先確保我們布局放得下大小windows。首先熟悉幾個功能

默認情況下,所有application和activity有個resizeable屬性可以用作multi-window功能、
在清單中可以禁用這個功能

        

        

嘗試一下這兩個模式

啟動 sunshine app 通過長按按鈕啟動multi-windows 模式禁用multi-windows app是全屏的將resizeable 置為 true 再試試

注意:如果root activity resizeble是false、則不起作用
A task’s root activity properties are applied to all additional activities launched in the task.
If the root activity of a task is resizeable, the system treats all other activities in the task as resizeable; if the root activity isn’t resizeable, it won’t.
這裡寫圖片描述

適配小窗口
支持 multi-windows 得考慮 size 和 density的問題
在實例中、用了很多pixel顯示天氣
這裡寫圖片描述

如果想把左邊藍色縮小、我們可以用下面的方法

在 values-sw220dp 創建refs.xml、這樣尺寸就限制在220dp到下一維度400dp
sw220dp/refs.xml<喎?/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxwcmUgY2xhc3M9"brush:java;"> @layout/list_item_forecast

sw400dp/refs.xml

@layout/list_item_forecast_today_big

這樣list_item_forecast_today 就適應了兩個布局

這裡寫圖片描述

總結:
適應不同大小的應用程序多畫面模式,建議先設計最小的大小。
創建220dp 盡量刪除無用元素

添加窗口背景
這裡寫圖片描述

添加android:windowBackgroundFallback會覆蓋 windowBackground

打開ForecastFragment .class openPreferredLocationInMap 方法
添加

Intent intent = new Intent(Intent.ACTION_VIEW);
intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCH_ADJACENT);

效果如下
這裡寫圖片描述
注意:FLAG_ACTIVITY_LAUNCH_ADJACENT只適用於多畫面模式。

優化電池效率

現在的android手機、有時候充的電還沒用的快…蛋疼 現在優化會好些嗎?
在Android N,我們繼續這些努力讓android 6打瞌睡功能更牛逼,讓設備更能保存點亮。任何時候屏幕在一段時間內,設備是不插電,瞌睡適用於CPU和網絡限制應用程序。即使在自己的口袋裡攜帶他們的設備也能省點。
輕量級打瞌睡模式
這裡寫圖片描述

靜止的:
這裡寫圖片描述

那麼有了這些功能、app功能會受到限制、特別是網絡活動
為了確保您的應用程序在後台繼續正常運行,一些服務可能需要修改

(如檢查電子郵件,或備份照片),遷移到theJobScheduler或GcmNetworkManager api。這些api提供更大的靈活性為調度工作,並確保你的工作是維護窗口期間處理。實時通知(如接收即時消息),使用高優先級GCM通知。這些有能力立即醒來一個應用的低功耗狀態。

我們的樣例應用程序使用AlarmManger定期醒來和獲取天氣數據,同時在後台運行。在本節中,我們將它升級到使用GcmNetworkManager。我們的應用程序中醒來的時候允許操作系統更好的去控制,並確保我們的應用程序在這個網絡訪問事件。

在SunshineSyncService.java定位現有alarm-based調度代碼:

public static void ScheduleAlarm(Context context) {
    Log.i(TAG, "Scheduling alarm, interval: " + AlarmManager.INTERVAL_HALF_HOUR / 60000 + " min");
    Intent intent = new Intent(context, SyncAlarmReceiver.class);
    final PendingIntent pIntent = PendingIntent.getBroadcast(
            context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    long firstMillis = System.currentTimeMillis(); // Perform initial sync immediately
    AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    // Perform subsequent syncs every 30 minutes
    alarm.setInexactRepeating(AlarmManager.RTC_WAKEUP, firstMillis,
            AlarmManager.INTERVAL_HALF_HOUR, pIntent);
}

public static class SyncAlarmReceiver extends BroadcastReceiver {
    private static final String TAG = "SyncAlarmReceiver";

    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "Broadcast received, sending sync intent to SunshineSyncService");
        Intent i = new Intent(context, SunshineSyncService.class);
        context.startService(i);
    }
}

基於GcmNetworkManager替換上面的代碼

dependencies {
    // ...
    compile 'com.google.android.gms:play-services-gcm:8.4.0'
}

封裝一個後台任務
sync/SunshineJobScheduler.java

public class SunshineJobScheduler extends GcmTaskService {

    @Override
    public int onRunTask(TaskParams taskParams) {
        return 0;
    }

}
如前所述,GcmNetworkManager和JobScheduler工作通過定義任務或工作,和一組約束決定當他們應該運行。讓我們為這個任務定義兩個約束條件——一個經常運行的同時連接到一個充電器,和一個不經常運行在電池。

sync/SunshineJobScheduler.java

public static final int MINUTES_AS_SEC = 60;
public static final int HOURS_AS_SEC = 60*60;
public static final String TASK_TAG_CHARGING = "sync_charging";
public static final String TASK_TAG_BATTERY = "sync_battery";

/**
 * Task specification for running jobs while connected to a charger. In this case, we allow
 * execution to occur frequently, as power usage is not constrained.
 */
private static final Task CHARGING_TASK = new PeriodicTask.Builder()
        .setService(SunshineJobScheduler.class)
        .setPeriod(30*MINUTES_AS_SEC)
        .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
        .setRequiresCharging(true)
        .setPersisted(true)
        .setUpdateCurrent(true)
        .setTag(TASK_TAG_CHARGING)
        .build();

/**
 * Task specification for running jobs while on battery. In this case, we execute jobs less
 * frequently to conserve battery life.
 *
 * Note that additional restrictions may be put on this task by the system if the device is
 * in Doze or App Standby mode due to inactivity. However, we should still try to be friendly
 * to the battery even when these aren't in effect.
 */
private static final Task BATTERY_TASK = new PeriodicTask.Builder()
        .setService(SunshineJobScheduler.class)
        .setPeriod(6 * HOURS_AS_SEC)
        .setRequiredNetwork(Task.NETWORK_STATE_CONNECTED)
        .setRequiresCharging(false)
        .setPersisted(true)
        .setUpdateCurrent(true)
        .setTag(TASK_TAG_BATTERY)
        .build();

setPersisted(true)調用確保跨設備重新啟動該任務將被保留下來

現在我們已經定義了任務,我們需要系統安排他們。創建一個新的ScheduleTasks()靜態方法,並調用GcmNetworkManager.schedule()我們定義的每個任務。

sync/SunshineJobScheduler.java

private static final String TAG = "SunshineJobScheduler";

/**
 * Method to schedule tasks. Called from either MainActivity.onCreate() for interactive
 * sessions, or onInitializeTasks() in the event Play Services is restarted.
 *
 * Note that since all jobs are flagged as "persisted" in their specifications (above), these
 * will automatically persist across reboots.
 *
 * @param context
 */
public static void ScheduleTasks(Context context) {
    GoogleApiAvailability googleAvailability = GoogleApiAvailability.getInstance();
    int resultCode = googleAvailability.isGooglePlayServicesAvailable(context);
    if (resultCode == ConnectionResult.SUCCESS) {
        Log.i(TAG, "Scheduling tasks");
        GcmNetworkManager gcmNetworkManager = GcmNetworkManager.getInstance(context);

        // Run every 30 minutes while the device is on a charger
        gcmNetworkManager.schedule(CHARGING_TASK);

        // ... And run every 6 hours while the device is on battery power
        gcmNetworkManager.schedule(BATTERY_TASK);
    } else {
        // We display a user actionable error inside MainActivity. We'll just abort and log the
        // error here.
        Log.e(TAG, "Google Play Services is not available, unable to schedule jobs");
    }
}

配置manifest
ACTION_TASK_READY,為了讓持久化設備重啟後任務被重塑。



    
        
    

我們的GcmNetworkManager實現相應的工作工作,我們可以刪除舊的實現。
刪除SunshineSyncService。SyncAlarmReceiver SunshineSyncService。BootBroadcastReceiver以及他們在AndroidManfiest.xml相關條目。
測試,嘗試啟動應用程序。你可能想嘗試不同的值用於setPeriod CHARGING_TASK()和BATTERY_TASK。如果使用一個模擬器,可以使用模擬器控制來模擬不同的充電和網絡狀態。

Q: What’s the difference between JobScheduler and GcmNetworKManager?
A: GcmNetworkManager is a wrapper around JobScheduler, that provides backwards compatibility for devices older than API 21. Your app doesn’t need to use GCM messaging in order to take advantage of it.
Q: How do I ensure my jobs are scheduled after a restart?
A: Use the setPersisted() option when creating a task specification.
Q: What happens if I don’t migrate to JobScheduler or GcmNetworkManager?
A: On devices running Marshmallow or later, your app may lose network access if Doze or App Standby modes are activated by the system. To avoid this, you need to make sure your app’s background activities only occur during maintenance windows. To do this, make sure you’re using JobScheduler/GcmNetworkManager (recommended) or a SyncAdapter.

支持增強的通知

Android N notifications 有一下幾點
1. 列表內容通知分組在phones和tablets使用、不僅僅 android wear
2. 通知可以響應文本輸入
3. 刷新和操作更美了

這裡寫圖片描述

NotificationCompat Android支持庫引入N,我們可以通過分組通知達到更好的用戶體驗

下面是notification group部分

使用一個支持庫版本大於24.0.0-alpha2

compile 'com.android.support:appcompat-v7:21.0.2'
compile 'com.android.support:appcompat-v7:24.0.0-alpha2'

打開SunshineSyncEngine.java
SunshineSyncEngine.java
添加如下代碼

private static final String FORECAST_NOTIFICATION_GROUP = "FORECAST_NOTIFICATION_GROUP";

new NotificationCompat.Builder
Builder調用setGroup(String)
SunshineSyncEngine.java

.setGroup(FORECAST_NOTIFICATION_GROUP)

所有通知組需要一個summary.創建額外的summary通知代碼
SunshineSyncEngine.java

if (numNotifications > 0) {
    // Always build a summary if you have notifications in a group.
    // The summary will be displayed by the system when needed.
    NotificationCompat.Builder summaryBuilder =
        createSummaryNotificationBuilder(context,
            "Sunshine Forecasts", "");
    summaryBuilder.setGroupSummary(true);
    mNotificationManager.notify(WEATHER_NOTIFICATION_ID,  
        summaryBuilder.build());
}

部署代碼,將看到在系統欄通知分組只占用一個圖標。單摘要通知是可擴展的,group內部數量低於2摘要通知消失

下面是關於Remote Input部分

通知欄輸入文字、要做一下幾個個步驟
1. 您需要聲明一個類,它將接收一個意圖。目的將包含的信息由用戶輸入的文本。在這個示例中我們要重復使用BroadcastReceiver。
2. MessageReplyReceiver類,您將看到以下意圖額外的定義。將存儲的回復文本意圖轉發給接收方是關鍵。
MessageReplyReceiver.java

    public static final String EXTRA_REMOTE_REPLY = "extra_remote_reply";
    // public static final String REPLY_ACTION = BuildConfig.APPLICATION_ID + ".ACTION_MESSAGE_REPLY";
    // public static final String EXTRA_FORECAST = "extra_forecast";

取消REPLY_ACTION和EXTRA_FORECAST靜態類變量的備注
REPLY_ACTION和EXTRA_FORECAST靜態類變量。REPLY_ACTION將用於聲明RemoteInput行動的通知。EXTRA_FORECAST包含預測信息,需要重建的通知。

將MessageReplyReceiver onReceive方法中的代碼解除注釋、
將檢索一個接收器可以處理的意圖。
SunshineSyncEngine.java

RemoteInput remoteInput = new RemoteInput.Builder(
                             MessageReplyReceiver.EXTRA_REMOTE_REPLY)
                             .setLabel("Take note")
                             .build();

5.創建一個Pending intent通知用戶提交的回復
SunshineSyncEngine.java

RemoteInput remoteInput = new RemoteInput.Builder(
                             MessageReplyReceiver.EXTRA_REMOTE_REPLY)
                             .setLabel("Take note")
                             .build();
創建action
SunshineSyncEngine.java
NotificationCompat.Action actionReplyByRemoteInput =
    new NotificationCompat.Action.Builder(
        R.mipmap.ic_launcher,
        "Take note",
        replyIntent)
        .addRemoteInput(remoteInput)
        .build();

7.現在添加遠程輸入行動通知。
SunshineSyncEngine.java

builder.addAction(actionReplyByRemoteInput);

部署應用程序、發送文本發現進度指示器沒有提醒、因為我們差了一步驟
onReceive消息中你會注意到NotificationManager變量不能使用。除非你通知用戶使用否則該系統將不知道遠程接收輸入
MesageReplyReceiver.java

NotificationManager notificationManager =
    (NotificationManager) context.getSystemService(
         Context.NOTIFICATION_SERVICE);
NotificationCompat.Builder notificationBuilder =
    SunshineSyncEngine.createForecastNotificationBuilder(
        context, forecast);
notificationManager.notify(forecast.mDaysSinceEpoch,
    notificationBuilder.build());

提示:NotificationCompat.Builder創建對象是昂貴的。如果你打算經常更新相同的通知需要創建和緩存它們。這將避免不必要的對象創建請求。

這裡寫圖片描述

OK、這些功能慢慢體驗吧、你的應用已經運行android n新功能了

互動的多窗口布局確保後台服務繼續工作,打瞌睡模式處於活動狀態利用新功能更新通知

google原文地址、注意帶上梯子
https://codelabs.developers.google.com/codelabs/getting-ready-for-android-n/index.html?index=..%2F..%2Fio2016

   
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved