如何在设置Android中禁用应用程序的卸载按钮

Arp*_*116 5 android device-admin

我正在实施父母和孩子的应用程序

  1. 父母可以追踪自己的孩子
  2. 孩子无法卸载该应用程序。

我正在使用设备管理功能来实现此目的。

启用管理员后,我想禁用孩子应用程序中的卸载按钮

图片

这是我的代码。

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);
    }
}
}
Run Code Online (Sandbox Code Playgroud)

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);
}



}
Run Code Online (Sandbox Code Playgroud)

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);
}
}
Run Code Online (Sandbox Code Playgroud)

Vis*_*hah 6

我也想在我的应用程序上实现相同的功能。

我已成功启用该权限。

问题是您必须向触发名为“DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN”的特定意图的用户请求此权限。

我在演示应用程序中实现了相同的功能。

逐步添加功能以使其代码适用。

我的应用程序是用Kotlin开发的,如果您想将此代码转换为java,那么您可以使用以下链接
1从Android Studio转换
2 Online Converter

步骤1

  • 在 res/xml 文件夹中创建 XML 文件
  • 文件名 - my_admin.xml(您可以根据需要修改名称)

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>
Run Code Online (Sandbox Code Playgroud)
  • 确保只添加需要的权限,添加不必要的权限将导致用户无法激活管理员权限。

第2步

  • 您必须创建一个扩展到DeviceAdminReceiver的类

  • 就我而言,我将该文件命名为 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)
 }
}
Run Code Online (Sandbox Code Playgroud)
  • 本课程将收到用户的反馈

步骤3

  • 同样编辑您的清单文件

Android清单

<?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>
Run Code Online (Sandbox Code Playgroud)

步骤4

  • 现在这是我的 MainActivity 的代码,我在其中触发了 Intent

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()
    }
}
}
Run Code Online (Sandbox Code Playgroud)
  • 最低目标 API 级别为 21,最高目标 API 级别为 32。

一般信息

此应用程序会将用户重定向到权限授予者屏幕,如果用户授予管理员权限,则用户将无法强制停止或卸载该应用程序,除非决定回滚该权限。用户将无法从应用程序抽屉中卸载应用程序。

当用户授予权限时,只能通过转到应用程序的信息屏幕并完成屏幕截图中所示的过程来卸载应用程序,或者必须转到设置>>应用程序管理>>应用程序信息并完成过程如屏幕截图所示。

  • 还附上屏幕截图以便更好地了解该应用程序

  • 权限页面

权限页面

  • 这是用户接受权限后的样子

许可授予

  • 单击卸载按钮后

卸载页面

笔记

由于不同的 API 级别和不同的操作系统版本,实际屏幕可能与屏幕截图有所不同。

如果您得到了您所排除的输出,请投赞成票,以鼓励我解决越来越多的问题

还可以通过评论部分分享您对此的想法和建议。

阿迪奥斯