Flutter开发中如何获取call account权限并检测用户授权状态
Flutter callkeep库Call Account权限检测实现方案
前置说明
callkeep库本身未封装Call Account权限的检测逻辑,该权限为Android平台特有,需自行结合原生层能力+Flutter MethodChannel实现,iOS端对应VoIP权限可直接通过permission_handler检测。
实现步骤
1. Android端基础配置
先在AndroidManifest.xml中添加必要权限和服务声明:
<!-- 通话账户相关权限 --> <uses-permission android:name="android.permission.BIND_TELECOM_CONNECTION_SERVICE" /> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.READ_CALL_LOG" /> <!-- 注册CallKeep对应的ConnectionService --> <service android:name="io.flutter.plugins.callkeep.CallKeepConnectionService" android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE"> <intent-filter> <action android:name="android.telecom.ConnectionService" /> </intent-filter> </service>
2. Android端原生逻辑封装
在安卓主Activity中注册MethodChannel,实现权限检测和跳转设置的方法:
// 注册MethodChannel private val CHANNEL = "com.yourapp/call_permission" override fun configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL).setMethodCallHandler { call, result -> when (call.method) { "checkCallAccount" -> result.success(hasValidCallAccount()) "openCallAccountSetting" -> { openCallAccountSetting() result.success(true) } else -> result.notImplemented() } } } // 检测是否存在有效的CallAccount private fun hasValidCallAccount(): Boolean { val telecomManager = getSystemService(Context.TELECOM_SERVICE) as TelecomManager val callAccounts = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { telecomManager.callAccounts } else { return true // 6.0以下系统无需单独申请该权限 } val myComponent = ComponentName(packageName, "io.flutter.plugins.callkeep.CallKeepConnectionService") return callAccounts.any { it.accountHandle.componentName == myComponent && it.isEnabled } } // 跳转通话账户设置页 private fun openCallAccountSetting() { val intent = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { Intent(TelecomManager.ACTION_CHANGE_PHONE_ACCOUNTS) } else { Intent("android.settings.CALL_SETTINGS") } startActivity(intent) }
3. Flutter侧调用封装
封装方法对齐permission_handler的使用习惯:
import 'package:flutter/services.dart'; import 'package:permission_handler/permission_handler.dart'; class CallAccountPermission { static const _channel = MethodChannel('com.yourapp/call_permission'); /// 检测是否已授予Call Account权限 static Future<bool> check() async { if (Platform.isAndroid) { try { return await _channel.invokeMethod<bool>('checkCallAccount') ?? false; } catch (e) { return false; } } // iOS端直接检测VoIP权限即可 return await Permission.voip.isGranted; } /// 跳转系统设置页开启权限 static Future<void> openSetting() async { if (Platform.isAndroid) { try { await _channel.invokeMethod('openCallAccountSetting'); } catch (e) { // 异常处理逻辑 } } else { await openAppSettings(); } } }
注意事项
- 需先完成callkeep的初始化配置,再调用权限检测方法,否则未完成Call Account注册会导致检测结果异常
- 部分国产Android定制系统存在额外权限限制,若开启Call Account后仍无法展示通话通知,需引导用户开启应用的自启动、后台弹出界面、悬浮窗等厂商定制权限
- 检测到权限未授予时,建议先弹出自定义提示框告知用户权限用途,用户确认后再跳转系统设置页
内容的提问来源于stack exchange,提问作者Benyamin Beyzaie
相关产品推荐
相关产品推荐

