SecurityException - “调用者......不是范围委托阻止卸载的代表”(Android 8 - Java)

Posted

技术标签:

【中文标题】SecurityException - “调用者......不是范围委托阻止卸载的代表”(Android 8 - Java)【英文标题】:SecurityException - "caller ... is not a delegate of scope delegation-block-uninstall" (Android 8 - Java) 【发布时间】:2020-06-12 02:34:27 【问题描述】:

我想编写一个具有安全功能的 android 应用程序。最重要的功能是不允许用户卸载(或停止)应用程序。

所以我找到了DevicePolicyManager API,它提供了一个名为 setUninstallBlocked() 的方法。我尝试运行此功能,但应用程序因错误日志而崩溃。您可以在此附件中查看日志。

您对可能出现的问题有任何想法吗?

日志

2020-02-28 01:57:22.231 20440-20440/com.example.foralex E/AndroidRuntime: FATAL EXCEPTION: main
                Process: com.example.foralex, PID: 20440
                java.lang.RuntimeException: Unable to start activity ComponentInfocom.example.foralex/com.example.foralex.MainActivity: java.lang.SecurityException: Caller with uid 10090 is not a delegate of scope delegation-block-uninstall.
                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2817)
                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892)
                    at android.app.ActivityThread.-wrap11(Unknown Source:0)
                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593)
                    at android.os.Handler.dispatchMessage(Handler.java:105)
                    at android.os.Looper.loop(Looper.java:164)
                    at android.app.ActivityThread.main(ActivityThread.java:6541)
                    at java.lang.reflect.Method.invoke(Native Method)
                    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240)
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)
                 Caused by: java.lang.SecurityException: Caller with uid 10090 is not a delegate of scope delegation-block-uninstall.
                    at android.os.Parcel.readException(Parcel.java:1942)
                    at android.os.Parcel.readException(Parcel.java:1888)
                    at android.app.admin.IDevicePolicyManager$Stub$Proxy.setUninstallBlocked(IDevicePolicyManager.java:6965)
                    at android.app.admin.DevicePolicyManager.setUninstallBlocked(DevicePolicyManager.java:6568)
                    at com.example.foralex.MainActivity.blockUninstallOfThisApp(MainActivity.java:206)
                    at com.example.foralex.MainActivity.onCreate(MainActivity.java:184)
                    at android.app.Activity.performCreate(Activity.java:6975)
                    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1213)
                    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2770)
                    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2892) 
                    at android.app.ActivityThread.-wrap11(Unknown Source:0) 
                    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1593) 
                    at android.os.Handler.dispatchMessage(Handler.java:105) 
                    at android.os.Looper.loop(Looper.java:164) 
                    at android.app.ActivityThread.main(ActivityThread.java:6541) 
                    at java.lang.reflect.Method.invoke(Native Method) 
                    at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:240) 
                    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:767)

MainActivity.java

包 com.example.foralex;

公共类 MainActivity 扩展 AppCompatActivity

@Override
protected void onCreate(Bundle savedInstanceState) 

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // ATTENTION: critical function!
    blockUninstallOfThisApp("com.example.foralex");



/**
 * Blocks the uninstall of the selected package
 * ToDo: Need to work here!
 */
public void blockUninstallOfThisApp (String appStr)
    DevicePolicyManager dpm  =  this.getSystemService(DevicePolicyManager.class);
    // set the app to the state that it can not get uninstalled
    dpm.setUninstallBlocked(null, appStr, true);
  

AndroidManifest.xml

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.foralex">

        <uses-permission
            android:name="android.permission.PACKAGE_USAGE_STATS" />

        <uses-permission

        <uses-permission
            android:name="Manifest.permission.BIND_DEVICE_ADMIN " />



        <application

            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity android:name="com.example.foralex.MainActivity">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />
                    <category android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>

        </application>

    </manifest>

</xml>

【问题讨论】:

【参考方案1】:

您应该将应用程序安装为 DeviceOwner 或 ProfileOwner 才能使用 DevicePolicyManager API。或者让 Do/Po 代表团也使用这个 api。

请在 Google 上搜索“Android 设备所有者/个人资料所有者”和“android 委托范围”,这样所有这些对您来说都有意义。

祝你好运

【讨论】:

以上是关于SecurityException - “调用者......不是范围委托阻止卸载的代表”(Android 8 - Java)的主要内容,如果未能解决你的问题,请参考以下文章

shutdown&&isTerminated

被调用者分配被调用者释放

如何使用inspect从Python中的被调用者那里获取调用者的信息?

使用rpcgen时,调用者如何找到被调用者?

调用者和被调用者中数组元素的值不同

如何将右值引用从调用者传递给被调用者