I am implementing a Parent's And Child's App where
I am using the Device Administration Feature to implement this.
When Enabled the Administrator, I want to disable the uninstall button in the child's app
image
Here is my code..
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private PolicyManager policyManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
policyManager = new PolicyManager(this);
}
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
switch (v.getId()) {
case R.id.activate_admin:
if (!policyManager.isAdminActive()) {
Intent activateDeviceAdmin = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
activateDeviceAdmin.putExtra(DevicePolicyManager.ACTION_SET_NEW_PASSWORD,"abcdefgh");
activateDeviceAdmin.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, policyManager.getAdminComponent());
activateDeviceAdmin.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "After activating admin, you will be able to block application uninstallation.");
startActivityForResult(activateDeviceAdmin,
PolicyManager.DPM_ACTIVATION_REQUEST_CODE);
}
break;
case R.id.deactivate_admin:
if (policyManager.isAdminActive())
policyManager.disableAdmin();
break;
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
// TODO Auto-generated method stub
if (resultCode == this.RESULT_OK && requestCode == PolicyManager.DPM_ACTIVATION_REQUEST_CODE) {
// handle code for successfull enable of admin
} else {
super.onActivityResult(requestCode, resultCode, data);
}
}
}
MyReceiver.java
public class SampleDeviceAdminReceiver extends DeviceAdminReceiver {
@Override
public void onDisabled(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "disabled dpm", Toast.LENGTH_SHORT).show();
super.onDisabled(context, intent);
}
@Override
public void onEnabled(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "enabled dpm", Toast.LENGTH_SHORT).show();
super.onEnabled(context, intent);
}
@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
// TODO Auto-generated method stub
Toast.makeText(context, "disable dpm request", Toast.LENGTH_SHORT).show();
return super.onDisableRequested(context, intent);
}
}
PolicyManager.java
public class PolicyManager {
public static final int DPM_ACTIVATION_REQUEST_CODE = 100;
private Context mContext;
private DevicePolicyManager mDPM;
private ComponentName adminComponent;
public PolicyManager(Context context) {
// TODO Auto-generated constructor stub
this.mContext = context;
mDPM = (DevicePolicyManager) mContext
.getSystemService(Context.DEVICE_POLICY_SERVICE);
adminComponent = new ComponentName(mContext.getPackageName(),
mContext.getPackageName() + ".SampleDeviceAdminReceiver");
}
public boolean isAdminActive() {
return mDPM.isAdminActive(adminComponent);
}
public ComponentName getAdminComponent() {
return adminComponent;
}
public void disableAdmin() {
mDPM.removeActiveAdmin(adminComponent);
}
}
I also wanted to implement the same feature on my application.
I've successfully managed to enable the permission.
The catch is that you have to ask this permission from the user firing a specific intent called "DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN".
I have implemented the same feature in a demo application.
Adding the functionality step by step to make it code applicable.
My Application is developed in Kotlin, if you want to convert this code into java, than you can use the following links
1 Convert from Android Studio
2 Online Converter
STEP 1
my_admin.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<limit-password />
<watch-login />
<reset-password />
<force-lock />
<wipe-data />
</uses-policies>
</device-admin>
Step 2
You will have to create a class which extends to DeviceAdminReceiver
In my case I've named the file as DeviceAdminDemo
DeviceAdminDemo.kt
class DeviceAdminDemo : DeviceAdminReceiver() {
override fun onReceive(context: Context, intent: Intent) {
super.onReceive(context, intent)
}
override fun onEnabled(context: Context, intent: Intent) {
super.onEnabled(context, intent)
}
override fun onDisabled(context: Context, intent: Intent) {
super.onDisabled(context, intent)
}
}
Step 3
AndroidManifest
<?xml version="1.0" encoding="utf-8"?>
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application
android:allowBackup="true"
android:dataExtractionRules="@xml/data_extraction_rules"
android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.DeviceAdminDemo"
tools:targetApi="31">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="" />
</activity>
<receiver
android:name=".DeviceAdminDemo"
android:description="@string/device_description"
android:exported="true"
android:label="@string/device_admin_label"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="@xml/my_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
</application>
</manifest>
Step 4
MainActivity.kt
class MainActivity : AppCompatActivity() {
lateinit var mDPM: DevicePolicyManager
lateinit var mAdminName: ComponentName
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
val resultLauncher =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
val data: Intent? = result.data
}
}
try {
mDPM = getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
mAdminName = ComponentName(this, DeviceAdminDemo::class.java)
if (!mDPM.isAdminActive(mAdminName)) {
val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN)
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName)
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.")
resultLauncher.launch(intent)
} else {
mDPM.lockNow()
}
} catch (e: Exception) {
e.printStackTrace()
}
}
}
General Information
This application will redirect the user to a permission grantor screen, if the user grants the permission for admin rights then the user won't be able to force stop or uninstall the application, unless it decides to rollback the permission. The user would not be able to uninstall application from the app drawer.
Ones when the user has granted the permission than it can only uninstall the application either by going to the Application's Info Screen and finish the process as shown in the screenshots or has to go to the Settings>>Application Management>>App Info and finish the process as shown in the screenshots.
Also attaching screenshots for better understanding of the application
Permission Page
Note
The actual screens might differ from the screenshots due to different API levels and different OS Versions.
If you got the output you excepted please do drop an upvote to make me encourage solving more and more problems
Also share your thoughts and suggestions on this by using the comments sections.
ADIOS
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With