簡體   English   中英

Android SIP 呼叫響鈴然后得到 ENETUNREACH(網絡不可達)

[英]Android SIP call rings then gets ENETUNREACH (Network is unreachable)

我正在嘗試使用android.net.sip.SipManager將出站 SIP 呼叫添加到 Android 應用程序中,我接到了onRingBack的電話,但是當對方接聽電話時,我接到了onError的電話,代碼為 -4 和消息android.system.ErrnoException: sendto failed: ENETUNREACH (Network is unreachable)

我懷疑這是某種防火牆或網絡問題,因為根據我使用的網絡,我在過程中的不同點會收到 ENETUNREACH 錯誤。 啟用我的 VPN 后,我會在onRingBack回調之前得到它。 使用公共 WiFi 網絡,我根本不會收到onError回調,我只是在onRingBack之后沒有收到回調。 通過我的個人 WiFi 網絡,我得到了如上所述的onError 然而不知何故,LinPhoneAndroid 應用程序沒有這個問題,所以必須有一種方法來解決這個問題。

對於我的測試設置,我在 linphone.org 創建了兩個帳戶:

  • sip:[myphonenumber]@sip.linphone.org // iPhone
  • sip:[myusername]@sip.linphone.org // Android

I use the first account with the LinPhone iOS app on my iPhone 11. I use the second account with the LinPhone Android app on my Google Pixel 4a with Android 12. I verified I can successfully make calls from Android to iOS using these LinPhone apps.

然后我在 Android 上編寫了自己的應用程序來調用 iPhone。 它成功地向 SIP 服務器注冊:

            sipProfile = SipProfile.Builder(username, domain).setPassword(password).build()
            val intent = Intent()
            intent.action = "android.SipDemo.INCOMING_CALL"
            val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, Intent.FILL_IN_DATA)
            sipManager.open(sipProfile, pendingIntent, null)
            sipManager.setRegistrationListener(sipProfile.uriString, object: SipRegistrationListener {
                override fun onRegistering(localProfileUri: String?) {
                    Log.d(TAG, "Registering")
                }

                override fun onRegistrationDone(localProfileUri: String?, expiryTime: Long) {
                    registrationExpiration = Date(expiryTime)
                    ...
                    Log.d(TAG, "Registration done.  LocalProfileUri: $localProfileUri Expiry Time: ${registrationExpiration}")
                }

                override fun onRegistrationFailed(
                    localProfileUri: String?,
                    errorCode: Int,
                    errorMessage: String?
                ) {
                    Log.d(TAG, "Registration failed.  LocalProfileUri: $localProfileUri,  Error code: $errorCode, Error MessagE: $errorMessage")
                }

            })

然后,我可以使用sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, audioCallListener, 30)向 iPhone 發起出站呼叫,iPhone 實際響鈴並且可以接聽啟動 LinPhone iOS 應用程序的呼叫並顯示正在進行的呼叫計時器。 **當 iPhone 開始響鈴時,我的 Android 代碼會回調到onRingingBack 但是當 iPhone 接聽電話時,它會使用代碼 -4 調用onError並且發送消息sendto failed: ENETUNREACH (Network is unreachable)

以下是啟動調用並實現回調的完整代碼:

        audioCallListener = object: SipAudioCall.Listener() {
            public override fun onError(
                call: SipAudioCall?,
                errorCode: Int,
                errorMessage: String?
            ) {
                super.onError(call, errorCode, errorMessage)
                Log.d(TAG, "Error making call code: $errorCode, message: $errorMessage")

            }

            public override fun onReadyToCall(call: SipAudioCall?) {
                Log.d(TAG, "ready to call")
                super.onReadyToCall(call)
            }

            public override fun onRingingBack(call: SipAudioCall?) {
                Log.d(TAG, "onRingingBack")
                super.onRingingBack(call)
            }

            public override fun onCalling(call: SipAudioCall?) {
                Log.d(TAG, "onCalling")
                super.onCalling(call)
            }

            public override fun onCallHeld(call: SipAudioCall?) {
                Log.d(TAG, "onCallHeld")
                super.onCallHeld(call)
            }

            public override fun onCallBusy(call: SipAudioCall?) {
                Log.d(TAG, "onCallBusy")
                super.onCallBusy(call)
            }

            public override fun onChanged(call: SipAudioCall?) {
                val state = call?.state ?: -1
                Log.d(TAG, "onChanged state: ${state}")
                super.onChanged(call)
            }
            public override fun onRinging(call: SipAudioCall?, caller: SipProfile?) {
                Log.d(TAG, "Ringing...")
                super.onRinging(call, caller)
            }
            public override fun onCallEstablished(call: SipAudioCall) {
                mediaPlayer?.stop()
                call.startAudio()
                call.setSpeakerMode(true)
                call.toggleMute()
                Log.d(TAG, "Calls started")
                super.onCallEstablished(call)
            }

            public override fun onCallEnded(call: SipAudioCall) {
                Log.d(TAG, "Call ended")
                super.onCallEnded(call)
            }
        }
        GlobalScope.launch {
                Log.d(TAG, "Making call from ${sipProfile.getUriString()} to ${sipAddress}")
                try {
                    lastCall = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, audioCallListener, 30);
                }
                catch (e: SipException) {
                    Log.e(TAG, "Call failed", e)
                }
        }

不幸的是,答案是放棄使用這些 API。 谷歌有:

此接口在 API 級別 31 中已棄用。不再支持 SipManager 和相關類,不應將其用作未來 VOIP 應用程序的基礎。

這里

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM