How Do i Stop() the media Recorder? I tried instantiating the
MediaRecorder r;
Globally but,
r.stop()
Does not work, because r is not instantiated.
If it is possible to save the state of this MediaRecorder Instance, and use it with the stop method later on, How do i do it?
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();
}
}
}
EDIT 2:
The Service Starts But the Recorder is not working, the BroadcastReceiver is not working.
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();
}
}
The Error 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)
With your current code your reference to the MediaRecorder is lost once the program execution exits the block it was declared in.
An easy way to store your reference is to eiter do the recording inside of a service (recommended) or to use a singleton which is responsible for handling all the MediaRecording things.
The only thing to keep in mind regarding a singleton is that you may need to do some clean up when your application is destroyed not to leak resources.
http://developer.android.com/guide/components/services.html
Register your broadcast receiver in onCreate in the service and unregistered it in onDestroy.
Something like this (then just start it from your activity or another broadcast receiver). Warning you're probably going to have to fix some compilation errors:
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();
}
}
If you want to start your service when the device boots up consider this stack overflow question: BroadcastReceiver not receiving BOOT_COMPLETED