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

Android自定义原生拨号器ConnectionService实现:外呼无法接通求助

自定义拨号器呼叫无法接通问题排查

正在基于ConnectionService、Connection实现自定义原生拨号器,注册PhoneAccount用于外呼,目前已能通过自定义PhoneAccount发起呼叫,但呼叫始终无法接通至目标号码,请求协助排查。

PhoneAccount注册代码

@RequiresApi(api = Build.VERSION_CODES.M)
private void registerConnectionService() {
    try {
        TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
        String connectionServiceId = getConnectionServiceId();
        ComponentName componentName = new ComponentName(getApplicationContext(), MyService.class);
        PhoneAccountHandle phoneAccountHandle = new PhoneAccountHandle(componentName, "Dialer");
        phoneAccount = manager.getPhoneAccount(phoneAccountHandle);
        // Log.i("phoneAccountTekV",phoneAccount.getAddress()+" "+phoneAccount.getCapabilities()+"  "+phoneAccount.getLabel());
        if (phoneAccount == null) { // no phone account from us registered yet
            PhoneAccount.Builder builder = PhoneAccount.builder(phoneAccountHandle, "Dialer");
            Uri uri = Uri.parse("tel:123456789");
            //builder.setSubscriptionAddress(uri);
            //builder.setAddress(uri);
            builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER);
           
            phoneAccount = builder.build();
            manager.registerPhoneAccount(phoneAccount);
            Log.i("phoneAccount", "" + phoneAccount.isEnabled());
            Intent intent = new Intent();
            intent.setComponent(new ComponentName("com.android.server.telecom",
                    "com.android.server.telecom.settings.EnableAccountPreferenceActivity"));
            startActivity(intent);
        }
        Log.i("is phoneAccountEnabled", "" + phoneAccount.isEnabled());
    } catch (SecurityException se) {
        Log.e("registerPhoneAccount", "SecurityException: Ensure all necessary permissions are granted", se);
    } catch (IllegalArgumentException iae) {
        Log.e("registerPhoneAccount", "IllegalArgumentException: Ensure the PhoneAccount is properly configured", iae);
    } catch (RuntimeException re) {
        Log.e("registerPhoneAccount", "RuntimeException: An unexpected error occurred", re);
    } catch (Exception re) {
        Log.e("registerPhoneAccount", "Exception: An unexpected error occurred", re);
    }
}

ConnectionService实现代码

@RequiresApi(api = Build.VERSION_CODES.Q)
@RequiresPermission(value = "android.permission.READ_PHONE_STATE")
@Override
public Connection onCreateOutgoingConnection(PhoneAccountHandle connectionManagerPhoneAccount, ConnectionRequest originalRequest) {
    Uri handle = originalRequest.getAddress();
    MyConnection connection = new MyConnection(false, originalRequest,this);
    connection.setAddress(handle, TelecomManager.PRESENTATION_ALLOWED);
    //connection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED);
   // connection.setDialing();
    connection.setInitializing();
    connection.setConnectionCapabilities(Connection.CAPABILITY_HOLD | Connection.CAPABILITY_MUTE | Connection.CAPABILITY_SUPPORT_HOLD);
    connection.setVideoState(originalRequest.getVideoState());
    addCall(connection);
    TelecomManager manager = (TelecomManager) getSystemService(Context.TELECOM_SERVICE);
    boolean isOut = manager.isOutgoingCallPermitted(connectionManagerPhoneAccount);
    Log.i("phoneAccountTekV",connectionManagerPhoneAccount.getUserHandle().toString());
            //setAddress(connection,handle);
    Log.i("isOutgoingCallPermitted"," isOutgoingCallPermitted-"+isOut);
    PhoneAccountHandle ph = manager.getUserSelectedOutgoingPhoneAccount();
    List<PhoneAccountHandle>  selfHandles =manager.getSelfManagedPhoneAccounts();
    List<PhoneAccountHandle>  handles =manager.getCallCapablePhoneAccounts();
    connection.startOutgoing();
    return connection;
}

LogCat日志

