[英]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 創建了兩個帳戶:
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)
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.