I want to program an Android app with security features. The most important feature is that a user is not allowed to uninstall (or stop) the app.
So I found the DevicePolicyManager API which offers a method which is called setUninstallBlocked(). I tried to run this function but the app crashes with error log. You can see the log in this attachment.
Do you have any idea about what could be wrong ?
Log
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 ComponentInfo{com.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
package com.example.foralex;
public class MainActivity extends 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>
You should install your application as DeviceOwner or ProfileOwner to be able to use DevicePolicyManager API. Or ask a Do/Po delegation to use this api also.
Please google for "Android device owner / profile owner" and " android delegation scope " so all this make sense to you.
Good luck