12:27:49.085 1563-1563/? W/Telecom: **Call: maybeOnInCallServiceTrackingChanged() request on a call without a connection service.: ICSBC.oSC(cgag)@C/U**
2024-06-24 12:27:49.085 1563-1563/? W/Telecom: **Call: maybeOnInCallServiceTrackingChanged() request on a call without a connection service.: ICSBC.oSC(cgaa)@C/Y**
2024-06-24 12:27:49.091 1563-6781/? W/WindowManager: Prepare app transition: mNextAppTransitionRequests=[TRANSIT_OPEN, TRANSIT_OPEN], mNextAppTransitionFlags=, displayId: 0 Callers=com.android.server.wm.DisplayContent.prepareAppTransition:6493 com.android.server.wm.TaskFragment.resumeTopActivity:1573 com.android.server.wm.TaskFragment.resumeTopActivity:1307 com.android.server.wm.Task.resumeTopActivityInnerLocked:6451 com.android.server.wm.Task.resumeTopActivityUncheckedLocked:6352
2024-06-24 12:27:49.091 1563-6781/? W/ActivityTaskManager: Tried to set launchTime (0) < mLastActivityLaunchTime (1105139)
2024-06-24 12:27:49.096 1563-1563/? W/Telecom: **Call: maybeOnInCallServiceTrackingChanged() request on a call without a connection service.: TSI.pC->CM.fOCP->CM.sOCPA->CM.dSMCP->CM.dSPA->CM.sRCQ->CM.pASP(ctd)@C/M**
2024-06-24 12:27:49.096 1563-1563/? W/Telecom: **Call: maybeOnInCallServiceTrackingChanged() request on a call without a connection service.: TSI.pC->CM.fOCP->CM.sOCPA->CM.dSMCP->CM.dSPA->CM.sRCQ->CM.pASP(ctd)@C/M**
2024-06-24 12:27:49.097 1563-6781/? W/WindowManager: Execute app transition: mNextAppTransitionRequests=[TRANSIT_OPEN, TRANSIT_OPEN], mNextAppTransitionFlags=, displayId: 0 Callers=com.android.server.wm.RootWindowContainer.executeAppTransitionForAllDisplay:2580 com.android.server.wm.ActivityTaskSupervisor.reportResumedActivityLocked:2287 com.android.server.wm.ActivityRecord.completeResumeLocked:6987 com.android.server.wm.Task.minimalResumeActivityLocked:6156 com.android.server.wm.ActivityTaskSupervisor.realStartActivityLocked:1137
2024-06-24 12:27:49.098 1563-1563/? W/Telecom: **Call: maybeOnInCallServiceTrackingChanged() request on a call without a connection service.: TSI.pC->CM.fOCP->CM.sOCPA->CM.dSMCP->CM.dSPA->CM.sRCQ->CM.pASP(ctd)@C/M**
2024-06-24 12:27:49.099 1224-1461/? W/SecAudioParamPolicy: g_volume_situation_key: did not support legacy situation volumes
2024-06-24 12:27:49.099 32494-32494/? E/m.samsung.crane: Not starting debugger since process cannot load the jdwp agent.
2024-06-24 12:27:49.102 9896-9925/? E/BluetoothAdapterService: getActiveDevices: HearingAidService is null
2024-06-24 12:27:49.107 1563-1563/? W/Telecom: Logging: Log.endSession was called with no session active.
2024-06-24 12:27:49.110 9896-9925/? E/BluetoothAdapterService: getActiveDevices: HearingAidService is null
**W/ContextImpl: Calling a method in the system process without a qualified user: android.app.ContextImpl.sendBroadcast:1252 com.android.server.notification.sec.DisplayToast.sendIntentForToastDumpLog:156 com.android.server.notification.sec.DisplayToast.outFile:106 com.android.server.notification.sec.DisplayToast.out:62 com.android.server.notification.NotificationManagerService$12.enqueueToastForDex:3989**
2024-06-24 12:27:49.507 5214-5307/? W/Parcel: Expecting binder but got null!
2024-06-24 12:27:49.513 677-677/? W/keymaster_tee: [WRN]begin req PARAMS: A32 B32 P1
2024-06-24 12:27:49.521 677-677/? W/keymaster_tee: [WRN]begin req PARAMS: A32 B32 P1
2024-06-24 12:27:49.529 1121-1121/? E/Sensors: inject_scontext_data: New ssp_data_injection_fd(44)
2024-06-24 12:27:49.530 1563-1718/? W/BroadcastQueue: Background execution not allowed: receiving Intent { act=com.samsung.rcs.contentsharing.action.NUMBER_TOKEN flg=0x10 (has extras) } to com.samsung.crane/.app.PhoneNumberReceiver
2024-06-24 12:27:49.536 1563-1718/? W/BroadcastQueue: Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x1000010 (has extras) } to ProcessRecord{b77a6ce 6726:com.samsung.android.app.cocktailbarservice/u0a52} (pid=6726, uid=10052) requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
2024-06-24 12:27:49.537 1563-1718/? W/BroadcastQueue: Permission Denial: receiving Intent { act=android.intent.action.PHONE_STATE flg=0x1000010 (has extras) } to ProcessRecord{b77a6ce 6726:com.samsung.android.app.cocktailbarservice/u0a52} (pid=6726, uid=10052) requires android.permission.READ_PHONE_STATE due to sender android (uid 1000)
2024-06-24 12:27:49.537 9896-18745/? E/BluetoothAdapterService: getActiveDevices: HearingAidService is null

排查关键点

  • 核心日志警告分析:Call: maybeOnInCallServiceTrackingChanged() request on a call without a connection service 说明Telecom系统未识别到呼叫关联的有效ConnectionService,需检查Connection状态流转和服务配置。
  • PhoneAccount配置修正:
    • 注册时添加PhoneAccount.CAPABILITY_SELF_MANAGED权限,确保系统将通话控制权交给自定义服务:builder.setCapabilities(PhoneAccount.CAPABILITY_CALL_PROVIDER | PhoneAccount.CAPABILITY_SELF_MANAGED)
    • 取消注释builder.setSubscriptionAddress(uri)或builder.setAddress(uri),为PhoneAccount设置有效地址标识,部分系统依赖该字段验证账户合法性。
  • Connection状态与属性修正:
    • 取消注释connection.setConnectionProperties(Connection.PROPERTY_SELF_MANAGED),明确标记为自管理通话。
    • 补充状态流转逻辑:创建Connection后调用connection.setDialing()标记拨号中,待实际通话接通后调用connection.setConnected(),系统需要明确状态更新才能正确处理通话。
  • Manifest与权限检查:
    • 确保ConnectionService在Manifest中正确注册并绑定权限:
      <service
          android:name=".MyService"
          android:permission="android.permission.BIND_CONNECTION_SERVICE">
          <intent-filter>
              <action android:name="android.telecom.ConnectionService" />
          </intent-filter>
      </service>
      
    • 确认已授予READ_PHONE_STATE、CALL_PHONE等必要动态权限(Android 6.0+)。
  • 补充通话发起逻辑:onCreateOutgoingConnection仅创建了Connection对象,需在MyConnection内部实现实际的呼叫建立逻辑(如SIP、VoIP调用),并在逻辑完成后更新Connection状态。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 22:34:52