如何停止()媒体记录器? 我试过实例化
MediaRecorder r;
全球但是,
r.stop()
不起作用,因为r未实例化。
如果可以保存此MediaRecorder实例的状态,并在稍后使用stop方法,我该怎么做?
public class nCallRecorder extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
//start recording
String CallNo = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
MediaRecorder r = new MediaRecorder();
r.setAudioSource(MediaRecorder.AudioSource.MIC);
r.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
r.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
r.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+CallNo+".mp4");
try { r.prepare(); } catch(IOException e) { e.printStackTrace(); }
r.start();
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE)) {
//stop recording
Toast.makeText(context,"Call Ends",Toast.LENGTH_LONG).show();
}
}
}
编辑2:
服务启动但是Recorder无法正常工作,BroadcastReceiver无法正常工作。
的AndroidManifest.xml
<service android:name=".RecordService">
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</service>
RecordService.java
public class RecordService extends Service {
private MediaRecorder r = null;
@Override
public IBinder onBind(Intent arg0) {
return null;
}
private final BroadcastReceiver receiver = new BroadcastReceiver () {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
String CallNo = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
onCreate();
r = new MediaRecorder();
r.setAudioSource(MediaRecorder.AudioSource.MIC);
r.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
r.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
r.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/l"+CallNo+".mp4");
try { r.prepare(); } catch(IOException e) { e.printStackTrace(); }
r.start();
Toast.makeText(context,"Recording Started",Toast.LENGTH_LONG).show();
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE)) {
cleanUp();
Toast.makeText(context,"Call Ends",Toast.LENGTH_LONG).show();
}
}
};
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Service Started", Toast.LENGTH_LONG).show();
return START_STICKY;
}
private void cleanUp() {
if(r != null) {
try {
r.stop();
} catch (Exception ex) {
} finally {
r.release();
r = null;
}
}
}
public void onCreate() {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver,filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(receiver);
cleanUp();
Toast.makeText(this, "Service Destroyed", Toast.LENGTH_LONG).show();
}
}
错误Logcat:
Process: com.alivezoned.callrecorder, PID: 2864
java.lang.RuntimeException: Error receiving broadcast Intent { act=android.intent.action.PHONE_STATE flg=0x10 (has extras) } in com.alivezoned.callrecorder.RecordService$1@355ef143
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:871)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
Caused by: java.lang.RuntimeException: start failed.
at android.media.MediaRecorder.start(Native Method)
at com.alivezoned.callrecorder.RecordService$1.onReceive(RecordService.java:34)
at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:861)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:135)
at android.app.ActivityThread.main(ActivityThread.java:5221)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:899)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:694)
答案 0 :(得分:2)
使用当前代码,一旦程序执行退出声明的块,就会丢失对MediaRecorder的引用。
存储引用的一种简单方法是在服务内部进行录制(推荐)或使用负责处理所有MediaRecording内容的单例。
关于单例的唯一要记住的是,当您的应用程序被销毁时,您可能需要进行一些清理,以免泄漏资源。
http://developer.android.com/guide/components/services.html
在服务中的onCreate中注册您的广播接收器,并在onDestroy中取消注册。
像这样的东西(然后从你的活动或其他广播接收器开始)。警告您可能需要修复一些编译错误:
public class MyService extends Service {
private MediaRecorder mMediaRecorder;
private final BroadcastReceiver mTelephonyReceiver = new BroadcastReceiver () {
@Override
public void onReceive(Context context, Intent intent) {
// Changed order of equals to avoid extra null check.
if (mMediaRecorder == null && TelephonyManager.EXTRA_STATE_RINGING.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE)) {
//start recording
String CallNo = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
mMediaRecorder = new MediaRecorder();
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
mMediaRecorder.setOutputFile(Environment.getExternalStorageDirectory().getAbsolutePath()+"/"+CallNo+".mp4");
try { mMediaRecorder.prepare(); } catch(IOException e) { e.printStackTrace(); }
mMediaRecorder.start();
} else if (TelephonyManager.EXTRA_STATE_IDLE.equals(intent.getStringExtra(TelephonyManager.EXTRA_STATE)) {
//stop recording
cleanUp();
Toast.makeText(context,"Call Ends",Toast.LENGTH_LONG).show();
}
}
}
private void cleanUp() {
if(mMediaRecorder != null) {
try {
mMediaRecorder.stop();
} catch (IOException ex) {
// Add your handling here.
} finally {
mMediaRecorder.release();
mMediaRecorder = null;
}
}
}
public void onCreate () {
super.onCreate();
IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_YOUR_ACTION);
registerReceiver(mTelephonyReceiver, filter);
}
public int onStartCommand(Intent intent, int flags, int startId) {
return START_STICKY;
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(mTelephonyReceiver);
cleanUp();
}
}
如果要在设备启动时启动服务,请考虑此堆栈溢出问题: BroadcastReceiver not receiving BOOT_COMPLETED
答案 1 :(得分:0)
请在异常中插入您的代码,然后尝试。
MediaRecorder mRecorder = new MediaRecorder();
File mFile = new File("The output file's absolutePath");
... //config the mRecorder
mRecorder.setOutputFile(mFile.getAbsolutePath());
... //prepare() ...
mRecorder.start();
try {
mRecorder.stop();
} catch(RuntimeException e) {
mFile.delete(); //you must delete the outputfile when the recorder stop failed.
} finally {
mRecorder.release();
mRecorder = null;
}