Java MediaRecorder在设置音频源时引发异常(android开发)

Java MediaRecorder在设置音频源时引发异常(android开发),java,android,mediarecorder,Java,Android,Mediarecorder,我正在尝试构建一个简单的应用程序来录制语音命令并将其发送到AmazonAlexa,为此,我将遵循这个程序来录制语音命令。以下代码段给我带来了麻烦: import android.app.Activity; import android.media.MediaPlayer; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.view.

我正在尝试构建一个简单的应用程序来录制语音命令并将其发送到AmazonAlexa,为此,我将遵循这个程序来录制语音命令。以下代码段给我带来了麻烦:

import android.app.Activity;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import java.io.IOException;


public class MainActivity extends Activity {
    Button play,stop,record;
    private MediaRecorder myAudioRecorder;
    private String outputFile = null;

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

    play=(Button)findViewById(R.id.button3);
    stop=(Button)findViewById(R.id.button2);
    record=(Button)findViewById(R.id.button);

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

    myAudioRecorder=new MediaRecorder();
    myAudioRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); ***ERROR***
    myAudioRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
    myAudioRecorder.setAudioEncoder(MediaRecorder.OutputFormat.AMR_NB);
    myAudioRecorder.setOutputFile(outputFile);
通过抛出以下错误堆栈:

FATAL EXCEPTION: main
                                                                          Process: com.example.michael.test, PID: 20504
                                                                          java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.michael.test/com.example.michael.test.MainActivity}: java.lang.RuntimeException: setAudioSource failed.
                                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2416)
                                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476)
                                                                              at android.app.ActivityThread.-wrap11(ActivityThread.java)
                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344)
                                                                              at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                              at android.os.Looper.loop(Looper.java:148)
                                                                              at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                              at java.lang.reflect.Method.invoke(Native Method)
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                           Caused by: java.lang.RuntimeException: setAudioSource failed.
                                                                              at android.media.MediaRecorder.setAudioSource(Native Method)
                                                                              at com.example.michael.test.MainActivity.onCreate(MainActivity.java:37)
                                                                              at android.app.Activity.performCreate(Activity.java:6251)
                                                                              at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1107)
                                                                              at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2369)
                                                                              at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2476) 
                                                                              at android.app.ActivityThread.-wrap11(ActivityThread.java) 
                                                                              at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1344) 
                                                                              at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                              at android.os.Looper.loop(Looper.java:148) 
                                                                              at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                              at java.lang.reflect.Method.invoke(Native Method) 
                                                                              at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                              at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616) 
04-25 12:35:39.109 20504-20504/com.example.michael.test I/Process: Sending signal. PID: 20504 SIG: 9
所有谷歌搜索都指出问题在于应用程序访问音频源的权限设置不正确,但my androidmanifest.xml确实包含以下内容:

    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />


所以我不知道这里还会出什么问题。。。我正在使用Android Studio开发一款LG Nexus 5和Android 6.0.1进行测试。SDK设置为Android 5.0。

经过大约三天的研究,我决定在MyRecorderApp运行时检查应用程序管理器(设置>应用程序>应用程序管理器>MyRecorderApp>权限)。事实证明,MyRecorderApp没有“危险权限”(谷歌称之为“危险权限”),所以我先手动打开它们(我的应用程序从此停止崩溃),这让我找到了下面的信息(从谷歌和谷歌)

从Android 6.0(API级别23)开始,用户在应用程序运行时授予应用程序权限,而不是在安装应用程序时

引用谷歌的话:

下面是我从Google页面和上述来源获得的代码的简短版本。这样做的目的是在用户第一次启动应用程序时,即安装应用程序后,请求用户允许录制音频并访问手机文件夹。它适用于我的Android M(6.0.1)、Android Studio 2.1.1

添加以下声明

private boolean permissionToRecordAccepted = false;
private boolean permissionToWriteAccepted = false;
private String [] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"};
添加以下覆盖代码块。您还可以通过按“Alt”+“Insert”(Windows)或“control”+“O”(Mac)将其与Android Studio模板一起添加,然后查找列表下方的onRequestPermissionsResult选项

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode){
        case 200:
            permissionToRecordAccepted  = grantResults[0] == PackageManager.PERMISSION_GRANTED;
            permissionToWriteAccepted  = grantResults[1] == PackageManager.PERMISSION_GRANTED;
            break;
    }
    if (!permissionToRecordAccepted ) MainActivity.super.finish();
    if (!permissionToWriteAccepted ) MainActivity.super.finish();

}
最后,将这个“if”语句添加到onCreate中

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    // Add the following code to your onCreate
    int requestCode = 200;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
        requestPermissions(permissions, requestCode);
    }

}

完美答案。解决了我的一个大问题。如果可能的话,我会投票几次。