【學以致用】android功能實現5---android8.0 Launcher獲取快捷方式原始碼分析(1)
從其他應用往桌面建立快捷方式,android8.0統一採用requestPinShortcut的方式。 對於桌面而言,是怎麼從requestPinShortcut獲取快捷方式資訊在桌面建立快捷方式呢?
Android8.0的快捷方式引數不再通過廣播傳送,而是存放在系統當中。建立快捷方式的應用將資訊放入系統,而系統則生成shortcut ID等資訊,傳入桌面應用。
桌面建立快捷方式由兩部分完成。
1:獲取快捷方式的名字和圖示,然後將兩者作為快捷方式放到桌面上,提供移動拖拽點選等服務。桌面應用接收ID等數個資訊,在桌面建立快捷方式,其中的圖片等資源需要桌面通過ID等資訊去系統裡面獲取。
2:放置在桌面上的快捷方式有
實際操作流程如下:
首先需要建立一個activity,這個activity會在其他應用呼叫requestPinShortcut的時候,會在框架中通過一個service啟動一個activity。
該activity包含android.content.pm.action.CONFIRM_PIN_SHORTCUT和android.content.pm.action.CONFIRM_PIN_APPWIDGET
在Launcher的manifest
<activity android:name="com.android.launcher3.dragndrop.AddItemActivity"
android:theme="@android:style/Theme.DeviceDefault.Light.Dialog.Alert"
android:excludeFromRecents="true"
android:autoRemoveFromRecents="true"
android:label="@string/action_add_to_workspace" >
<intent-filter>
<action android:name="android.content.pm.action.CONFIRM_PIN_SHORTCUT" />
<action android:name="android.content.pm.action.CONFIRM_PIN_APPWIDGET" />
</intent-filter>
</activity>
這樣當其他應用點選在桌面建立快捷方式時,就會彈出這個activity,Launcher原始碼將本activity的設為style/Theme.DeviceDefault.Light.Dialog.Alert, 這樣彈出的activity就是一個對話方塊。
接著在activity中設立一個按鈕,點選的話,會自動建立快捷方式,這個按鈕主要是從intent獲取mRequest,在使用 InstallShortcutReceiver.queueShortcut來處理mRequest.getShortcutInfo()中的shortcut。
public void onPlaceAutomaticallyClick(View v) {
if (mRequest.getRequestType() == PinItemRequestCompat.REQUEST_TYPE_SHORTCUT) {
InstallShortcutReceiver.queueShortcut(
new ShortcutInfoCompat(mRequest.getShortcutInfo()), this);
logCommand(Action.Command.CONFIRM);
mRequest.accept();
finish();
return;
}
上面涉及兩個重點方法:
一個是:
InstallShortcutReceiver.queueShortcut( new ShortcutInfoCompat(mRequest.getShortcutInfo()), this);
用來將外界傳入的shortcut引數放入快捷方式建立列隊中,用來建立跨界方式。
另一個是:
mRequest.accept();
該方法會傳遞給系統,表示桌面接收了本次資訊,並將為本次資訊建立快捷方式。有了這個資訊,後面才可以通過ID資訊去系統裡面查詢,圖片等引數。
將intent中獲取的shortcutinfo由ShortcutInfoCompat處理一下,其實ShortcutInfoCompat和shortcutinfo是一樣的,ShortcutInfoCompat是用來將shortcutinfo的資訊更好的被Launcher使用。
public ShortcutInfoCompat(ShortcutInfo shortcutInfo) {
mShortcutInfo = shortcutInfo;
}
隨後建立PendingInstallShortcutInfo。裡面涉及到shortcutInfo 、user、launchIntent、 label 的賦值
public PendingInstallShortcutInfo(ShortcutInfoCompat info, Context context) {
activityInfo = null;
shortcutInfo = info;
providerInfo = null;
data = null;
mContext = context;
user = info.getUserHandle();
launchIntent = info.makeIntent();
label = info.getShortLabel().toString();
}
其中shortcutInfo 、user和 label是直接獲取,而launchIntent 是呼叫了makeIntent方法:
該方法,從shortcutInfo獲取了的activity、package和id這三個引數,剩下為預設配置引數。
return new Intent(Intent.ACTION_MAIN)
.addCategory(INTENT_CATEGORY)
.setComponent(getActivity())
.setPackage(getPackage())
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED)
.putExtra(EXTRA_SHORTCUT_ID, getId());
本intent是索引快捷方式的關鍵,用來在手機中定位究竟是什麼快捷方式。
總結,建立快捷方式主要由第三方應用呼叫requestPinShortcut來啟動包含android.content.pm.action.CONFIRM_PIN_SHORTCUT和android.content.pm.action.CONFIRM_PIN_APPWIDGET的附屬於Launcher的activity。
啟動該activity的時候,就會傳入一個intent。Intent包含第三方應用的包名,分辨快捷方式的ID。
如果Launcher接收了該快捷方式,則通過intent獲取PinItemRequestCompat,呼叫其accept()方法,表示使用者確定要建立該快捷方式,隨後系統將該快捷方式存入手機中。
而Launcher本身也獲取快捷方式的資訊,主要是packgakename和ID。用來建立具體的快捷方式圖示