1. 程式人生 > >【學以致用】android功能實現5---android8.0 Launcher獲取快捷方式原始碼分析(1)

【學以致用】android功能實現5---android8.0 Launcher獲取快捷方式原始碼分析(1)

從其他應用往桌面建立快捷方式,android8.0統一採用requestPinShortcut的方式。 對於桌面而言,是怎麼從requestPinShortcut獲取快捷方式資訊在桌面建立快捷方式呢?

Android8.0的快捷方式引數不再通過廣播傳送,而是存放在系統當中。建立快捷方式的應用將資訊放入系統,而系統則生成shortcut ID等資訊,傳入桌面應用。

桌面建立快捷方式由兩部分完成。

1:獲取快捷方式的名字和圖示,然後將兩者作為快捷方式放到桌面上,提供移動拖拽點選等服務。桌面應用接收ID等數個資訊,在桌面建立快捷方式,其中的圖片等資源需要桌面通過ID等資訊去系統裡面獲取。

2:放置在桌面上的快捷方式有

intent這個引數存入資料庫,而intent引數一個核心功能是啟動該應用。配置合理的intent並使其能夠啟動。點選啟動應用的時候,也是通過ID等資訊,去系統中啟動。

實際操作流程如下:

首先需要建立一個activity,這個activity會在其他應用呼叫requestPinShortcut的時候,會在框架中通過一個service啟動一個activity

activity包含android.content.pm.action.CONFIRM_PIN_SHORTCUTandroid.content.pm.action.CONFIRM_PIN_APPWIDGET

Launchermanifest

裡面這樣寫。

<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>

這樣當其他應用點選在桌面建立快捷方式時,就會彈出這個activityLauncher原始碼將本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中獲取的shortcutinfoShortcutInfoCompat處理一下,其實ShortcutInfoCompatshortcutinfo是一樣的,ShortcutInfoCompat是用來將shortcutinfo的資訊更好的被Launcher使用。

public ShortcutInfoCompat(ShortcutInfo shortcutInfo) {
    mShortcutInfo = shortcutInfo;
}

隨後建立PendingInstallShortcutInfo。裡面涉及到shortcutInfo userlaunchIntent 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獲取了activitypackageid這三個引數,剩下為預設配置引數。

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_SHORTCUTandroid.content.pm.action.CONFIRM_PIN_APPWIDGET的附屬於Launcheractivity

啟動該activity的時候,就會傳入一個intentIntent包含第三方應用的包名,分辨快捷方式的ID

如果Launcher接收了該快捷方式,則通過intent獲取PinItemRequestCompat,呼叫其accept()方法,表示使用者確定要建立該快捷方式,隨後系統將該快捷方式存入手機中。

Launcher本身也獲取快捷方式的資訊,主要是packgakenameID。用來建立具體的快捷方式圖示