代码之家  ›  专栏  ›  技术社区  ›  WorieN

Android连接服务来电

  •  2
  • WorieN  · 技术社区  · 6 年前

    我正在努力实现 iOS callkit Android上的行为。我收到来自firebase的推送通知,我想向用户显示“来电”屏幕。我用 ConnectionService android.telecom

    这是我的呼叫经理课程:

    class CallManager(context: Context) {
    val telecomManager: TelecomManager
    var phoneAccountHandle:PhoneAccountHandle
    var context:Context
    val number = "3924823202"
    init {
        telecomManager = context.getSystemService(Context.TELECOM_SERVICE) as TelecomManager
        this.context = context
        val componentName =  ComponentName(this.context, CallConnectionService::class.java)
        phoneAccountHandle = PhoneAccountHandle(componentName, "Admin")
        val phoneAccount = PhoneAccount.builder(phoneAccountHandle, "Admin").setCapabilities(PhoneAccount.CAPABILITY_SELF_MANAGED).build()
    
    
        telecomManager.registerPhoneAccount(phoneAccount)
        val intent = Intent()
        intent.component = ComponentName("com.android.server.telecom", "com.android.server.telecom.settings.EnableAccountPreferenceActivity")
        intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
    
    }
    
    
    @TargetApi(Build.VERSION_CODES.M)
    fun startOutgoingCall() {
        val extras = Bundle()
        extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
    
        val manager = context.getSystemService(TELECOM_SERVICE) as TelecomManager
        val phoneAccountHandle = PhoneAccountHandle(ComponentName(context.packageName, CallConnectionService::class.java!!.getName()), "estosConnectionServiceId")
        val test = Bundle()
        test.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
        test.putInt(TelecomManager.EXTRA_START_CALL_WITH_VIDEO_STATE, VideoProfile.STATE_BIDIRECTIONAL)
        test.putParcelable(TelecomManager.EXTRA_OUTGOING_CALL_EXTRAS, extras)
        try {
            manager.placeCall(Uri.parse("tel:$number"), test)
        } catch (e:SecurityException){
            e.printStackTrace()
        }
    }
    
    @TargetApi(Build.VERSION_CODES.M)
    fun  startIncomingCall(){
        if (this.context.checkSelfPermission(Manifest.permission.MANAGE_OWN_CALLS) == PackageManager.PERMISSION_GRANTED) {
            val extras = Bundle()
            val uri = Uri.fromParts(PhoneAccount.SCHEME_TEL, number, null)
            extras.putParcelable(TelecomManager.EXTRA_INCOMING_CALL_ADDRESS, uri)
            extras.putParcelable(TelecomManager.EXTRA_PHONE_ACCOUNT_HANDLE, phoneAccountHandle)
            extras.putBoolean(TelecomManager.EXTRA_START_CALL_WITH_SPEAKERPHONE, true)
            val isCallPermitted = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                telecomManager.isIncomingCallPermitted(phoneAccountHandle)
            } else {
               true
            }
            Log.i("CallManager", "is incoming call permited = $isCallPermitted")
            telecomManager.addNewIncomingCall(phoneAccountHandle, extras)
        }
    }
    

    }

    还有我的习惯 实施:

    class CallConnectionService : ConnectionService() {
    override fun onCreateOutgoingConnection(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?): Connection {
        Log.i("CallConnectionService", "onCreateOutgoingConnection")
        val conn = CallConnection(applicationContext)
        conn.setAddress(request!!.address, PRESENTATION_ALLOWED)
        conn.setInitializing()
        conn.videoProvider = MyVideoProvider()
        conn.setActive()
        return conn
    }
    
    override fun onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?) {
        super.onCreateOutgoingConnectionFailed(connectionManagerPhoneAccount, request)
        Log.i("CallConnectionService", "create outgoing call failed")
    }
    
    override fun onCreateIncomingConnection(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?): Connection {
        Log.i("CallConnectionService", "onCreateIncomingConnection")
        val conn = CallConnection(applicationContext)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
            conn.connectionProperties = Connection.PROPERTY_SELF_MANAGED
        }
        conn.setCallerDisplayName("test call", TelecomManager.PRESENTATION_ALLOWED)
        conn.setAddress(request!!.address, PRESENTATION_ALLOWED)
        conn.setInitializing()
        conn.videoProvider = MyVideoProvider()
        conn.setActive()
    
        return conn
    }
    
    override fun onCreateIncomingConnectionFailed(connectionManagerPhoneAccount: PhoneAccountHandle?, request: ConnectionRequest?) {
        super.onCreateIncomingConnectionFailed(connectionManagerPhoneAccount, request)
        Log.i("CallConnectionService", "create outgoing call failed ")
    }
    

    我的连接实现是这样的:

        class CallConnection(ctx:Context) : Connection() {
    
        var ctx:Context = ctx
        val TAG = "CallConnection"
    
        override fun onShowIncomingCallUi() {
    //        super.onShowIncomingCallUi()
            Log.i(TAG, "onShowIncomingCallUi")
            val intent = Intent(Intent.ACTION_MAIN, null)
            intent.flags = Intent.FLAG_ACTIVITY_NO_USER_ACTION or Intent.FLAG_ACTIVITY_NEW_TASK
            intent.setClass(ctx, IncomingCallActivity::class.java!!)
            val pendingIntent = PendingIntent.getActivity(ctx, 1, intent, 0)
            val builder = Notification.Builder(ctx)
            builder.setOngoing(true)
            builder.setPriority(Notification.PRIORITY_HIGH)
    
            // Set notification content intent to take user to fullscreen UI if user taps on the
            // notification body.
            builder.setContentIntent(pendingIntent)
            // Set full screen intent to trigger display of the fullscreen UI when the notification
            // manager deems it appropriate.
            builder.setFullScreenIntent(pendingIntent, true)
    
            // Setup notification content.
            builder.setSmallIcon(R.mipmap.ic_launcher)
            builder.setContentTitle("Your notification title")
            builder.setContentText("Your notification content.")
    
            // Use builder.addAction(..) to add buttons to answer or reject the call.
    
            val notificationManager = ctx.getSystemService(
                    NotificationManager::class.java)
    
            notificationManager.notify("Call Notification", 37, builder.build())
        }
    
        override fun onCallAudioStateChanged(state: CallAudioState?) {
            Log.i(TAG, "onCallAudioStateChanged")
        }
    
        override fun onAnswer() {
            Log.i(TAG, "onAnswer")
        }
    
        override fun onDisconnect() {
            Log.i(TAG, "onDisconnect")
        }
    
        override fun onHold() {
            Log.i(TAG, "onHold")
        }
    
        override fun onUnhold() {
            Log.i(TAG, "onUnhold")
        }
    
        override fun onReject() {
            Log.i(TAG, "onReject")
        }
    }
    

    根据文档向用户显示传入的calcustomon UI-我应该在中做一些操作 onShowIncomingCallUi()

    我该怎么修?

    1 回复  |  直到 6 年前
        1
  •  5
  •   TALE    6 年前

    我能够让它工作使用一个测试应用程序和Android派上运行的像素2XL。

    通过我的测试,重要的部分是确保:

    • 那个Connection.PROPERTY\自我管理在连接上设置。至少需要API 26。
    • 你必须注册你的电话帐户。
    • 你必须把PhoneAccount.CAPABILITY\自我管理在您的能力注册的电话帐户。这是我唯一设定的能力。设置其他功能导致它抛出异常。
    • 最后,您需要确保在中设置了这两个权限AndroidManifest.xml文件. android.permission.MANAGE\u OWN\u呼叫以及android.permission.READ\ CALL\日志

    因此,我将检查您的清单,以确保您拥有权限,并确保功能设置正确。看起来上面的代码中其他所有内容都设置正确。

    希望有帮助!