2016-07-06 17 views
-3

我在這裏找過,但沒有找到解決方案爲了我。記錄器不能工作多次(嘗試調用空對象引用的虛擬方法'void android.media.MediaRecorder.prepare()')

基本上,我試圖做的是當ImageButton按下時開始錄製,當ImageButton被釋放時停止錄製並且能夠再次錄製,這次覆蓋舊錄製,而不先關閉應用程序。當我試圖記錄不止一次(再次按住ImageButton的),應用程序崩潰,並給了我一個:

顯示java.lang.NullPointerException:試圖調用虛擬方法無效android.media.MediaRecorder.prepare ()」上的空對象引用

在com.myname.audiorecorder.MainActivity.startRecording(MainActivity.java:86)

在com.myname.audiorecorder.MainActivity $ 1.onTouch(MainActivity.java:61 )

This是我的代碼(這兩個錯誤都有**的評論)

public class MainActivity extends Activity { 
    Button play; 
    private MediaRecorder myAudioRecorder; 
    private String outputFile; 

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    play = (Button)findViewById(R.id.button3); 

    play.setEnabled(false); 
    outputFile = Environment.getExternalStorageDirectory().getAbsolutePath() + "/recording.3gp";; 

    myAudioRecorder = new MediaRecorder(); 
    myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); 
    myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); 
    myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB); 
    myAudioRecorder.setOutputFile(outputFile); 


    // handles "record" and "stop" 
    ImageButton roundButton = (ImageButton) findViewById(R.id.fab_button); 

    roundButton.setOnTouchListener(new View.OnTouchListener() { 
     @Override 
     public boolean onTouch(View v, MotionEvent event) 
     { 
      Vibrator vb = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE); 
      if (event.getAction() == MotionEvent.ACTION_DOWN) 
      { 
       vb.vibrate(50); 
       Log.i("Touched", "Recording"); 
       startRecording(); // ** ERROR (MainActivity.java:86) 
      } 
      else if (event.getAction() == MotionEvent.ACTION_UP) { 
       stopRecording(); 
       Log.i("Released", "Stopped"); 
       vb.vibrate(50); 
      } 
      return false; 
     } 
    }); 

    // play recording 
    play.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) throws IllegalArgumentException,SecurityException,IllegalStateException { 
      playRecording(); 
     } 
    }); 
} 


// start recording voice 
public void startRecording() 
{ 
    try { 
     myAudioRecorder.prepare(); // ** ERROR (MainActivity.java:61) 
     myAudioRecorder.start(); 
    } 

    catch (IllegalStateException e) { 
     e.printStackTrace(); 
    } 

    catch (IOException e) { 
     e.printStackTrace(); 
    } 

    Toast.makeText(getApplicationContext(), "Recording started", Toast.LENGTH_LONG).show(); 
} 


// stop recording voice 
public void stopRecording() 
{ 
    myAudioRecorder.stop(); 
    myAudioRecorder.reset(); 
    myAudioRecorder.release(); 
    myAudioRecorder = null; 

    play.setEnabled(true); 

    Toast.makeText(getApplicationContext(), "Audio recorded successfully",Toast.LENGTH_LONG).show(); 
} 


// play recorded voice 
public void playRecording() 
{ 
    MediaPlayer m = new MediaPlayer(); 

    try { 
     m.setDataSource(outputFile); 
    } 

    catch (IOException e) { 
     e.printStackTrace(); 
    } 

    try { 
     m.prepare(); 
    } 

    catch (IOException e) { 
     e.printStackTrace(); 
    } 

    m.start(); 
    Toast.makeText(getApplicationContext(), "Playing audio", Toast.LENGTH_LONG).show(); 
} 
} 

有關正在發生什麼的任何想法?我嘗試了一些我在這裏看到的解決方案,還有一些我自己想出來的,但沒有成功。非常感謝你。


編輯

這裏的誤差在logcat的

在android.view.View.dispatchTouchEvent(View.java:8470)

在Android上休息.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2407)

在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)

在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2407)

在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java :2049)

在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2407)

在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)

在android.view。 ViewGroup.dispatchTran sformedTouchEvent(ViewGroup.java:2407)

在android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)

在com.android.internal.policy.impl.PhoneWindow $ DecorView.superDispatchTouchEvent(PhoneWindow。的java:2369)

在com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719)

在android.app.Activity.dispatchTouchEvent(活動。Java的:2752)

在com.android.internal.policy.impl.PhoneWindow $ DecorView.dispatchTouchEvent(PhoneWindow.java:2330)

在android.view.View.dispatchPointerEvent(View.java:8671)

在android.view.ViewRootImpl $ ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4193)

在android.view.ViewRootImpl $ ViewPostImeInputStage.onProcess(ViewRootImpl.java:4059)

在android.view .ViewRootImpl $ InputStage.d eliver(ViewRootImpl.java:3604)

在android.view.ViewRootImpl $ InputStage.onDeliverToNext(ViewRootImpl.java:3657)

在android.view.ViewRootImpl $ InputStage.forward(ViewRootImpl.java:3623)

在android.view.ViewRootImpl $ AsyncInputStage.forward(ViewRootImpl.java:3740)

在android.view.ViewRootImpl $ InputStage.apply(ViewRootImpl.java:3631)

在android.view .ViewRootImpl $ AsyncInputStage.apply(ViewRootI mpl.java:3797)

在android.view.ViewRootImpl $ InputStage.deliver(ViewRootImpl.java:3604)

在android.view.ViewRootImpl $ InputStage.onDeliverToNext(ViewRootImpl.java:3657)

在android.view.ViewRootImpl $ InputStage.forward(ViewRootImpl.java:3623)

在android.view.ViewRootImpl $ InputStage.apply(ViewRootImpl.java:3631)

在android.view.ViewRootImpl $ InputStage.deliver(ViewRootImpl.java:3604)

在android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5912)

在android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5851)

在android.view.ViewRootImpl.enqueueInputEvent (ViewRootImpl.java:5822)

在android.view.ViewRootImpl $ WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6002)

在android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:192)

在android.os.MessageQueue.nativePollOnce(本機方法)

在android.os.MessageQueue.next(MessageQueue.java:143)

在android.os.Looper.loop(活套。的java:122)

在android.app.ActivityThread.main(ActivityThread.java:5343)

在java.lang.reflect.Method.invoke(本機方法)

在java的。lang.reflect.Method.invoke(Method.java:372)

在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:905)

在com.android.internal。 os.ZygoteInit.main(ZygoteInit.java:700)

+0

在'stopRecording()'方法中,您設置了'myAudioRecorder = null',但您再次調用'startRecording()'時不會重新初始化它。 –

+0

您錯過了導致錯誤的原因。你的堆棧跟蹤不完整。提供完整的堆棧跟蹤。 – JoxTraex

回答

0

您正在初始化AudioRecorder的oncreate。這意味着實例將在您打開該活動時創建。在ClickListener上最好使用Initialize AudioRecorder,所以每次單擊ImageView時都會創建新的實例。

0

您應該在onTouch()內部調用startRecording()之前初始化AudioRecorder,否則第二次調用它時它會爲null,因爲在將它釋放到stopRecording()之後將其設置爲null。

相關問題