Android創建桌面快捷方式(兼容Android 8.0)

在Android O原生桌面上,按照傳統創建快捷方式的形式,是不會產生快捷方式的。

傳統方式如下:

public static final String ACTION_ADD_SHORTCUT = "com.android.launcher.action.INSTALL_SHORTCUT";

public void addShortcutBelowAndroidN(Context context) {
    Intent addShortcutIntent = new Intent(ACTION_ADD_SHORTCUT);

    // 不允許重復創建,不是根據快捷方式的名字判斷重復的
    addShortcutIntent.putExtra("duplicate", false);

    addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Shortcut Name");

    //圖標
    addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.mipmap.ic_shortcut));

    // 設置關聯程序
    Intent launcherIntent = new Intent();
    launcherIntent.setClass(context, ShortcutActivity.class);
    addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);

    // 發送廣播
    context.sendBroadcast(addShortcutIntent);
}

ShortCutManager

從Android 7.1(API 25)開始,新增了ShortcutManager,可以對桌面久按應用圖標彈出的快捷方式進行管理。

但是,Android 7.1上直接往桌面上添加快捷方式依然是使用上面說到的這種舊方式,但是Android O上,Google應該是想通過比較統一的接口來管理桌面快捷方式了,所以摒棄了這種形式,轉而使用ShortcutManager進行管理。所以API 26上,ShortcutManager進行管理。所以API 26上,ShortcutManager新增了對Pinned Shortcuts(固定快捷方式)的管理。

官文:
Apps can pin an existing shortcut (either static or dynamic) or an entirely new shortcut to a supported launcher programatically using requestPinShortcut(ShortcutInfo, IntentSender). You pass two arguments into this method:

A ShortcutInfo object – If the shortcut already exists, this object should contain only the shortcut’s ID. Otherwise, the new ShortcutInfo object must contain an ID, an intent, and a short label for the new shortcut.
A PendingIntent object – This intent represents the callback that your app receives if the shortcut is successfully pinned to the device’s launcher.

Note: If the user doesn’t allow the shortcut to be pinned to the launcher, the pinning process fails, and the Intent object that is passed into this PendingIntent object isn’t executed.

Note: Due to background execution limits introduced in Android O, it’s best to use a manifest-declared receiver to receive a callback.
Also, to prevent other apps from invoking the receiver, add the attribute assignment android:exported=”false” to the receiver’s manifest entry.

Note: As you add logic in your app to make requests to pin shortcuts, keep in mind that not all launchers support pinning of shortcuts. To determine whether your app can complete this process on a particular device, check the return value of isRequestPinShortcutSupported(). Based on this return value, you might decide to hide the option in your app that allows users to pin a shortcut.

Note: See also the support library APIs isRequestPinShortcutSupported(Context) and requestPinShortcut(Context, ShortcutInfoCompat, IntentSender), which works on Android versions lower than O by falling back to the deprecated private intent com.android.launcher.action.INSTALL_SHORTCUT.

譯:
應用程序可以使用requestPinShortcut(ShortcutInfo,IntentSender)將現有的快捷方式(靜態或動態)或全新的快捷方式固定到支持的啟動器。你通過這個方法的兩個參數:

ShortcutInfo對象 - 如果快捷方式已存在,則該對象應僅包含快捷方式的ID。否則,新的ShortcutInfo對象必須包含新快捷方式的ID,意圖和短標簽。
PendingIntent對象 - 此意圖表示如果快捷方式成功固定到設備的啟動器,您的應用程序將收到回調。

注意:如果用戶不允許將快捷方式固定在啟動器上,則固定進程將失敗,并且未執行傳入此PendingIntent對象的Intent對象。

注意:由于Android O中引入的后臺執行限制,最好使用清單聲明的接收器來接收回調。
另外,為了防止其他應用程序調用接收器,將屬性賦值android:exported =“false”添加到接收者的清單條目中。

注意:當您在應用程序中添加邏輯以引導快捷方式時,請記住,并非所有啟動器都支持固定快捷方式。 要確定您的應用程序是否可以在特定設備上完成此過程,請檢查isRequestPinShortcutSupported()的返回值。 根據此返回值,您可以決定隱藏您應用程序中允許用戶固定快捷方式的選項。

注意:另請參見支持庫API isRequestPinShortcutSupported(Context)和requestPinShortcut(Context,ShortcutInfoCompat,IntentSender),它可以在低于O的Android版本上運行,因為它們回落到不推薦使用的私有意圖com.android.launcher.action.INSTALL_SHORTCUT。

ShortcutManager類在API level 26上,增加了對isRequestPinShortcutSupported、requestPinShortcut、createShortcutResultIntent三個方法。說明如下:

1.isRequestPinShortcutSupported

官文:
Return TRUE if the app is running on a device whose default launcher supports requestPinShortcut(ShortcutInfo, IntentSender).

The return value may change in subsequent calls if the user changes the default launcher app.

Note: See also the support library counterpart isRequestPinShortcutSupported(Context), which supports Android versions lower than O using the legacy private intent com.android.launcher.action.INSTALL_SHORTCUT.

譯:
如果默認桌面支持requestPinShortcut(ShortcutInfo,IntentSender)方法,則返回TRUE。

