2016-06-25 11 views
3

マイク入力(特に呼吸)を聞き取り、それに基づいてデータを提示するアプリを実装しようとしています。私はAndroidクラスAudioRecordを使用しています.AudioRecordをインスタンス化しようとすると3つのエラーが発生します。Android AudioRecordが初期化されません

AudioRecord: AudioFlinger could not create record track, status: -1 
AudioRecord-JNI: Error creating AudioRecord instance: initialization check failed with status -1. 
android.media.AudioRecord: Error code -20 when initializing native AudioRecord object. 

私は、この優れたスレッドが見つかりました:AudioRecord object not initializing

私は、すべてのサンプルレート、オーディオフォーマットおよびチャネル構成で問題を解決しようとしようとした受け入れ答えからコードを借りてきたが、それはしませんでしたヘルプ、私はすべての設定の上記のエラーを取得します。私はまた、スレッド内の回答の1つに従っていくつかの場所でAudioRecord.release()への呼び出しを追加しましたが、違いはありませんでした。

import android.media.AudioFormat; 
import android.media.AudioRecord; 
import android.media.MediaRecorder; 
import android.util.Log; 

public class SoundMeter { 

private AudioRecord ar = null; 
private int minSize; 
private static int[] mSampleRates = new int[] { 8000, 11025, 22050, 32000, 44100 }; 

public boolean start() { 
    ar = findAudioRecord(); 
    if(ar != null){ 
     ar.startRecording(); 
     return true; 
    } 
    else{ 
     Log.e("SoundMeter", "ERROR, could not create audio recorder"); 
     return false; 
    } 
} 

public void stop() { 
    if (ar != null) { 
     ar.stop(); 
     ar.release(); 
    } 
} 

public double getAmplitude() { 
    short[] buffer = new short[minSize]; 
    ar.read(buffer, 0, minSize); 
    int max = 0; 
    for (short s : buffer) 
    { 
     if (Math.abs(s) > max) 
     { 
      max = Math.abs(s); 
     } 
    } 
    return max; 
} 

public AudioRecord findAudioRecord() { 
    for (int rate : mSampleRates) { 
     for (short audioFormat : new short[] { AudioFormat.ENCODING_PCM_8BIT, AudioFormat.ENCODING_PCM_16BIT, AudioFormat.ENCODING_PCM_FLOAT }) { 
      for (short channelConfig : new short[] { AudioFormat.CHANNEL_IN_MONO, AudioFormat.CHANNEL_IN_STEREO }) { 
       try { 
        Log.d("SoundMeter", "Attempting rate " + rate + "Hz, bits: " + audioFormat + ", channel: " + channelConfig); 
        int bufferSize = AudioRecord.getMinBufferSize(rate, channelConfig, audioFormat); 

        if (bufferSize != AudioRecord.ERROR_BAD_VALUE) { 
         // check if we can instantiate and have a success 
         Log.d("SoundMeter", "Found a supported bufferSize, attempting to instantiate"); 
         AudioRecord recorder = new AudioRecord(MediaRecorder.AudioSource.DEFAULT, rate, channelConfig, audioFormat, bufferSize); 

         if (recorder.getState() == AudioRecord.STATE_INITIALIZED){ 
          minSize = bufferSize; 
          return recorder; 
         } 
         else 
          recorder.release(); 
        } 
       } catch (Exception e) { 
        Log.e("SoundMeter", rate + " Exception, keep trying.", e); 
       } 
      } 
     } 
    } 
    return null; 
} 

}私はまた私のマニフェストファイルへ

<uses-permission android:name="android.permission.RECORD_AUDIO"/> 

タグを追加した

、マニフェストタグの子や兄弟のよう:

この

は私のコードですアプリケーションタグは、上記スレッドの他の回答の1つに従います。私はこのタグを追加した後でプロジェクトを再構築しました。

これらは私が問題を見つけたときに見つけた解決策ですが、残念なことに私のためにやっていないようです。 Nexus 5の電話機(エミュレータではありません)でデバッグしています。これらのエラーは、AudioRecordのコンストラクタを呼び出すと表示されます。私はマイクをリリースしようと数回自分の電話機を再起動しましたが、無駄です。このプロジェクトはAndroid 4.4に基づいており、携帯電話は現在Android 6.0.1を実行しています。

他に何ができるか、私が逃した可能性のあることについてのヒントを高く評価しますか?ありがとうございました!

答えて

7

私は自分自身で答えを見つけました。それは許可と関係がありました。

私の電話でAPIバージョン23(Android 6.0.1)を実行しており、マニフェストファイルのみを使用してアクセス権を処理していないという問題がありました。バージョン23以降、実行時にアクセス権が付与されます。私は実行時にパーミッションを要求するメソッドを追加しました。そして、一度それを自分の電話で許可してしまえば、それはうまくいきました。

private void requestRecordAudioPermission() { 
    //check API version, do nothing if API version < 23! 
    int currentapiVersion = android.os.Build.VERSION.SDK_INT; 
    if (currentapiVersion > android.os.Build.VERSION_CODES.LOLLIPOP){ 

     if (ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) { 

      // Should we show an explanation? 
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.RECORD_AUDIO)) { 

       // Show an expanation to the user *asynchronously* -- don't block 
       // this thread waiting for the user's response! After the user 
       // sees the explanation, try again to request the permission. 

      } else { 

       // No explanation needed, we can request the permission. 

       ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.RECORD_AUDIO}, 1); 
      } 
     } 
    } 
} 

@Override 
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { 
    switch (requestCode) { 
     case 1: { 
      // If request is cancelled, the result arrays are empty. 
      if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

       // permission was granted, yay! Do the 
       // contacts-related task you need to do. 
       Log.d("Activity", "Granted!"); 

      } else { 

       // permission denied, boo! Disable the 
       // functionality that depends on this permission. 
       Log.d("Activity", "Denied!"); 
       finish(); 
      } 
      return; 
     } 

     // other 'case' lines to check for other 
     // permissions this app might request 
    } 
} 

私はその後、audiorecordのを作成する前に、私のメインの活動でのonCreate()メソッドからrequestRecordAudioPermission()を呼び出します。

+1

あなたは私の日を救った!エラーログはパーミッションに完全に関係しておらず、実際問題の原因となった新しいバージョン23でした。ありがとうございます –

+1

他にも助けてくれてうれしいです:) – Helena

+0

ありがとうございました。この問題では数日を過ごしました – sharry

関連する問題