2016-04-25 7 views
2

私は音声コマンドを録音してAmazon Alexaに送信する簡単なアプリを構築しようとしています。そのためにはtutorialに従っています。 、問題へのすべてのグーグルでのポイントは、オーディオソースにアクセスするためのアプリのために適切に設定されていない権利であることオーディオソースの設定時にMediaRecorderが例外をスローする(アンドロイド開発)

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 

:次のエラー・スタックを投げることによって

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

:次のコードスニペットは私に支障をきたしますだから私はここで間違って行くことができ、他に何の損失で午前...私はAndroidのスタッドを開発しています

<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" /> 

:しかし、私のAndroidManifest.xmlには、以下の行を含んでいますAndroid 6.0.1搭載のLG Nexus 5を使用してテストします。 SDKはAndroid 5.0に設定されています。

答えて

13

調査の約3日後、MyRecorderAppの実行中にアプリケーションマネージャ(設定>アプリケーション>アプリケーションマネージャ> MyRecorderApp>権限)をチェックすることにしました。明らかに、MyRecorderAppの「危険なアクセス許可」(Googleが呼び出すようなもの)はなかったので、私はそれらを手動でオンにした(私のアプリはそれ以来クラッシュを止めた)。 。

ユーザーはAndroid 6.0(APIレベル23)から、アプリケーションのインストール時ではなく、アプリケーションの実行中にアプリケーションにアクセス許可を与えます。 Googleからの

引用:以下Complete explanation from Google's developers website

私はGoogleのページと上記の起源に由来するコードの短いバージョンです。アイデアは、オーディオを録音し、アプリを初めて起動したとき、すなわちインストールした後に電話のフォルダにアクセスする権限をユーザに求めることです。これは、次の宣言

private boolean permissionToRecordAccepted = false; 
private boolean permissionToWriteAccepted = false; 
private String [] permissions = {"android.permission.RECORD_AUDIO", "android.permission.WRITE_EXTERNAL_STORAGE"}; 

次オーバーライドのコードブロックを追加

を追加2.1.1

私のアンドロイドM(6.0.1)、Androidのメーカーに勤務しました。 「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); 
    } 

} 
+0

完璧な答え。私の大きな問題を解決しました。可能であれば、数回upvoteします。 – filipebarretto

関連する問題