如何在MAUI Android中将InCallService设为默认电话应用并实现通话控制
MAUI中基于InCallService实现来电控制方案
要在MAUI的Android平台实现来电自动接听、音频设备控制功能,核心是通过自定义InCallService子类对接系统通话服务,以下是具体实现步骤:
1. 配置AndroidManifest权限与服务声明
在MAUI项目的Platform/Android/AndroidManifest.xml中添加必要权限和服务声明:
<!-- 通话相关权限 --> <uses-permission android:name="android.permission.READ_PHONE_STATE" /> <uses-permission android:name="android.permission.ANSWER_PHONE_CALLS" /> <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" /> <uses-permission android:name="android.permission.CALL_PHONE" /> <!-- 声明InCallService服务 --> <application ...> <service android:name=".CustomInCallService" android:permission="android.permission.BIND_INCALL_SERVICE"> <intent-filter> <action android:name="android.telecom.InCallService" /> </intent-filter> </service> </application>
2. 创建自定义InCallService子类
在Platform/Android目录下新建CustomInCallService.cs,继承Android.Telecom.InCallService,重写核心方法处理通话事件:
using Android.Telecom; using Android.Media; using Android.App; namespace YourAppName.Platform.Android; [Service] public class CustomInCallService : InCallService { private AudioManager _audioManager; private Call.Callback _callCallback; public override void OnCreate() { base.OnCreate(); _audioManager = (AudioManager)GetSystemService(AudioService); _callCallback = new CallCallbackImpl(this, _audioManager); } public override void OnCallAdded(Call call) { base.OnCallAdded(call); // 设置通话回调监听 call.RegisterCallback(_callCallback); // 实现自动接听(可根据来电号码、类型等自定义判断逻辑) if (ShouldAutoAnswer(call)) { call.Answer(CallAudioState.RouteSpeaker); // 指定音频路由,如扬声器、蓝牙 } } public override void OnCallRemoved(Call call) { base.OnCallRemoved(call); call.UnregisterCallback(_callCallback); // 通话结束后恢复音频设置 _audioManager.SetSpeakerphoneOn(false); } // 自定义自动接听判断逻辑示例 private bool ShouldAutoAnswer(Call call) { // 示例:所有来电自动接听,可修改为特定号码判断 return true; } } // 自定义通话回调处理类 public class CallCallbackImpl : Call.Callback { private readonly CustomInCallService _service; private readonly AudioManager _audioManager; public CallCallbackImpl(CustomInCallService service, AudioManager audioManager) { _service = service; _audioManager = audioManager; } public override void OnStateChanged(Call call, CallState state) { base.OnStateChanged(call, state); switch (state) { case CallState.Active: // 通话接通后切换到扬声器 _audioManager.SetSpeakerphoneOn(true); break; case CallState.Disconnected: // 通话断开关闭扬声器 _audioManager.SetSpeakerphoneOn(false); break; } } }
3. 申请运行时权限
在MAUI共享代码中动态申请必要权限,确保应用获得权限后正常工作:
using Microsoft.Maui.ApplicationModel; public async Task RequestPhonePermissions() { // 申请基础电话权限 var phoneStatus = await Permissions.CheckStatusAsync<Permissions.Phone>(); if (phoneStatus != PermissionStatus.Granted) { phoneStatus = await Permissions.RequestAsync<Permissions.Phone>(); } // 申请自动接听权限(Android 10+需要) var answerCallStatus = await Permissions.CheckStatusAsync<CustomAnswerPhoneCallsPermission>(); if (answerCallStatus != PermissionStatus.Granted) { answerCallStatus = await Permissions.RequestAsync<CustomAnswerPhoneCallsPermission>(); } // 申请音频修改权限 var audioStatus = await Permissions.CheckStatusAsync<Permissions.Microphone>(); if (audioStatus != PermissionStatus.Granted) { audioStatus = await Permissions.RequestAsync<Permissions.Microphone>(); } } // 自定义权限类,对应ANSWER_PHONE_CALLS public class CustomAnswerPhoneCallsPermission : Permissions.BasePlatformPermission { public override (string androidPermission, bool isRuntime)[] RequiredPermissions => new List<(string, bool)> { ("android.permission.ANSWER_PHONE_CALLS", true) }.ToArray(); }
4. 设置为默认电话应用
InCallService仅对系统默认电话应用生效,需引导用户在系统设置中操作:
- 进入「设置」→「应用」→「默认应用」→「电话应用」
- 选择你的MAUI应用作为默认选项
关键注意事项
- Android版本限制:自动接听功能在Android 10(API 29)及以上需要
ANSWER_PHONE_CALLS权限,低版本需用无障碍服务等替代方案(兼容性较差)。 - 厂商适配:部分国产Android厂商对通话服务有额外限制,需针对性测试适配。
- 音频路由控制:使用
AudioManager切换音频设备时,需在通话状态变化时正确处理,避免音频异常。
内容的提问来源于stack exchange,提问作者Vladimir B
相关产品推荐
相关产品推荐

