我正在尝试构建一个简单的应用程序来录制语音命令并将其发送到Amazon Alexa,为此我正在关注此tutorial来录制语音命令。以下代码段给我带来了麻烦:
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
所有Google搜索指向的问题是应用程序无法正确设置访问音频源的权限,但我的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 Nexus 5和Android 6.0.1进行Android Studio测试。 SDK设置为Android 5.0。
答案 0 :(得分:13)
经过大约三天的研究,我决定在MyRecorderApp运行时检查应用程序管理器(设置&gt;应用程序&gt;应用程序管理器&gt; MyRecorderApp&gt;权限)。事实证明,MyRecorderApp没有“危险权限”(谷歌称之为),所以我先手动打开它们(我的应用程序从此停止崩溃),这使我找到了以下信息(来自Google和{{ 3}})。
从Android 6.0(API级别23)开始,用户在应用运行时向应用授予权限,而不是在安装应用时授予权限。
Google引用:this blog
以下是我从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”+“插入”(Windows)或“控制”+“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);
}
}