如果用戶更改默認啟動程序應用程序,返回值可能會在后續調用中更改。

注意:另請參見支持庫對應的isRequestPinShortcutSupported(Context),在低于O的Android版本,它支持使用舊的私有意圖com.android.launcher.action.INSTALL_SHORTCUT。

2.requestPinShortcut

官文:
Request to create a pinned shortcut. The default launcher will receive this request and ask the user for approval. If the user approves it, the shortcut will be created, and resultIntent will be sent. If a request is denied by the user, however, no response will be sent to the caller.

Only apps with a foreground activity or a foreground service can call this method. Otherwise, it’ll throw IllegalStateException.

It’s up to the launcher to decide how to handle previous pending requests when the same package calls this API multiple times in a row. One possible strategy is to ignore any previous requests.

Note: See also the support library counterpart requestPinShortcut(Context, ShortcutInfoCompat, IntentSender), which supports Android versions lower than O using the legacy private intent com.android.launcher.action.INSTALL_SHORTCUT.

譯:
請求創建固定的快捷方式。默認啟動器將收到該請求,并要求用戶批準。如果用戶批準,將創建快捷方式,并且將發送resultIntent。但是,如果請求被用戶拒絕,則不會向呼叫者發送任何響應。

只有具有前臺活動或前臺服務的應用程序才能調用此方法。否則,它將拋出IllegalStateException。

當同一個軟件包連續多次調用該API時,由開發人員決定如何處理以前的待處理請求。一個可能的策略是忽略任何先前的請求。

注意:另請參見支持庫對應件requestPinShortcut(Context,ShortcutInfoCompat,IntentSender),在低于O的Android版本,它支持使用舊的私有意圖com.android.launcher.action.INSTALL_SHORTCUT。

3.createShortcutResultIntent

官文:
Returns an Intent which can be used by the default launcher to pin a shortcut containing the given ShortcutInfo. This method should be used by an Activity to set a result in response to ACTION_CREATE_SHORTCUT.

譯:
返回默認啟動器可以使用的Intent來固定包含給定的ShortcutInfo的快捷方式。 Activity應該使用此方法來設置響應ACTION_CREATE_SHORTCUT的結果。

@RequiresApi(api = Build.VERSION_CODES.O)
public static void addShortCut(Context context) {
      ShortcutManager shortcutManager = (ShortcutManager) context.getSystemService(Context.SHORTCUT_SERVICE);
      if(shortcutManager.isRequestPinShortcutSupported()) {
          Intent shortcutInfoIntent = new Intent(context, ShortcutActivity.class);
          shortcutInfoIntent.setAction(Intent.ACTION_VIEW);
          ShortcutInfo info = new ShortcutInfo.Builder(context, "The only id")
               .setIcon(Icon.createWithResources(context, R.mipmap.ic_shortcut))
               .setShortLabel("Short Label")
               .setIntent(shortcutInfoIntent);
               .build();
          //當添加快捷方式的確認彈框彈出來時,將被回調
          PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, MyReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
        shortcutManager.requestPinShortcut(info, shortcutCallbackIntent.getIntentSender());
      }
}
image

根據彈窗提示可以看出,可以通過拖動這個圖標往桌面上添加快捷方式,可以通過點擊自動添加按鍵,系統給你在桌面的默認位置上添加。

添加后,桌面上會出現如圖所示的圖標:


image

回調用到的Receiver:

public class MyReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        Log.i(TAG, "onReceive: ");
    }
}

打印log發現,onReceive如圖官方文檔所說,點擊彈框自動添加按鍵后,會得到回調。但實踐發現,如果桌面上已經添加了圖標,當再次調用requestPinShortcut進行添加時,onReceive會在調用requestPinShortcut的時候,直接被回調,而且彈框也會彈出來。

ShortcutManagerCompat

在以上三個方法官方介紹中,官方提示我們,可以使用Android support庫的ShortcutManagerCompat進行快捷方式的版本適配。于是,在build.gradle中添加依賴進行嘗試:

compile 'com.android.support:appcompat-v7:26.+'
public static void addShortCutCompact(Context context) {
    if (ShortcutManagerCompat.isRequestPinShortcutSupported(context)) {
        Intent shortcutInfoIntent = new Intent(context, ShortcutActivity.class);
        shortcutInfoIntent.setAction(Intent.ACTION_VIEW); //action必須設置,不然報錯

        ShortcutInfoCompat info = new ShortcutInfoCompat.Builder(context, "The only id")
                .setIcon(R.mipmap.ic_shortcut)
                .setShortLabel("Short Label")
                .setIntent(shortcutInfoIntent)
                .build();

        //當添加快捷方式的確認彈框彈出來時,將被回調
        PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, MyReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
        ShortcutManagerCompat.requestPinShortcut(context, info, shortcutCallbackIntent.getIntentSender());
    }
}

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 228,197評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,415評論 3 415
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 176,104評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,884評論 1 309
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,647評論 6 408
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,130評論 1 323
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,208評論 3 441
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,366評論 0 288
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,887評論 1 334
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,737評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,939評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,478評論 5 358
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,174評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,586評論 0 26
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,827評論 1 283
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,608評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,914評論 2 372