- Forum posts: 1
Jul 31, 2017, 6:38:17 PM via Website
Jul 31, 2017 6:38:17 PM via Website
I have an activity and a service. Activity starts the service at runtime. All work is being done in Service (Registering broadcast receiver, recording and saving file). The problem is when i disconnect the call, recording doesn't stop, it continues to record. If i try to play that audio file after disconnecting call, it says "sorry, the player cann't play this audio file for it is modified or deleted." After several minutes it stopped automatically and then i am able to play that audio file (which has length of several minutes). I want to stop and save that audio file when call disconnects. Here is my code.
public class MyService extends Service {
MediaRecorder mr;
boolean isRecording;
NotificationManager notificationManager;
public MyService() {
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
IntentFilter filter = new IntentFilter();
filter.addAction("android.intent.action.NEW_OUTGOING_CALL");
filter.addAction("android.intent.action.PHONE_STATE");
this.registerReceiver(new Broad(), filter);
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
Toast.makeText(this, "Record Service Destroyed", Toast.LENGTH_LONG).show();
super.onDestroy();
}
public void startRecording() {
mr = new MediaRecorder();
mr.setAudioSource(MediaRecorder.AudioSource.MIC);
mr.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mr.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
mr.setOutputFile(getFilename().toString());
try {
mr.prepare();
} catch (IOException e) {
e.printStackTrace();
}
try {
mr.start();
createNotification();
isRecording = true;
} catch (Exception e) {
Toast.makeText(this, " " + e, Toast.LENGTH_SHORT).show();
}
}
public void stopRecording() {
if (isRecording) {
mr.stop();
mr.release();
isRecording = false;
notificationManager.cancel(0);
}
}
private String getFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath, "AudioRecorder");
if (!file.exists()) {
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + ".amr");
}
public void createNotification() {
Notification noti = new Notification.Builder(this)
.setContentTitle("Recording started...")
.setContentText("Recording started...")
.setSmallIcon(R.drawable.recordericon)
.build();
notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.notify(0, noti);
}
public class Broad extends BroadcastReceiver {
int laststate = TelephonyManager.CALL_STATE_IDLE;
Date callStartTime;
boolean isRecording;
String savedNum;
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNum = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
} else {
String stateStr = intent.getExtras().getString(TelephonyManager.EXTRA_STATE);
String number = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
int state = 0;
if (stateStr.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateStr.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
onCallStateChanged(context, state, number);
}
}
public void onCallStateChanged(Context context, int state, String number) {
if (laststate == state) {
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isRecording = true;
callStartTime = new Date();
savedNum = number;
String stamp1 = "onIncomingCallReceived" + number + " " + callStartTime.toString();
Toast.makeText(context, "" + stamp1, Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (laststate != TelephonyManager.CALL_STATE_RINGING) {
isRecording = false;
callStartTime = new Date();
startRecording();
String stamp2 = "onOutgoingCallStarted" + number + " " + callStartTime.toString();
Toast.makeText(context, "" + stamp2, Toast.LENGTH_LONG).show();
} else {
isRecording = true;
callStartTime = new Date();
startRecording();
String stamp3 = "onIncomingCallAnswered" + number + " " + callStartTime.toString();
Toast.makeText(context, "" + stamp3, Toast.LENGTH_LONG).show();
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if (laststate == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
String stamp4 = "onMissedCall" + number + " " + callStartTime.toString();
Toast.makeText(context, "" + stamp4, Toast.LENGTH_LONG).show();
} else if (isRecording) {
stopRecording();
String stamp5 = "onIncomingCallEnded" + number + " " + callStartTime.toString() + "\t" + new Date().toString();
Toast.makeText(context, "" + stamp5, Toast.LENGTH_LONG).show();
} else {
stopRecording();
String stamp6 = "onOutgoingCallEnded" + number + " " + callStartTime.toString() + "\t" + new Date().toString();
Toast.makeText(context, "" + stamp6, Toast.LENGTH_LONG).show();
}
}
}
}
}
Here is manifest.xml
android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
android:allowBackup="true"
android:icon="@drawable/recordericon"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> <service android:name=".MyService" android:enabled="true" android:exported="true"></service> </application>