在我的应用程序中,我正在使用铃音代码,现在我想为此添加诸如暂停/恢复选项的功能。为此,我尝试如下:
private void recordAudio() {
mFile = null;
mTitle = null;
mArtist = null;
mRecordingLastUpdateTime = getCurrentTime();
mRecordingKeepGoing = true;
mFinishActivity = false;
final AlertDialog.Builder adBuilder = new AlertDialog.Builder(RingdroidEditActivity.this); adBuilder.setTitle(getResources().getText(R.string.progress_dialog_recording);
adBuilder.setCancelable(true);
adBuilder.setNegativeButton(
getResources().getText(R.string.progress_dialog_cancel),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mRecordingKeepGoing = false;
mFinishActivity = true;
}
});
adBuilder.setPositiveButton(
getResources().getText(R.string.progress_dialog_stop),
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
mRecordingKeepGoing = false;
}});
//here is the code i added for pause option
adBuilder.setNeutralButton("Pause", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int id) {
mRecordingKeepGoing = false;
adBuilder.show();
}
})
// TODO(nfaralli): try to use a FrameLayout and pass it to the following inflate call.
// Using null, android:layout_width etc. may not work (hence text is at the top of view).
// On the other hand, if the text is big enough, this is good enough. adBuilder.setView(getLayoutInflater().inflate(R.layout.record_audio, null));
mAlertDialog = adBuilder.show();
Button nbutton = mAlertDialog.getButton(DialogInterface.BUTTON_NEGATIVE); nbutton.setBackgroundColor(getResources().getColor(R.color.lightred));
Button pbutton = mAlertDialog.getButton(DialogInterface.BUTTON_POSITIVE);
pbutton.setBackgroundColor(getResources().getColor(R.color.lightGreen));
mTimerTextView = (TextView)mAlertDialog.findViewById(R.id.record_audio_timer);
final SoundFile.ProgressListener listener =
new SoundFile.ProgressListener() {
public boolean reportProgress(double elapsedTime) {
long now = getCurrentTime();
if (now - mRecordingLastUpdateTime > 5) {
mRecordingTime = elapsedTime;
// Only UI thread can update Views such as TextViews.
runOnUiThread(new Runnable() {
public void run() {
int min = (int)(mRecordingTime/60);
float sec = (float)(mRecordingTime - 60 * min);
mTimerTextView.setText(String.format("%d:%05.2f", min, sec));
}
});
mRecordingLastUpdateTime = now;
}
return mRecordingKeepGoing;
}
};
// Record the audio stream in a background thread
mRecordAudioThread = new Thread() {
public void run() {
try {
mSoundFile = SoundFile.record(listener);
if (mSoundFile == null) {
mAlertDialog.dismiss();
Runnable runnable = new Runnable() {
public void run() {
showFinalAlert(
new Exception(),
getResources().getText(R.string.record_error)
);
}
};
mHandler.post(runnable);
return;
}
mPlayer = new SamplePlayer(mSoundFile);
} catch (final Exception e) {
mAlertDialog.dismiss();
e.printStackTrace();
mInfoContent = e.toString();
runOnUiThread(new Runnable() {
public void run() {
mInfo.setText(mInfoContent);
}
});
Runnable runnable = new Runnable() {
public void run() {
showFinalAlert(e, getResources().getText(R.string.record_error));
}
};
mHandler.post(runnable);
return;
}
mAlertDialog.dismiss();
if (mFinishActivity){
RingdroidEditActivity.this.finish();
} else {
Runnable runnable = new Runnable() {
public void run() {
finishOpeningSoundFile();
}
};
mHandler.post(runnable);
}
}
};
mRecordAudioThread.start();
}
但是上面给出了以下运行时例外。
java.lang.IllegalStateException:指定的子代已经有一个父代。您必须先在孩子的父母上调用removeView()。 在android.view.ViewGroup.addViewInner(ViewGroup.java:4417) 在android.view.ViewGroup.addView(ViewGroup.java:4258) 在android.view.ViewGroup.addView(ViewGroup.java:4230) 在com.android.internal.app.AlertController.setupCustomContent(AlertController.java:601) 在com.android.internal.app.AlertController.setupView(AlertController.java:495) 在com.android.internal.app.AlertController.installContent(AlertController.java:253) 在android.app.AlertDialog.onCreate(AlertDialog.java:423) 在android.app.Dialog.dispatchOnCreate(Dialog.java:395) 在android.app.Dialog.show(Dialog.java:294) 在android.app.AlertDialog $ Builder.show(AlertDialog.java:1112) 在com.ringdroid.RingdroidEditActivity $ 8.onClick(RingdroidEditActivity.java:739) 在com.android.internal.app.AlertController $ ButtonHandler.handleMessage(AlertController.java:166) 在android.os.Handler.dispatchMessage(Handler.java:102) 在android.os.Looper.loop(Looper.java:154) 在android.app.ActivityThread.main(ActivityThread.java:6119) 在java.lang.reflect.Method.invoke(本机方法) 在com.android.internal.os.ZygoteInit $ MethodAndArgsCaller.run(ZygoteInit.java:886) 在com.android.internal.os.ZygoteInit.main(ZygoteInit.java:776)
任何人都可以帮助我解决这个问题。
答案 0 :(得分:0)
要录制音频,应用程序的清单文件必须具有android.permission.RECORD_AUDIO权限:
<uses-permission android:name="android.permission.RECORD_AUDIO" />
尝试在没有麦克风的设备上录制音频会导致Android系统引发异常。因此,至关重要的是,在进行这种尝试之前,代码必须检查麦克风是否存在。
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.content.pm.PackageManager;
public class AudioAppActivity extends Activity {
protected boolean hasMicrophone() {
PackageManager pmanager = this.getPackageManager();
return pmanager.hasSystemFeature(
PackageManager.FEATURE_MICROPHONE);
}
}
覆盖活动的onStart()方法以执行许多初始化任务
import android.app.Activity;
import android.app.ActionBar;
import android.app.Fragment;
import android.os.Bundle;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.os.Build;
import android.content.pm.PackageManager;
import android.media.MediaRecorder;
import android.os.Environment;
import android.widget.Button;
import android.media.MediaPlayer;
public class AudioAppActivity extends Activity {
private static MediaRecorder mediaRecorder;
private static MediaPlayer mediaPlayer;
private static String audioFilePath;
private static Button pauseButton;
private static Button playButton;
private static Button recordButton;
private boolean isRecording = false;
@Override
protected void onStart() {
super.onStart();
recordButton = (Button) findViewById(R.id.recordButton);
playButton = (Button) findViewById(R.id.playButton);
pauseButton = (Button) findViewById(R.id.stopButton);
if (!hasMicrophone())
{
pauseButton.setEnabled(false);
playButton.setEnabled(false);
recordButton.setEnabled(false);
} else {
playButton.setEnabled(false);
pauseButton.setEnabled(false);
}
audioFilePath =
Environment.getExternalStorageDirectory().getAbsolutePath()
+ "/myaudio.3gp";
}
}
public void recordAudio (View view) throws IOException
{
isRecording = true;
pauseButton.setEnabled(true);
playButton.setEnabled(false);
recordButton.setEnabled(false);
try {
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(audioFilePath);
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mediaRecorder.prepare();
} catch (Exception e) {
e.printStackTrace();
}
mediaRecorder.start();
}
实现pauseClicked()方法 pauseClicked()方法负责启用“播放”按钮,禁用“暂停”按钮,然后停止并重置MediaRecorder实例。如下面的清单所示,实现此目的的代码如下,并且应将其添加到AudioAppAcitivy.java文件中:
public void pauseClicked (View view)
{
pauseButton.setEnabled(false);
playButton.setEnabled(true);
if (isRecording)
{
recordButton.setEnabled(false);
mediaRecorder.stop();
mediaRecorder.release();
mediaRecorder = null;
isRecording = false;
} else {
mediaPlayer.release();
mediaPlayer = null;
recordButton.setEnabled(true);
}
}