Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/345.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 记录器不工作不止一次(尝试在空对象引用上调用虚拟方法&x27;void android.media.MediaRecorder.prepare()&&x27;)_Java_Android - Fatal编程技术网

Java 记录器不工作不止一次(尝试在空对象引用上调用虚拟方法&x27;void android.media.MediaRecorder.prepare()&&x27;)

Java 记录器不工作不止一次(尝试在空对象引用上调用虚拟方法&x27;void android.media.MediaRecorder.prepare()&&x27;),java,android,Java,Android,我在这里四处寻找,但没有一个解决方案适合我。 基本上,我要做的是在按下ImageButton时开始录制,在松开ImageButton时停止录制,并且能够再次录制,这一次,覆盖旧的录制,而无需先关闭应用程序。当我尝试录制多次(再次按住ImageButton)时,应用程序崩溃并给我一个: java.lang.NullPointerException:尝试对空对象引用调用虚拟方法“void android.media.MediaRecorder.prepare()” 位于com.myname.audi

我在这里四处寻找,但没有一个解决方案适合我。

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

java.lang.NullPointerException:尝试对空对象引用调用虚拟方法“void android.media.MediaRecorder.prepare()”

位于com.myname.audiorecorder.MainActivity.startRecording(MainActivity.java:86)

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

这是我的代码(两个错误都有带**的注释)

你知道发生了什么事吗?我尝试了一些我在这里看到的解决方案,还有一些我自己想出的,但都不管用。多谢各位


编辑

下面是日志中的其余错误

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

在android.view.ViewGroup.DispatchTransformedToucheEvent(ViewGroup.java:2407)中

位于android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)

在android.view.ViewGroup.DispatchTransformedToucheEvent(ViewGroup.java:2407)中

位于android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)

在android.view.ViewGroup.DispatchTransformedToucheEvent(ViewGroup.java:2407)中

位于android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2049)

在android.view.ViewGroup.DispatchTransformedToucheEvent(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(Activity.java:2752)

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

位于android.view.view.dispatchPointerEvent(view.java:8671)

位于android.view.ViewRootImpl$viewPostimeiInputStage.processPointerEvent(ViewRootImpl.java:4193)

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

在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$AsyncInputStage.forward(ViewRootImpl.java:3740)中

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

在android.view.ViewRootImpl$AsyncInputStage.apply上(ViewRootImpl.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(本机方法)

下一步(MessageQueue.java:143)

位于android.os.Looper.loop(Looper.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)


您正在oncreate中初始化录音机。这意味着在打开该活动时将创建实例。因此,最好是在ClickListener上初始化AudioRecorder,这样当您单击ImageView时,每次都会创建新实例。

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

stopRecording()
方法中,您设置了
myAudioRecorder=null
,但在再次调用
startRecording()
时,您从未重新初始化它。您缺少导致错误的原因。您的堆栈跟踪不完整。提供完整的堆栈跟踪。
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();
}
}