由于 org.webrtc.PeerConnection.setRemoteDescription 空指针异常,无法接受 QuickBlox RTC 调用

Unable to accept QuickBlox RTC Call due to org.webrtc.PeerConnection.setRemoteDescription null pointer exception

我无法接受 QuickBlox RTC 呼叫。

这是异常日志:

02-25 16:46:18.080 9035-9240/com.myapp.chat E/AndroidRuntime: FATAL EXCEPTION: Thread-10031
    Process: com.myapp.chat, PID: 9035
    java.lang.NullPointerException: Attempt to invoke virtual method 'void org.webrtc.PeerConnection.setRemoteDescription(org.webrtc.SdpObserver, org.webrtc.SessionDescription)' on a null object reference
    at com.quickblox.videochat.webrtc.QBPeerChannel.run(QBPeerChannel.java:245)
    at android.os.Handler.handleCallback(Handler.java:739)
    at android.os.Handler.dispatchMessage(Handler.java:95)
    at android.os.Looper.loop(Looper.java:211)

这是我的呼叫接受代码:

            Integer myId = QBChatService.getInstance().getUser().getId();
            ArrayList<Integer> opponentsWithoutMe = new ArrayList<>(this.currentSession.getOpponents());

            opponentsWithoutMe.remove(new Integer(myId));
            opponentsWithoutMe.add(this.currentSession.getCallerID());
            List<QBUser> qbUserList = new ArrayList<>();
            for (int opponentId : opponentsWithoutMe) {
                qbUserList.add(new QBUser(opponentId));
            }

            SettingsUtil.setSettingsStrategy(qbUserList, PreferenceManager.getDefaultSharedPreferences(mContext), this);

            Intent intent = new Intent(mContext, QuickBloxCallActivity.class);
            intent.putExtra(Keys.QB_CONFERENCE_CALL_TYPE, this.currentSession.getConferenceType().getValue());
            intent.putExtra(Keys.QB_CALL_OPPONENT_NAME, getString(R.string.qb_dafault_opponent_name));
            intent.putExtra(Keys.QB_CALL_OPPONENT, this.currentSession.getOpponents().get(0));
            intent.putExtra(Keys.QB_START_CALL_ACTIVITY_REASON, QuickBloxCallActivity.StartCallActivityReason.INCOMING_CALL.ordinal());

            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            startActivity(intent);

            Map<String, String> userInfo = new HashMap<>();
            userInfo.put("key", "value");

            this.currentSession.acceptCall(userInfo);

与SDK中提供的示例不同,我尝试在Service中实现它。上面的代码写在一个Service中,通过GreenRobot的EventBus触发。

这是我的通话代码:

QBRTCSession session = QBRTCClient.getInstance(mContext).createNewSessionWithOpponents(
                        opponentIdList, event.getQbConferenceType());

                SettingsUtil.setSettingsFromPreferences(PreferenceManager.getDefaultSharedPreferences(mContext), this);
                initCurrentSession(session);

                ringtonePlayer.play(true);

                Intent intent = new Intent(mContext, QuickBloxCallActivity.class);
                intent.putExtra(Keys.QB_CONFERENCE_CALL_TYPE, session.getConferenceType().getValue());
                intent.putExtra(Keys.QB_CALL_OPPONENT_NAME, getString(R.string.qb_dafault_opponent_name));
                intent.putExtra(Keys.QB_CALL_OPPONENT, session.getOpponents().get(0));
                intent.putExtra(Keys.QB_START_CALL_ACTIVITY_REASON, QuickBloxCallActivity.StartCallActivityReason.OUTGOING_CALL.ordinal());

                intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(intent);

                Map<String, String> userInfo = new HashMap<>();
                userInfo.put(Keys.QB_USER_INFO_MAP_CALLER_NAME, event.getCallerName());

                this.currentSession.startCall(userInfo);

这是完整的错误日志:

02-25 16:46:17.167 9035-9146/com.myapp.chat D/RTCClient.:  Added 

