Androidで音声を録音しようとしていますが、問題が発生しています。
開始ボタンと停止ボタンがあります。「開始」は録音を開始し、「停止」は録音を停止します。
問題は、停止ボタンを押すと、アプリケーションが「W/MediaRecorder(635):mediarecorderが未処理のイベントで消えました」というメッセージをログに記録することです。 (スタート機能はオーディオファイルを正しく保存しています。)
次に、もう一度開始ボタンまたは停止ボタンを押すと、「A/libc(743):0x00000010(code = 1)の致命的なシグナル11(SIGSEGV)、スレッド743(xample.recorder)」というエラーメッセージが表示されます。
録音クラスのコードは以下のとおりです。
/**
* Creates a new audio recording at the given path (relative to root of SD card).
*/
public AudioRecorder(String path) {
this.path = sanitizePath(path);
}
private String sanitizePath(String path) {
if (!path.startsWith("/")) {
path = "/" + path;
}
if (!path.contains(".")) {
path += ".3gp";
}
return Environment.getExternalStorageDirectory().getAbsolutePath() + path;
}
public void start() throws IOException {
String state = Android.os.Environment.getExternalStorageState();
if(!state.equals(Android.os.Environment.MEDIA_MOUNTED)) {
throw new IOException("SD Card is not mounted. It is " + state + ".");
}
// make sure the directory we plan to store the recording in exists
File directory = new File(path).getParentFile();
if (!directory.exists() && !directory.mkdirs()) {
throw new IOException("Path to file could not be created.");
}
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(path);
try{
recorder.prepare();
}
catch(IOException e){
Log.e("Recorder","Recording failed");
}
recorder.start();
}
/**
* Stops a recording that has been previously started.
*/
public void stop() throws IOException {
recorder.stop();
recorder.release();
}
主な活動のコードは以下のとおりです。
/*
* */
public class Recorder extends Activity implements OnClickListener
{
private static final String TAG="Recorder";
AudioRecorder ar=new AudioRecorder("/TestAudio.3gp");
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recorder);
final Button start = (Button) this.findViewById(R.id.btn_start);
start.setOnClickListener(this);
final Button stop = (Button) this.findViewById(R.id.btn_stop);
stop.setOnClickListener(this);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.activity_recorder, menu);
return true;
}
public void onClick(View v) {
// TODO Auto-generated method stub
try{
switch (v.getId()) {
case R.id.btn_start:
ar.start();
Log.d("Recorder","Recorded");
Toast.makeText(this, "Controll returned from start function", Toast.LENGTH_LONG).show();
break;
case R.id.btn_stop:
ar.stop();
Toast.makeText(this, "Recording stopped; Starting MediaPlayer", Toast.LENGTH_SHORT).show();
//Toast.makeText(this, "Starting media player", Toast.LENGTH_LONG).show();
ar.startPlaying();
//Toast.makeText(this, "Recording stopped", Toast.LENGTH_LONG).show();
break;
}
}
catch(Exception e){
Log.e("Recorder", e.getMessage(), e);
Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
}
}
}
この問題は、レコーダーをリリースする前にリセットすることで解決しました。
recorder.stop(); // stop recording
recorder.reset(); // set state to idle
recorder.release(); // release resources back to the system
recorder = null;
ドキュメントには次のように記載されています。
これらのリスナーに関連付けられたそれぞれのコールバックを受信するには、アプリケーションはLooperが実行されているスレッドでMediaRecorderオブジェクトを作成する(デフォルトではメインUIスレッドで既にLooperが実行されている)が必要です。
必ずUIスレッドでレコーダーを作成してください。おそらく、UIスレッドでそのメソッドを呼び出すこともできます。
これは、変更されたファームウェアの実行が原因で発生する可能性があります。 SIGSEGVはJavaからは使用できないはずです。この投稿を読んでください。最後にエラーの説明があります。幸運を。
私のSamsungGalaxyS3でAndroid 4.0.4(の変更されていないバージョンでは、Samsungが変更を加えました)を実行していますが、SIGSEGV( "A/libc(20448 ):mediarecorderを使用すると、0x00000010(code = 1) ")で致命的な信号11(SIGSEGV)が発生します。
Android 4.0のAVDでもSIGSEGVを取得するので、そこでもSIGSEGVを取得することができます。
今、私はメディアレコーダーで何が間違っているのかを見つける必要があります。 =)