首页 文章

Logger 不能多次工作(尝试在空对象引用上调用虚方法'void android.media.MediaRecorder.prepare()')

提问于
浏览
-3

I've looked around here but none of the solutions I've found work for me.

基本上,我要做的是在按下ImageButton时开始录制,在释放ImageButton时停止录制,并且能够再次录制,这次覆盖旧录制,而无需先关闭应用程序 . 当我尝试多次录制时(再次按住ImageButton),应用程序崩溃并给我一个:

java.lang.NullPointerException:尝试在com.myname的com.myname.audiorecorder.MainActivity.startRecording(MainActivity.java:86)上的空对象引用上调用虚拟方法'void android.media.MediaRecorder.prepare()' .audiorecorder.MainActivity $ 1.onTouch(MainActivity.java:61)

这是我的代码(两个错误都有**评论)

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();
}
}

关于发生了什么的任何想法?我已经尝试了一些我在这里看到的解决方案,并且我自己想出了一些解决方案,但没有任何效果 . 非常感谢你 .


EDIT

这是logcat中的其余错误

在Android.view.View.View.St上的android.view.View.View.St.EvatchTventEvent(ViewGroup.java:2407)上的android.view.View.DispatchTouchEvent(View.java:8470) .ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2407)位于android.view.View.View.StartEvent(ViewGroup.java:2049),位于android.view.View.St.EvatchTouchEvent(ViewGroup.java:2407),位于android.view.ViewGroup.dispatchTouchEvent( ViewGroup.java:2049)在android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:2407)的android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)com.android.internal.policy.impl.PhoneWindow $ DecorView .superDispatchTouchEvent(PhoneWindow.java:2369)位于com.android的android.app.Activity.dispatchTouchEvent(Activity.java:2752)的com.android.internal.policy.impl.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1719) . andr的internal.policy.impl.PhoneWindow $ DecorView.dispatchTouchEvent(PhoneWindow.java:2330) android.view.ViewRootImpl上的oid.view.View.dispatchPointerEvent(View.java:8671)$ android.view.ViewRootImpl $ ViewPostImeInputStage.onProcess(ViewRootImpl.java:4059) .view.ViewRootImpl $ InputStage.deliver(ViewRootImpl.java:3604)at android.view.ViewRootImpl $ InputStage.onDeliverToNext(ViewRootImpl.java:3657)at android.view.ViewRootImpl $ InputStage.forward(ViewRootImpl.java:3623)at at android.view.ViewRootImpl $ AsyncInputStage.forward(ViewRootImpl.java:3740)at android.view.ViewRootImpl $ InputStage.apply(ViewRootImpl.java:3631)at android.view.ViewRootImpl $ AsyncInputStage.apply(ViewRootImpl.java:3797)在android.view.ViewRootImpl $ InputStage.deliver(ViewRootImpl.java:3604)android.view.ViewRootImpl $ InputStage.onDeliverToNext(ViewRootImpl.java:3657)at android.view.ViewRootImpl $ InputStage.forward(ViewRootImpl.java:3623) )在android.view.ViewRootImpl $的android.view.ViewRootImpl $ InputStage.apply(ViewRootImpl.java:3631) android.view.ViewRootImpl.enqueueInputEvent中的android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:5851)上的android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:5912)的InputStage.deliver(ViewRootImpl.java:3604)(ViewRootImpl) .java:5822)在android.view.MessageQueue.nativePollOnce(Native Method)的android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:192)上的android.view.ViewRootImpl $ WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:6002) android.os.MessageQueue.next(MessageQueue.java:143)位于android.app.Looper.loop(Looper.java:122),位于java.lang.reflect的android.app.ActivityThread.main(ActivityThread.java:5343) .Method.invoke(Native Method)位于com.android的com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:905)的java.lang.reflect.Method.invoke(Method.java:372) .internal.os.ZygoteInit.main(ZygoteInit.java:700)

2 回答

  • 0

    您应该在调用onTouch()内部的startRecording()之前初始化AudioRecorder,否则第二次调用它时它将为null,因为您在stopRecording()中释放后将其设置为null;

  • 0

    您正在使用oncreate初始化AudioRecorder . 这意味着当您打开该活动时将创建实例 . 因此,ClickListener上的Initialize AudioRecorder更好,因此每次创建新实例时都会单击ImageView .

相关问题