session CALLBACK listenercom.myapp.chat.service.MyService@1523fc25
02-25 16:46:18.033 9035-9232/com.myapp.chat D/RTCClient.: New signalling was added for participant10182814
02-25 16:46:18.036 9035-9232/com.myapp.chat D/QBASDK: Receive Video signal ' accept', from User: 10182814, sessionId: 9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.044 9035-9232/com.myapp.chat D/RTCClient.: onReceiveAcceptFromUser 10182814
02-25 16:46:18.044 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.044 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10026 for QBRTCClient
02-25 16:46:18.046 9035-9219/com.myapp.chat D/RTCClient.: createSessionWithDescriptionQBRTCSessionDescription{sessionID='9bc25a69-8e1d-4508-8caa-bb6bda8228cf', callerID='10182806', opponents=[10182814], conferenceType=QBConferenceType{value='2'}, userInfo={key=value}}
02-25 16:46:18.048 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Create looper executor on thread: 10026 for PeerFactoryManager
02-25 16:46:18.048 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper start. On PeerFactoryManager
02-25 16:46:18.051 9035-9238/com.myapp.chat D/RTCClient.LooperExecutor: Looper thread started.
02-25 16:46:18.051 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.051 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10029 for PeerFactoryManager
02-25 16:46:18.051 9035-9219/com.myapp.chat D/RTCClient.QBRTCSession: Create new session
02-25 16:46:18.053 9035-9219/com.myapp.chat D/RTCClient.: New signalling was added for participant10182814
02-25 16:46:18.059 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Create looper executor on thread: 10026 for QBPeerChannel
02-25 16:46:18.060 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper start. On QBPeerChannel
02-25 16:46:18.069 9035-9240/com.myapp.chat D/RTCClient.LooperExecutor: Looper thread started.
02-25 16:46:18.069 9035-9219/com.myapp.chat D/RTCClient.QBRTCSession: Make new channel for oppoennt:10182814com.quickblox.videochat.webrtc.QBPeerChannel@4679156
02-25 16:46:18.070 9035-9219/com.myapp.chat D/RTCClient.QBRTCSession: Process accept from 10182814
02-25 16:46:18.070 9035-9219/com.myapp.chat D/RTCClient.QBPeerChannel: setRemoteSDPToConnection
02-25 16:46:18.070 9035-9219/com.myapp.chat D/RTCClient.QBPeerChannel.PeerChannelLifeCycleTimers: Stop DialingTimer
02-25 16:46:18.071 9035-9219/com.myapp.chat D/RTCClient.RTCMediaUtils: generateRemoteDescription:  audioCodec=ISAC
02-25 16:46:18.071 9035-9219/com.myapp.chat W/RTCClient.RTCMediaUtils: No m=audio  line, so can't prefer ISAC
02-25 16:46:18.071 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.071 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10031 for QBPeerChannel
02-25 16:46:18.071 9035-9219/com.myapp.chat D/SessionClosedListener: onCallAcceptByUser
02-25 16:46:18.071 9035-9219/com.myapp.chat D/MyService: onCallAcceptByUser. QBRTCSession ID: 9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.078 9035-9238/com.myapp.chat D/EglBase: SDK version: 22
02-25 16:46:18.080 9035-9240/com.myapp.chat E/AndroidRuntime: FATAL EXCEPTION: Thread-10031
                                                                      Process: com.myapp.chat, PID: 9035
                                                                      java.lang.NullPointerException: Attempt to invoke virtual method 'void org.webrtc.PeerConnection.setRemoteDescription(org.webrtc.SdpObserver, org.webrtc.SessionDescription)' on a null object reference
                                                                          at com.quickblox.videochat.webrtc.QBPeerChannel.run(QBPeerChannel.java:245)
                                                                          at android.os.Handler.handleCallback(Handler.java:739)
                                                                          at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                          at android.os.Looper.loop(Looper.java:211)
                                                                          at com.quickblox.videochat.webrtc.LooperExecutor.run(LooperExecutor.java:73)
