diff --git a/README.md b/README.md index 2b4a62e..8f2c9b4 100644 --- a/README.md +++ b/README.md @@ -269,18 +269,37 @@ if (opened) { 相比传统的 `openAppSettings()` 方法会打开应用的全部设置页面,新增的 `openInstallPermissionSettings()` 方法可以更精确地定位到安装权限设置: -- **Android 8.0+**:直接跳转到"安装未知应用"权限页面 +- **Android 8.0+**:直接跳转到当前应用的"安装未知应用"权限页面 - **Android 8.0-**:跳转到应用详情页面 -- **自动降级**:如果无法打开精确页面,会自动使用通用设置页面作为后备 +- **厂商适配**:针对小米、华为、OPPO、Vivo、三星等定制ROM优化 +- **多重降级**:确保在各种情况下都能成功跳转到相关设置页面 ```dart // 使用新方法精确跳转到安装权限设置 -await AppUpgradePlugin().openInstallPermissionSettings(); +final success = await AppUpgradePlugin().openInstallPermissionSettings(); +if (success) { + print('成功跳转到安装权限设置页面'); +} else { + print('跳转失败,请检查设备兼容性'); +} -// 对比:传统方法打开全部应用设置 -await openAppSettings(); +// 获取设备信息用于调试 +final deviceInfo = await AppUpgradePlugin().getDeviceInfo(); +print('设备制造商: ${deviceInfo?['manufacturer']}'); +print('Android版本: ${deviceInfo?['release']}'); ``` +**厂商特殊适配**: + +| 厂商 | 特殊处理 | 预期效果 | +|------|---------|----------| +| 小米/红米 | MIUI权限管理页面 | 直接跳转到应用权限设置 | +| 华为/荣耀 | EMUI/HarmonyOS适配 | 跳转到应用管理页面 | +| OPPO | ColorOS标准方式 | 直接跳转到安装权限 | +| Vivo | FunTouch OS标准方式 | 直接跳转到安装权限 | +| 三星 | One UI标准方式 | 直接跳转到安装权限 | +| 原生Android | 标准Intent | 直接跳转到安装权限 | + ## 🐛 故障排除 ### 常见问题 diff --git a/android/src/main/kotlin/com/example/app_upgrade_plugin/AppUpgradePlugin.kt b/android/src/main/kotlin/com/example/app_upgrade_plugin/AppUpgradePlugin.kt index cf65f72..5e4729e 100644 --- a/android/src/main/kotlin/com/example/app_upgrade_plugin/AppUpgradePlugin.kt +++ b/android/src/main/kotlin/com/example/app_upgrade_plugin/AppUpgradePlugin.kt @@ -19,6 +19,7 @@ import java.io.FileInputStream import java.math.BigInteger import java.security.MessageDigest import android.os.Environment +import android.content.ComponentName /** AppUpgradePlugin */ class AppUpgradePlugin: FlutterPlugin, MethodCallHandler, ActivityAware { @@ -106,6 +107,9 @@ class AppUpgradePlugin: FlutterPlugin, MethodCallHandler, ActivityAware { "openInstallPermissionSettings" -> { openInstallPermissionSettings(result) } + "getDeviceInfo" -> { + getDeviceInfo(result) + } else -> { result.notImplemented() } @@ -202,34 +206,195 @@ class AppUpgradePlugin: FlutterPlugin, MethodCallHandler, ActivityAware { try { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { - // Android 8.0 及以上版本,直接跳转到安装未知应用权限页面 - val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) - intent.data = Uri.parse("package:${context.packageName}") - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - activity!!.startActivity(intent) + // Android 8.0 及以上版本,尝试多种方式跳转到安装未知应用权限页面 + + // 方法1:标准Android方式 - 直接跳转到当前应用的安装权限页面 + if (tryStandardInstallPermissionSettings()) { + result.success(true) + return + } + + // 方法2:尝试厂商特定的设置页面 + if (tryManufacturerSpecificSettings()) { + result.success(true) + return + } + + // 方法3:降级到应用详情页面 + val fallbackIntent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + fallbackIntent.data = Uri.parse("package:${context.packageName}") + fallbackIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(fallbackIntent) result.success(true) + } else { - // Android 8.0 以下版本,跳转到应用详情页面 - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - intent.data = Uri.parse("package:${context.packageName}") - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) - activity!!.startActivity(intent) - result.success(true) + // Android 8.0 以下版本,跳转到应用详情页面或安全设置 + try { + val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) + intent.data = Uri.parse("package:${context.packageName}") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(intent) + result.success(true) + } catch (e: Exception) { + // 降级到安全设置页面 + val securityIntent = Intent(Settings.ACTION_SECURITY_SETTINGS) + securityIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(securityIntent) + result.success(true) + } } } catch (e: Exception) { - // 如果无法跳转到具体页面,则跳转到应用设置 - try { - val intent = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS) - intent.data = Uri.parse("package:${context.packageName}") - intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + result.error("SETTINGS_ERROR", "Failed to open install permission settings: ${e.message}", null) + } + } + + private fun tryStandardInstallPermissionSettings(): Boolean { + return try { + val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) + intent.data = Uri.parse("package:${context.packageName}") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + // 检查是否有应用可以处理这个Intent + if (intent.resolveActivity(context.packageManager) != null) { activity!!.startActivity(intent) - result.success(true) - } catch (fallbackException: Exception) { - result.error("SETTINGS_ERROR", "Failed to open install permission settings", fallbackException.message) + true + } else { + false + } + } catch (e: Exception) { + false + } + } + + private fun tryManufacturerSpecificSettings(): Boolean { + val manufacturer = Build.MANUFACTURER.lowercase() + + return when { + manufacturer.contains("xiaomi") || manufacturer.contains("redmi") -> { + tryMiuiInstallPermissionSettings() + } + manufacturer.contains("huawei") || manufacturer.contains("honor") -> { + tryHuaweiInstallPermissionSettings() + } + manufacturer.contains("oppo") -> { + tryOppoInstallPermissionSettings() + } + manufacturer.contains("vivo") -> { + tryVivoInstallPermissionSettings() + } + manufacturer.contains("samsung") -> { + trySamsungInstallPermissionSettings() + } + else -> { + false } } } + private fun tryMiuiInstallPermissionSettings(): Boolean { + return try { + // MIUI 特殊处理 + val intent = Intent() + intent.action = "miui.intent.action.APP_PERM_EDITOR" + intent.setClassName("com.miui.securitycenter", "com.miui.permcenter.permissions.PermissionsEditorActivity") + intent.putExtra("extra_pkgname", context.packageName) + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + if (intent.resolveActivity(context.packageManager) != null) { + activity!!.startActivity(intent) + true + } else { + // 尝试另一种MIUI方式 + val intent2 = Intent() + intent2.action = Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES + intent2.data = Uri.parse("package:${context.packageName}") + intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(intent2) + true + } + } catch (e: Exception) { + false + } + } + + private fun tryHuaweiInstallPermissionSettings(): Boolean { + return try { + // 华为/荣耀特殊处理 + val intent = Intent() + intent.action = "huawei.intent.action.HSM_BOOTUP_MANAGER" + intent.setClassName("com.huawei.systemmanager", "com.huawei.systemmanager.optimize.process.ProtectActivity") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + + if (intent.resolveActivity(context.packageManager) != null) { + activity!!.startActivity(intent) + true + } else { + // 降级到标准方式 + val intent2 = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) + intent2.data = Uri.parse("package:${context.packageName}") + intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(intent2) + true + } + } catch (e: Exception) { + false + } + } + + private fun tryOppoInstallPermissionSettings(): Boolean { + return try { + // OPPO ColorOS 特殊处理 + val intent = Intent() + intent.action = Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES + intent.data = Uri.parse("package:${context.packageName}") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(intent) + true + } catch (e: Exception) { + false + } + } + + private fun tryVivoInstallPermissionSettings(): Boolean { + return try { + // Vivo FunTouch OS 特殊处理 + val intent = Intent() + intent.action = Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES + intent.data = Uri.parse("package:${context.packageName}") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(intent) + true + } catch (e: Exception) { + false + } + } + + private fun trySamsungInstallPermissionSettings(): Boolean { + return try { + // 三星 One UI 特殊处理 + val intent = Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES) + intent.data = Uri.parse("package:${context.packageName}") + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) + activity!!.startActivity(intent) + true + } catch (e: Exception) { + false + } + } + + private fun getDeviceInfo(result: Result) { + val deviceInfo = mapOf( + "manufacturer" to Build.MANUFACTURER, + "model" to Build.MODEL, + "brand" to Build.BRAND, + "device" to Build.DEVICE, + "sdkVersion" to Build.VERSION.SDK_INT, + "release" to Build.VERSION.RELEASE, + "packageName" to context.packageName + ) + result.success(deviceInfo) + } + private fun calculateMD5(file: File): String { val digest = MessageDigest.getInstance("MD5") val inputStream = FileInputStream(file) diff --git a/lib/app_upgrade_plugin.dart b/lib/app_upgrade_plugin.dart index 0e6b871..3de08e4 100644 --- a/lib/app_upgrade_plugin.dart +++ b/lib/app_upgrade_plugin.dart @@ -83,6 +83,17 @@ class AppUpgradePlugin { return AppUpgradePluginPlatform.instance.openInstallPermissionSettings(); } + /// 获取设备信息(仅Android) + /// + /// 返回包含设备制造商、型号、Android版本等信息的Map + /// 主要用于调试和了解设备特性 + Future?> getDeviceInfo() { + if (!Platform.isAndroid) { + return Future.value(null); + } + return AppUpgradePluginPlatform.instance.getDeviceInfo(); + } + /// 获取当前App信息 Future> getAppInfo() { return AppUpgradePluginPlatform.instance.getAppInfo(); diff --git a/lib/app_upgrade_plugin_method_channel.dart b/lib/app_upgrade_plugin_method_channel.dart index 22ab7c4..03278a0 100644 --- a/lib/app_upgrade_plugin_method_channel.dart +++ b/lib/app_upgrade_plugin_method_channel.dart @@ -226,6 +226,19 @@ class MethodChannelAppUpgradePlugin extends AppUpgradePluginPlatform { } } + @override + Future?> getDeviceInfo() async { + if (!Platform.isAndroid) return null; + + try { + final result = await methodChannel.invokeMethod>('getDeviceInfo'); + return result?.cast(); + } catch (e) { + debugPrint('Failed to get device info: $e'); + return null; + } + } + @override Future> getAppInfo() async { final packageInfo = await PackageInfo.fromPlatform(); diff --git a/lib/app_upgrade_plugin_platform_interface.dart b/lib/app_upgrade_plugin_platform_interface.dart index 826bad5..825fc64 100644 --- a/lib/app_upgrade_plugin_platform_interface.dart +++ b/lib/app_upgrade_plugin_platform_interface.dart @@ -38,6 +38,11 @@ abstract class AppUpgradePluginPlatform extends PlatformInterface { throw UnimplementedError('openInstallPermissionSettings() has not been implemented.'); } + /// 获取设备信息(仅Android) + Future?> getDeviceInfo() { + throw UnimplementedError('getDeviceInfo() has not been implemented.'); + } + /// 配置HTTP设置 void configureHttp(HttpConfig config) { throw UnimplementedError('configureHttp() has not been implemented.');