安卓:解決應用前後臺切換報The surface has been released錯誤;PhoneStateListener實現通話狀態的監聽

被這個The surface has been released錯誤糾纏了2天,今天終於解決了,現在整理下思路。

自己練手做了個項目,使用SurfaceView播放視頻。但是測試時發現如果播放時來電話,通話結束後不能自動播放。經過百度,重寫了onPush和onResume方法,測試通過。但是此時如果按HOME鍵,再切換回主程序時,視頻不能自動播放,並且會報The surface has been released這個錯誤。

各位大神的見解基本都差不多,說是 在surfaceHolder還沒準備好的時候,就調用了MediaPlayer的start()方法。並建議將mediaPlayer.setDisplay(surfaceHolder)放在surfaceCreated中,自己嘗試了下,問題並沒有解決。最後經過多方查閱,才知道surface的創建在onResume方法之後,但是我確是在onResume方法之中調用的play方法,因此必然會報這個錯。

好的,既然知道了問題,那麼答案也就在眼前了,我的解決思路是,不採用onPush和onResume這兩個方法來判斷應用是否在前臺。而是用surfaceHolder.addCallback(new SurfaceCallback());來監聽,通過surfaceCreated和surfaceDestroyed這兩個方法來判斷。當然,這樣只是解決了HOME鍵返回的問題,當來電話時是不會調用這兩個方法的(但是onPush和onResume方法卻會調用,很奇怪,不知道爲什麼),所以接下來要做的是對來電進行監聽。

        //獲取電話服務
        manager = (TelephonyManager) this.getSystemService(TELEPHONY_SERVICE);
        // 手動註冊對PhoneStateListener中的listen_call_state狀態進行監聽
        manager.listen(new MyPhoneStateListener(), PhoneStateListener.LISTEN_CALL_STATE);

創建MyPhoneStateListener類,由於OFFHOOK是主動掛斷電話,API中沒有被動掛斷這一狀態,所以只能定義一個isCalling用來判斷被動掛斷這種情況。

private class MyPhoneStateListener extends PhoneStateListener{
        @Override
        public void onCallStateChanged(int state, String incomingNumber) {
            //需要考慮主動掛斷和被動掛斷兩種情況
            switch (state){
                //空閒
                case TelephonyManager.CALL_STATE_IDLE:
                    System.out.println("電話處於空閒狀態......");
                    //判斷通話是否爲對方掛斷
                    if (isCalling) {
                        if (position > 0 && path != null) {
                            play(position);
                            position = 0;
                        }
                    }
                    isCalling = false;
                    break;
                //來電
                case TelephonyManager.CALL_STATE_RINGING:
                    System.out.println("電話呼入......電話號碼是:"+incomingNumber);
                    if (mediaPlayer.isPlaying()) {
                        position = mediaPlayer.getCurrentPosition();
                        mediaPlayer.stop();
                    }
                    isCalling = true;
                    break;
                //主動掛斷
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    System.out.println("電話掛斷......");
                    if (position > 0 && path != null) {
                        play(position);
                        position = 0;
                    }
                    break;
            }
            super.onCallStateChanged(state, incomingNumber);
        }
    }
最後,千萬別忘了註冊權限

<uses-permission android:name="android.permission.READ_PHONE_STATE" />


現在。OK,大功告成,無論是電話進來,還是按HOME鍵返回,當程序切換回來的時候,視頻都可以繼續播放了!


最後,如果我的經驗對你有用,不要吝嗇你寶貴的支持,在下面回覆下吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章