You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Flutter构建无法卸载的Android默认应用?

解决Flutter Android应用设为默认且禁止卸载的问题

你的现有代码缺少关键配置与权限环节,导致禁止卸载的逻辑未生效。以下是分步骤的修复与实现方案:


一、修复「禁止卸载」的核心逻辑

1. 实现必需的DeviceAdminReceiver组件

在android/app/src/main/kotlin/[你的包名]/路径下创建YourDeviceAdminReceiver.kt:

import android.app.admin.DeviceAdminReceiver
import android.content.Context
import android.content.Intent

class YourDeviceAdminReceiver : DeviceAdminReceiver() {
    override fun onEnabled(context: Context, intent: Intent) {
        super.onEnabled(context, intent)
        // 管理员权限激活后的自定义操作(如提示用户)
    }
}

2. 配置AndroidManifest.xml权限与组件

在AndroidManifest.xml中添加设备管理员权限,并注册上述Receiver:

<!-- 全局权限声明 -->
<uses-permission android:name="android.permission.BIND_DEVICE_ADMIN" />
<uses-permission android:name="android.permission.MANAGE_DEVICE_ADMINS" />

<!-- 在application标签内添加Receiver -->
<receiver
    android:name=".YourDeviceAdminReceiver"
    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>

3. 创建设备管理员策略配置文件

在res/xml目录下新建device_admin.xml(无xml目录则手动创建):

<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
    <uses-policies>
        <!-- 声明阻止应用卸载的权限 -->
        <limit-installed-packages />
    </uses-policies>
</device-admin>

4. 引导用户激活设备管理员权限

调用setUninstallBlocked前必须确保应用已获得设备管理员权限,在MainActivity中添加激活逻辑:

private fun requestDeviceAdmin() {
    val adminComponent = ComponentName(this, YourDeviceAdminReceiver::class.java)
    val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN).apply {
        putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, adminComponent)
        putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "需要激活设备管理员权限以禁止卸载")
    }
    startActivityForResult(intent, 1001)
}

// 处理权限激活结果
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    super.onActivityResult(requestCode, resultCode, data)
    if (requestCode == 1001) {
        if (resultCode == RESULT_OK) {
            // 权限激活成功,可执行禁止卸载逻辑
        } else {
            // 用户拒绝权限,需提示
        }
    }
}

5. 注意自身卸载限制的特殊要求

setUninstallBlocked默认只能阻止其他应用卸载,若要阻止自身被卸载,你的应用必须成为设备所有者,需通过ADB命令设置(仅适用于调试/企业设备):

adb shell dpm set-device-owner [你的应用包名]/.YourDeviceAdminReceiver

二、实现「设为默认应用」逻辑

以设为默认Launcher为例,修改MainActivity的intent-filter:

<activity
    android:name=".MainActivity"
    android:exported="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.LAUNCHER" />
        <!-- 添加默认应用必需的category -->
        <category android:name="android.intent.category.HOME" />
        <category android:name="android.intent.category.DEFAULT" />
    </intent-filter>
</activity>

可通过代码引导用户跳转系统默认应用设置页面:

fun openDefaultAppSettings() {
    val intent = Intent(android.provider.Settings.ACTION_HOME_SETTINGS)
    startActivity(intent)
}

三、Flutter侧补充调用逻辑

新增权限检查方法,确保调用禁止卸载前权限已激活:

import 'package:flutter/services.dart';

const platform = MethodChannel('your_channel_name');

// 检查设备管理员权限是否激活
Future<bool> isDeviceAdminActive() async {
  try {
    return await platform.invokeMethod('isDeviceAdminActive') ?? false;
  } on PlatformException catch (e) {
    print('权限检查失败: ${e.message}');
    return false;
  }
}

// 原有的禁止卸载方法
Future<void> setUninstallBlocked(String packageName, bool uninstallBlocked) async {
  try {
    await platform.invokeMethod('setUninstallBlocked', {
      'packageName': packageName,
      'uninstallBlocked': uninstallBlocked,
    });
  } on PlatformException catch (e) {
    print('操作失败: ${e.message}');
  }
}

原生侧补充权限检查的MethodChannel实现:

// 在configureFlutterEngine的MethodCallHandler中添加case
"isDeviceAdminActive" -> {
    val adminComponent = ComponentName(this, YourDeviceAdminReceiver::class.java)
    val dpm = getSystemService(DEVICE_POLICY_SERVICE) as DevicePolicyManager
    result.success(dpm.isAdminActive(adminComponent))
}

常见排查点

  • 查看Logcat日志,setUninstallBlocked失败会返回明确的权限错误信息
  • 确认设备管理员权限已激活,且应用已通过ADB设置为设备所有者(自身卸载限制需要)
  • 检查AndroidManifest的权限、Receiver配置是否完全匹配上述要求

内容的提问来源于stack exchange,提问作者Kumaresan Jackie

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 03:37:54