在Android O原生桌面上姑廉,按照傳統(tǒng)創(chuàng)建快捷方式的形式,是不會產(chǎn)生快捷方式的罗侯。
傳統(tǒng)方式如下:
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);
// 不允許重復(fù)創(chuàng)建仑撞,不是根據(jù)快捷方式的名字判斷重復(fù)的
addShortcutIntent.putExtra("duplicate", false);
addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Shortcut Name");
//圖標(biāo)
addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.mipmap.ic_shortcut));
// 設(shè)置關(guān)聯(lián)程序
Intent launcherIntent = new Intent();
launcherIntent.setClass(context, ShortcutActivity.class);
addShortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, launcherIntent);
// 發(fā)送廣播
context.sendBroadcast(addShortcutIntent);
}
ShortCutManager
從Android 7.1(API 25)開始聋袋,新增了ShortcutManager突倍,可以對桌面久按應(yīng)用圖標(biāo)彈出的快捷方式進(jìn)行管理腔稀。
但是,Android 7.1上直接往桌面上添加快捷方式依然是使用上面說到的這種舊方式羽历,但是Android O上焊虏,Google應(yīng)該是想通過比較統(tǒng)一的接口來管理桌面快捷方式了,所以摒棄了這種形式窄陡,轉(zhuǎn)而使用ShortcutManager進(jìn)行管理炕淮。所以API 26上,ShortcutManager進(jìn)行管理跳夭。所以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.
譯:
應(yīng)用程序可以使用requestPinShortcut(ShortcutInfo币叹,IntentSender)將現(xiàn)有的快捷方式(靜態(tài)或動態(tài))或全新的快捷方式固定到支持的啟動器。你通過這個方法的兩個參數(shù):
ShortcutInfo對象 - 如果快捷方式已存在模狭,則該對象應(yīng)僅包含快捷方式的ID颈抚。否則,新的ShortcutInfo對象必須包含新快捷方式的ID,意圖和短標(biāo)簽贩汉。
PendingIntent對象 - 此意圖表示如果快捷方式成功固定到設(shè)備的啟動器驱富,您的應(yīng)用程序?qū)⑹盏交卣{(diào)。
注意:如果用戶不允許將快捷方式固定在啟動器上匹舞,則固定進(jìn)程將失敗褐鸥,并且未執(zhí)行傳入此PendingIntent對象的Intent對象。
注意:由于Android O中引入的后臺執(zhí)行限制赐稽,最好使用清單聲明的接收器來接收回調(diào)叫榕。
另外,為了防止其他應(yīng)用程序調(diào)用接收器姊舵,將屬性賦值android:exported =“false”添加到接收者的清單條目中晰绎。
注意:當(dāng)您在應(yīng)用程序中添加邏輯以引導(dǎo)快捷方式時,請記住括丁,并非所有啟動器都支持固定快捷方式荞下。 要確定您的應(yīng)用程序是否可以在特定設(shè)備上完成此過程,請檢查isRequestPinShortcutSupported()的返回值史飞。 根據(jù)此返回值尖昏,您可以決定隱藏您應(yīng)用程序中允許用戶固定快捷方式的選項。
注意:另請參見支持庫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.
譯:
如果默認(rèn)桌面支持requestPinShortcut(ShortcutInfo荷鼠,IntentSender)方法句携,則返回TRUE。
如果用戶更改默認(rèn)啟動程序應(yīng)用程序允乐,返回值可能會在后續(xù)調(diào)用中更改矮嫉。
注意:另請參見支持庫對應(yīng)的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.
譯:
請求創(chuàng)建固定的快捷方式。默認(rèn)啟動器將收到該請求鳞陨,并要求用戶批準(zhǔn)昨寞。如果用戶批準(zhǔn),將創(chuàng)建快捷方式,并且將發(fā)送resultIntent援岩。但是歼狼,如果請求被用戶拒絕,則不會向呼叫者發(fā)送任何響應(yīng)享怀。
只有具有前臺活動或前臺服務(wù)的應(yīng)用程序才能調(diào)用此方法羽峰。否則,它將拋出IllegalStateException凹蜈。
當(dāng)同一個軟件包連續(xù)多次調(diào)用該API時限寞,由開發(fā)人員決定如何處理以前的待處理請求。一個可能的策略是忽略任何先前的請求仰坦。
注意:另請參見支持庫對應(yīng)件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.
譯:
返回默認(rèn)啟動器可以使用的Intent來固定包含給定的ShortcutInfo的快捷方式妈橄。 Activity應(yīng)該使用此方法來設(shè)置響應(yīng)ACTION_CREATE_SHORTCUT的結(jié)果庶近。
@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();
//當(dāng)添加快捷方式的確認(rèn)彈框彈出來時,將被回調(diào)
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, MyReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
shortcutManager.requestPinShortcut(info, shortcutCallbackIntent.getIntentSender());
}
}
根據(jù)彈窗提示可以看出眷蚓,可以通過拖動這個圖標(biāo)往桌面上添加快捷方式鼻种,可以通過點擊自動添加按鍵,系統(tǒng)給你在桌面的默認(rèn)位置上添加沙热。
添加后叉钥,桌面上會出現(xiàn)如圖所示的圖標(biāo):
回調(diào)用到的Receiver:
public class MyReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "onReceive: ");
}
}
打印log發(fā)現(xiàn),onReceive如圖官方文檔所說篙贸,點擊彈框自動添加按鍵后投队,會得到回調(diào)。但實踐發(fā)現(xiàn)爵川,如果桌面上已經(jīng)添加了圖標(biāo)敷鸦,當(dāng)再次調(diào)用requestPinShortcut進(jìn)行添加時,onReceive會在調(diào)用requestPinShortcut的時候寝贡,直接被回調(diào)扒披,而且彈框也會彈出來。
ShortcutManagerCompat
在以上三個方法官方介紹中圃泡,官方提示我們谎碍,可以使用Android support庫的ShortcutManagerCompat進(jìn)行快捷方式的版本適配。于是洞焙,在build.gradle中添加依賴進(jìn)行嘗試:
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必須設(shè)置,不然報錯
ShortcutInfoCompat info = new ShortcutInfoCompat.Builder(context, "The only id")
.setIcon(R.mipmap.ic_shortcut)
.setShortLabel("Short Label")
.setIntent(shortcutInfoIntent)
.build();
//當(dāng)添加快捷方式的確認(rèn)彈框彈出來時,將被回調(diào)
PendingIntent shortcutCallbackIntent = PendingIntent.getBroadcast(context, 0, new Intent(context, MyReceiver.class), PendingIntent.FLAG_UPDATE_CURRENT);
ShortcutManagerCompat.requestPinShortcut(context, info, shortcutCallbackIntent.getIntentSender());
}
}