Android Studio MediaRecorder 不会录制

Android Studio MediaRecorder won't record

我想在 android 工作室制作录音机。我遵循了本教程: https://www.youtube.com/watch?v=XANjoeEeQ1Y

哪个不适合我?当我按下 "record" 按钮时,没有任何反应。

由此我添加了带有 onClick() 方法等的动作侦听器。仍然没有用。然后我添加了一个文本视图来显示调试状态。

添加状态文本视图后,我发现 beginRecording() 方法直接进入 catch 语句。

我看了另一个 youtube 视频 https://www.youtube.com/watch?v=lWaypoRVfSc 这似乎或多或少地对 MediaRecorder 做了同样的事情。

所以..我的问题是。我做错了什么?我怎样才能让它在按下录音按钮时真正录音?

提前谢谢你。

这是我的代码:

package com.example.natalie.recorder;

import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Button;
import android.widget.TextView;

import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.StringWriter;

public class MainActivity extends AppCompatActivity {
    private MediaPlayer mediaPLayer;
    private MediaRecorder recorder;
    private String OUTPUT_FILE;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
        setSupportActionBar(toolbar);

        Button startR = (Button) findViewById(R.id.startBtn);
        Button stopR = (Button) findViewById(R.id.finishBtn);
        Button playRecording = (Button) findViewById(R.id.playBtn);
        Button stopPlaying = (Button) findViewById(R.id.stopBtn);
        final TextView statusTV;
        statusTV = (TextView) findViewById(R.id.statusTextView);

        OUTPUT_FILE= Environment.getExternalStorageDirectory().getAbsolutePath()+"/audiorecorder.3gpp";

        /*------START BUTTON------*/

        startR.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                final TextView stv=statusTV;
                try {
                    beginRecording();
                    stv.setText("Recording");
                } catch (Exception e) {
                    StringWriter sw = new StringWriter();
                    e.printStackTrace(new PrintWriter(sw));
                    String exceptionAsString = sw.toString();
                    stv.setText("Error");
                }
            }
        });

        /*------STOP BUTTON------*/

        stopR.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                final TextView stv=statusTV;
                try {
                    stopRecording();
                    stv.setText("Stopped");
                } catch (Exception e) {
                    StringWriter sw = new StringWriter();
                    e.printStackTrace(new PrintWriter(sw));
                    String exceptionAsString = sw.toString();
                    statusTV.setText("Error");
                    Log.d("here","dd",e);
                }
            }
        });

        playRecording.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                try {
                    playRecording();
                } catch (Exception e) {
                    StringWriter sw = new StringWriter();
                    e.printStackTrace(new PrintWriter(sw));
                    String exceptionAsString = sw.toString();
                    statusTV.setText("Error");
                }
            }
        });

        stopPlaying.setOnClickListener(new View.OnClickListener(){
            @Override
            public void onClick(View view) {
                try {
                    stopPlayback();
                } catch (Exception e) {
                    StringWriter sw = new StringWriter();
                    e.printStackTrace(new PrintWriter(sw));
                    String exceptionAsString = sw.toString();
                    statusTV.setText("Error");
                }
            }
        });

    }

    private void stopPlayback() throws Exception{
        if(mediaPLayer != null)
            mediaPLayer.stop();
    }
    private void playRecording() throws IOException {
        ditchMediaPLayer();
        mediaPLayer = new MediaPlayer();
        mediaPLayer.setDataSource(OUTPUT_FILE);
        mediaPLayer.prepare();
        mediaPLayer.start();

    }

    private void ditchMediaPLayer() {
        if (mediaPLayer != null) {
            try{
                mediaPLayer.release();
            } catch(Exception e) {
                e.printStackTrace();
            }
        }
    }

    private void stopRecording() {
        if(recorder != null)
            recorder.stop();
    }
    private void beginRecording() throws Exception{
        ditchMediaRecorder();
        File outFile = new File(OUTPUT_FILE);

        if (outFile.exists()) {
            outFile.delete();
        }

        recorder = new MediaRecorder();
        recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        record.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);  
        recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
        recorder.setOutputFile(OUTPUT_FILE);
        recorder.prepare();
        recorder.start();
    }

    private void ditchMediaRecorder() {
        if(recorder != null)
            recorder.release();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

AndroidManifest 如下所示:

<?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.natalie.recorder">



        <uses-permission android:name="android.permission.CAMERA" />
        <uses-feature android:name="android.hardware.camera" />
        <uses-permission android:name="android.permission.RECORD_AUDIO" 
        />
        <uses-permission 
        android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:roundIcon="@mipmap/ic_launcher_round"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
            <activity
                android:name=".MainActivity"
                android:label="@string/app_name"
                android:theme="@style/AppTheme.NoActionBar">
                <intent-filter>
                    <action android:name="android.intent.action.MAIN" />

                    <category 
  android:name="android.intent.category.LAUNCHER" />
                </intent-filter>
            </activity>
        </application>

    </manifest>

content_main.xml来到这里:

                <Button
                    android:id="@+id/stopBtn"
                    android:layout_width="249dp"
                    android:layout_height="56dp"
                    android:background="@color/colorAccent"
                    android:text="Stop PLayback"
                    app:layout_constraintBottom_toBottomOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/playBtn" />

                <Button
                    android:id="@+id/playBtn"
                    android:layout_width="249dp"
                    android:layout_height="48dp"
                    android:background="@color/colorAccent"
                    android:text="Play Recording"
                    app:layout_constraintBottom_toTopOf="@+id/stopBtn"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/finishBtn" />

                <Button
                    android:id="@+id/finishBtn"
                    android:layout_width="249dp"
                    android:layout_height="48dp"
                    android:background="@color/colorAccent"
                    android:text="Finish Recording"
                    app:layout_constraintBottom_toTopOf="@+id/playBtn"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toBottomOf="@+id/startBtn" />

                <Button
                    android:id="@+id/startBtn"
                    android:layout_width="247dp"
                    android:layout_height="48dp"
                    android:background="@color/colorAccent"
                    android:text="Start Recording"
                    app:layout_constraintBottom_toTopOf="@+id/finishBtn"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintTop_toTopOf="parent" />

                <TextView
                    android:id="@+id/statusTextView"
                    android:layout_width="246dp"
                    android:layout_height="22dp"
                    android:text="Status"
                    android:textAlignment="center"
                    android:textSize="24sp"
                    app:layout_constraintRight_toRightOf="parent"
                    app:layout_constraintLeft_toLeftOf="parent"
                    app:layout_constraintBottom_toTopOf="@+id/startBtn"
                    app:layout_constraintTop_toTopOf="parent" />

            </android.support.constraint.ConstraintLayout>

您请求了 CAMERAWRITE_STORAGERECORD_AUDIO 许可,但您并未在 activity 处请求。看看 this.

使用: ContextCompat.checkSelfPermission(this,Manifest.permission.WRITE_EXTERNAL_STORAGE) 检查权限状态并将其与 PackageManager.PERMISSION_GRANTED 进行比较,这意味着您的权限已被接受,如下所示:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 100);
}

并在 onRequestPermissionsResult 中做这样的事情:

 @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
            //do work
        }
    }