02-25 16:46:18.080 9035-9238/com.myapp.chat D/*WEBRTCN*: SetRenderAndroidVM
02-25 16:46:18.080 9035-9238/com.myapp.chat D/JVM: JVM::Initialize@[tid=9238]
02-25 16:46:18.080 9035-9238/com.myapp.chat D/JVM: JVM::JVM@[tid=9238]
02-25 16:46:18.081 9035-9238/com.myapp.chat D/MediaCodecVideo: SetAndroidObjects for surface decoding.
02-25 16:46:18.081 9035-9238/com.myapp.chat D/MediaCodecVideo: NULL VideoDecoder EGL context - HW surface decoding is disabled.
02-25 16:46:18.088 9035-9241/com.myapp.chat D/JVM: AttachCurrentThreadIfNeeded::ctor@[tid=9241]
02-25 16:46:18.088 9035-9241/com.myapp.chat D/JVM: Attaching thread to JVM
02-25 16:46:18.089 9035-9241/com.myapp.chat D/JVM: JVM::environment@[tid=9241]
02-25 16:46:18.089 9035-9241/com.myapp.chat D/JVM: JNIEnvironment::ctor@[tid=9241]
02-25 16:46:18.089 9035-9241/com.myapp.chat D/AudioManager: ctor@[tid=9241]
02-25 16:46:18.089 9035-9241/com.myapp.chat D/JVM: JNIEnvironment::RegisterNatives(org/webrtc/voiceengine/WebRtcAudioManager)
02-25 16:46:18.089 9035-9241/com.myapp.chat D/JVM: NativeRegistration::ctor@[tid=9241]
02-25 16:46:18.089 9035-9241/com.myapp.chat D/JVM: NativeRegistration::NewObject@[tid=9241]
02-25 16:46:18.090 9035-9241/com.myapp.chat D/WebRtcAudioManager: ctor@[name=Thread-10032, id=10032]
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: OnCacheAudioParameters@[tid=9241]
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: hardware_aec: 1
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: low_latency_output: 0
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: sample_rate: 48000
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: channels: 1
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: output_buffer_size: 3840
02-25 16:46:18.095 9035-9241/com.myapp.chat D/AudioManager: input_buffer_size: 1920
02-25 16:46:18.095 9035-9241/com.myapp.chat D/JVM: GlobalRef::ctor@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/AudioManager: JavaAudioManager::ctor@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/AudioManager: IsLowLatencyPlayoutSupported()
02-25 16:46:18.096 9035-9241/com.myapp.chat D/JVM: AttachCurrentThreadIfNeeded::ctor@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/JVM: JVM::environment@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/JVM: JNIEnvironment::ctor@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/AudioTrackJni: ctor@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/JVM: JNIEnvironment::RegisterNatives(org/webrtc/voiceengine/WebRtcAudioTrack)
02-25 16:46:18.096 9035-9241/com.myapp.chat D/JVM: NativeRegistration::ctor@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/JVM: NativeRegistration::NewObject@[tid=9241]
02-25 16:46:18.096 9035-9241/com.myapp.chat D/WebRtcAudioTrack: ctor@[name=Thread-10032, id=10032]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/WebRtcAudioTrack: Android SDK: 22, Release: 5.1.1, Brand: Sony, Device: D5833, Id: 23.4.A.1.232, Hardware: qcom, Manufacturer: Sony, Model: D5833, Product: D5833
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: GlobalRef::ctor@[tid=9241]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: AttachCurrentThreadIfNeeded::ctor@[tid=9241]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: JVM::environment@[tid=9241]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: JNIEnvironment::ctor@[tid=9241]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/AudioRecordJni: ctor@[tid=9241]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: JNIEnvironment::RegisterNatives(org/webrtc/voiceengine/WebRtcAudioRecord)
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: NativeRegistration::ctor@[tid=9241]
02-25 16:46:18.099 9035-9241/com.myapp.chat D/JVM: NativeRegistration::NewObject@[tid=9241]
02-25 16:46:18.100 9035-9241/com.myapp.chat D/WebRtcAudioRecord: ctor@[name=Thread-10032, id=10032]
02-25 16:46:18.100 9035-9241/com.myapp.chat D/JVM: GlobalRef::ctor@[tid=9241]
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioManager: SetActiveAudioLayer(5)@[tid=9241]
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioManager: delay_estimate_in_milliseconds: 150
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioTrackJni: AttachAudioBuffer@[tid=9241]
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioTrackJni: SetPlayoutSampleRate(48000)
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioTrackJni: SetPlayoutChannels(1)
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioRecordJni: AttachAudioBuffer
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioRecordJni: SetRecordingSampleRate(48000)
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioRecordJni: SetRecordingChannels(1)
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioRecordJni: total_delay_in_milliseconds: 150
02-25 16:46:18.101 9035-9241/com.myapp.chat D/AudioManager: Init@[tid=9241]
02-25 16:46:18.101 9035-9241/com.myapp.chat D/WebRtcAudioManager: init@[name=Thread-10032, id=10032]
02-25 16:46:18.104 9035-9241/com.myapp.chat D/WebRtcAudioManager: audio mode is: MODE_NORMAL
02-25 16:46:18.104 9035-9241/com.myapp.chat D/AudioRecordJni: EnableBuiltInAEC@[tid=9241]
02-25 16:46:18.104 9035-9241/com.myapp.chat D/WebRtcAudioRecord: EnableBuiltInAEC(true)
02-25 16:46:18.109 9035-9241/com.myapp.chat D/AudioRecordJni: EnableBuiltInAEC@[tid=9241]
02-25 16:46:18.109 9035-9241/com.myapp.chat D/WebRtcAudioRecord: EnableBuiltInAEC(true)
02-25 16:46:18.113 9035-9238/com.myapp.chat D/RTCClient.PeerFactoryManager: Peer connection factory initiated from thread10029
02-25 16:46:18.148 9035-9232/com.myapp.chat D/QBASDK: Receive Video signal ' iceCandidates', from User: 10182814, sessionId: 9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.148 9035-9232/com.myapp.chat D/RTCClient.: onReceiveIceCandidatesFromUser 10182814, session=9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.148 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.148 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10026 for QBRTCClient
02-25 16:46:18.149 9035-9219/com.myapp.chat D/RTCClient.QBRTCSession: process ice candidates from 10182814
02-25 16:46:18.149 9035-9219/com.myapp.chat D/RTCClient.QBPeerChannel: Set iceCandidates in count of: 1
02-25 16:46:18.149 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.149 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10031 for QBPeerChannel
02-25 16:46:18.376 9035-9232/com.myapp.chat D/QBASDK: Receive Video signal ' iceCandidates', from User: 10182814, sessionId: 9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.376 9035-9232/com.myapp.chat D/RTCClient.: onReceiveIceCandidatesFromUser 10182814, session=9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.376 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.376 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10026 for QBRTCClient
02-25 16:46:18.378 9035-9219/com.myapp.chat D/RTCClient.QBRTCSession: process ice candidates from 10182814
02-25 16:46:18.378 9035-9219/com.myapp.chat D/RTCClient.QBPeerChannel: Set iceCandidates in count of: 1
02-25 16:46:18.378 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.378 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10031 for QBPeerChannel
02-25 16:46:18.464 9035-9232/com.myapp.chat D/QBASDK: Receive Video signal ' iceCandidates', from User: 10182814, sessionId: 9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.464 9035-9232/com.myapp.chat D/RTCClient.: onReceiveIceCandidatesFromUser 10182814, session=9bc25a69-8e1d-4508-8caa-bb6bda8228cf
02-25 16:46:18.464 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.464 9035-9232/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10026 for QBRTCClient
02-25 16:46:18.464 9035-9219/com.myapp.chat D/RTCClient.QBRTCSession: process ice candidates from 10182814
02-25 16:46:18.464 9035-9219/com.myapp.chat D/RTCClient.QBPeerChannel: Set iceCandidates in count of: 1
02-25 16:46:18.464 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: Request Looper execute.
02-25 16:46:18.464 9035-9219/com.myapp.chat D/RTCClient.LooperExecutor: POST.Run on thread:10031 for QBPeerChannel

我发现这是我自己的错误造成的。

将代码从样本转移到服务时,我在 onStart() 中删除了以下代码:

intentFilter = new IntentFilter();
intentFilter.addAction(AudioManager.ACTION_HEADSET_PLUG);
intentFilter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED);
audioStreamReceiver = new AudioStreamReceiver();
getActivity().registerReceiver(audioStreamReceiver, intentFilter);

没关系。但是我没有在 onStop() 方法中删除以下内容:

getActivity().unregisterReceiver(audioStreamReceiver);

这会导致崩溃。我没能捕捉到这个事件,因为我的服务会立即重启并立即清除所有日志。

我正在关闭这个问题。