1. 程式人生 > >Android 啟用裝置管理器後就無法再次開啟裝置管理器介面

Android 啟用裝置管理器後就無法再次開啟裝置管理器介面

Android系統的裝置管理器功能在一定程度上可以阻止app被解除安裝。一旦某個app申請了系統裝置管理器許可權,並且被使用者授予了此許可權,那麼使用者必須先取消該app的此項許可權才能解除安裝這個app。(此功能並不適用於所有機型,比如小米或者某些Android 6.0以上的華為手機。)

App在申請了裝置管理器許可權時,可以呼叫如下方法開啟裝置管理器頁面:

    public static void startDeviceManager(Context mContext) {
        //新增一個隱式意圖,完成裝置許可權的新增
        //這個Intent (DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)跳轉到 許可權提醒頁面
//並傳遞了兩個引數EXTRA_DEVICE_ADMIN 、 EXTRA_ADD_EXPLANATION Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN); ComponentName componentName = new ComponentName(mContext, ActivateDeviceAdminReceiver.class); //許可權列表 //EXTRA_DEVICE_ADMIN引數中說明了用到哪些許可權, intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, componentName); //描述(additional explanation)
//EXTRA_ADD_EXPLANATION引數為附加的說明 intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, ""); // intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); ((Activity) mContext).startActivityForResult(intent, 0); }

其中上面程式碼中的ActivateDeviceAdminReceiver是一個自定義的BroadcastReceiver,必須繼承於android.app.admin.DeviceAdminReceiver。在Mainfest中註冊如下:

        <receiver
            android:name=".receiver.ActivateDeviceAdminReceiver"
            android:description="@string/description" 這裡的字串會出現在裝置管理器啟用頁面
            android:label="@string/app_name"
            android:permission="android.permission.BIND_DEVICE_ADMIN">
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/device_admin" />

            <intent-filter>
                <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
            </intent-filter>
        </receiver>

在ActivateDeviceAdminReceiver中,我們可以覆蓋父類的onEnable(),onDisable()等方法,用於處理裝置管理器被開啟或者關閉等情況。

開啟的頁面類似如下:

但經實驗發現,如果使用者未為app開啟裝置管理器功能,那麼呼叫上面的startDeviceManager()方法是可以開啟裝置管理器頁面的。但是一旦開啟開啟裝置管理器功能之後,就無法打開了。這是為什麼呢?

看原始碼註釋:

     * <p>If your administrator is already active, this will ordinarily return immediately (without
     * user intervention).  However, if your administrator has been updated and is requesting
     * additional uses-policy flags, the user will be presented with the new list.  New policies
     * will not be available to the updated administrator until the user has accepted the new list.
     */
    @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
    public static final String ACTION_ADD_DEVICE_ADMIN
            = "android.app.action.ADD_DEVICE_ADMIN";

大概意思就是說,如果裝置管理器許可權已經打開了的話,想呼叫這個ACTION_ADD_DEVICE_ADMIN型別的Intent去開啟裝置管理器頁面,是不行的,系統會在沒有任何提示的情況下立即返回(即如果呼叫startActivityForResult()去開啟裝置管理器頁面的話,onActivityResult()方法會立即被呼叫,並且經驗證,返回的resultCode為0)。

另外注意:裝置管理器頁面必須從activity中開啟,如果從Service中開啟是不行的。