How to record phone calls in android? - android

I want to make an app which records the incoming and outgoing calls and it run automatically when user get or make any call.

Ok, for this first of all you need to use Device Policy Manager, and need to make your device Admin device. After that you have to create one BroadCast receiver and one service. I am posting code here and its working fine.
MainActivity:
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 0;
private DevicePolicyManager mDPM;
private ComponentName mAdminName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
// Initiate DevicePolicyManager.
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mAdminName = new ComponentName(this, DeviceAdminDemo.class);
if (!mDPM.isAdminActive(mAdminName)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
startActivityForResult(intent, REQUEST_CODE);
} else {
// mDPM.lockNow();
// Intent intent = new Intent(MainActivity.this,
// TrackDeviceService.class);
// startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (REQUEST_CODE == requestCode) {
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
}
}
//DeviceAdminDemo class
public class DeviceAdminDemo extends DeviceAdminReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
public void onEnabled(Context context, Intent intent) {
};
public void onDisabled(Context context, Intent intent) {
};
}
//TService Class
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
private Handler handler;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging == true) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
}
}
}
}
}
//Permission in manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.STORAGE" />
//my_admin.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<force-lock />
</uses-policies>
</device-admin>
//Declare following thing in manifest:
Declare DeviceAdminDemo class to manifest:
<receiver
android:name="com.example.voicerecorder1.DeviceAdminDemo"
android:description="#string/device_description"
android:label="#string/device_admin_label"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/my_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
</intent-filter>
</receiver>
<service android:name=".TService" >
</service>

Below code is working for me to record a outgoing phone call
//Call Recording varibales
private static final String AUDIO_RECORDER_FILE_EXT_3GP = ".3gp";
private static final String AUDIO_RECORDER_FILE_EXT_MP4 = ".mp4";
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private MediaRecorder recorder = null;
private int currentFormat = 0;
private int output_formats[] = { MediaRecorder.OutputFormat.MPEG_4,
MediaRecorder.OutputFormat.THREE_GPP };
private String file_exts[] = { AUDIO_RECORDER_FILE_EXT_MP4,
AUDIO_RECORDER_FILE_EXT_3GP };
AudioManager audioManager;
//put this methods to outside of oncreate() method
private String getFilename() {
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath, AUDIO_RECORDER_FOLDER);
if (!file.exists()) {
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + System.currentTimeMillis() + file_exts[currentFormat]);
}
private MediaRecorder.OnErrorListener errorListener = new MediaRecorder.OnErrorListener() {
#Override
public void onError(MediaRecorder mr, int what, int extra) {
Toast.makeText(CallActivity.this,
"Error: " + what + ", " + extra, Toast.LENGTH_SHORT).show();
}
};
private MediaRecorder.OnInfoListener infoListener = new MediaRecorder.OnInfoListener() {
#Override
public void onInfo(MediaRecorder mr, int what, int extra) {
Toast.makeText(CallActivity.this,
"Warning: " + what + ", " + extra, Toast.LENGTH_SHORT)
.show();
}
};
//below part of code to make your device on speaker
audioManager = (AudioManager)getApplicationContext().getSystemService(Context.AUDIO_SERVICE);
audioManager.setMode(AudioManager.MODE_IN_CALL);
audioManager.setSpeakerphoneOn(true);
//below part of code to start recording
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(output_formats[currentFormat]);
//recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
recorder.setOnErrorListener(errorListener);
recorder.setOnInfoListener(infoListener);
try {
recorder.prepare();
recorder.start();
} catch (IllegalStateException e) {
Log.e("REDORDING :: ",e.getMessage());
e.printStackTrace();
} catch (IOException e) {
Log.e("REDORDING :: ",e.getMessage());
e.printStackTrace();
}
//For stop recording and keep in mind to set speaker off while call end or stop
audioManager.setSpeakerphoneOn(false);
try{
if (null != recorder) {
recorder.stop();
recorder.reset();
recorder.release();
recorder = null;
}
}catch(RuntimeException stopException){
}
And give permission to manifest file,
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

So, basically, I want to combine 2 answers, one from this post and one from another post that I read, don't know the author of it so please sorry for using your methods.
So, here are my classes for achieving desired result:
public class StartActivity extends Activity {
public static final int REQUEST_CODE = 5912;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
PackageManager p = getPackageManager();
ComponentName componentName = new ComponentName(this, StartActivity.class); // activity which is first time open in manifiest file which is declare as <category android:name="android.intent.category.LAUNCHER" />
p.setComponentEnabledSetting(componentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
startService(new Intent(this, StartService.class));
startService(new Intent(this, SmsOutgoingService.class));
try {
// Initiate DevicePolicyManager.
DevicePolicyManager mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName mAdminName = new ComponentName(this, DeviceAdminReciever.class);
if (!mDPM.isAdminActive(mAdminName)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
startActivityForResult(intent, REQUEST_CODE);
} else {
mDPM.lockNow();
finish();
// Intent intent = new Intent(MainActivity.this,
// TrackDeviceService.class);
// startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (REQUEST_CODE == requestCode) {
startService(new Intent(StartActivity.this, TService.class));
finish();
}
super.onActivityResult(requestCode, resultCode, data);
}
}
And my TService class:
public class TService extends Service {
private MediaRecorder recorder;
private File audiofile;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d("StartService", "TService");
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.registerReceiver(new CallReceiver(), filter);
return super.onStartCommand(intent, flags, startId);
}
private void startRecording() {
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
private void stopRecording() {
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
public abstract class PhonecallReceiver extends BroadcastReceiver {
//The receiver will be recreated whenever android feels like it. We need a static variable to remember data between instantiations
private int lastState = TelephonyManager.CALL_STATE_IDLE;
private Date callStartTime;
private boolean isIncoming;
private String savedNumber; //because the passed incoming is only valid in ringing
#Override
public void onReceive(Context context, Intent intent) {
// startRecording();
//We listen to two intents. The new outgoing call only tells us of an outgoing call. We use it to get the number.
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = 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);
}
}
//Derived classes should override these to respond to specific events of interest
protected abstract void onIncomingCallReceived(Context ctx, String number, Date start);
protected abstract void onIncomingCallAnswered(Context ctx, String number, Date start);
protected abstract void onIncomingCallEnded(Context ctx, String number, Date start, Date end);
protected abstract void onOutgoingCallStarted(Context ctx, String number, Date start);
protected abstract void onOutgoingCallEnded(Context ctx, String number, Date start, Date end);
protected abstract void onMissedCall(Context ctx, String number, Date start);
//Deals with actual events
//Incoming call- goes from IDLE to RINGING when it rings, to OFFHOOK when it's answered, to IDLE when its hung up
//Outgoing call- goes from IDLE to OFFHOOK when it dials out, to IDLE when hung up
public void onCallStateChanged(Context context, int state, String number) {
if (lastState == state) {
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = number;
onIncomingCallReceived(context, number, callStartTime);
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
//Transition of ringing->offhook are pickups of incoming calls. Nothing done on them
if (lastState != TelephonyManager.CALL_STATE_RINGING) {
isIncoming = false;
callStartTime = new Date();
startRecording();
onOutgoingCallStarted(context, savedNumber, callStartTime);
} else {
isIncoming = true;
callStartTime = new Date();
startRecording();
onIncomingCallAnswered(context, savedNumber, callStartTime);
}
break;
case TelephonyManager.CALL_STATE_IDLE:
//Went to idle- this is the end of a call. What type depends on previous state(s)
if (lastState == TelephonyManager.CALL_STATE_RINGING) {
//Ring but no pickup- a miss
onMissedCall(context, savedNumber, callStartTime);
} else if (isIncoming) {
stopRecording();
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
} else {
stopRecording();
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
}
public class CallReceiver extends PhonecallReceiver {
#Override
protected void onIncomingCallReceived(Context ctx, String number, Date start) {
Log.d("onIncomingCallReceived", number + " " + start.toString());
}
#Override
protected void onIncomingCallAnswered(Context ctx, String number, Date start) {
Log.d("onIncomingCallAnswered", number + " " + start.toString());
}
#Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
Log.d("onIncomingCallEnded", number + " " + start.toString() + "\t" + end.toString());
}
#Override
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
Log.d("onOutgoingCallStarted", number + " " + start.toString());
}
#Override
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
Log.d("onOutgoingCallEnded", number + " " + start.toString() + "\t" + end.toString());
}
#Override
protected void onMissedCall(Context ctx, String number, Date start) {
Log.d("onMissedCall", number + " " + start.toString());
// PostCallHandler postCallHandler = new PostCallHandler(number, "janskd" , "")
}
}
}
inside TService class you will find CallReceiever class that is going to handle everything you need from the call. You can add parameters as per your will, but, the main point is important.
From your MainActvitiy call Service that will start your Receiever. If you want to record media from receiever directly, you will get errors, so, you need to register Receiever from service. After that, you can call start recording and end recording wherever you like.
Calling return super.onStartCommand(intent, flags, startId); will have that Service lasting for more than one call, so keep that in mind.
Finally, AndroidManifest.xml file:
<manifest
package="your.package.name"
xmlns:android="http://schemas.android.com/apk/res/android"
android:installLocation="internalOnly">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.MODIFY_PHONE_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_SMS"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.STORAGE" />
<application
android:name=".AppController"
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".ui.StartActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<receiver
android:name=".io.boot.DeviceAdminReciever"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/my_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
</intent-filter>
</receiver>
<service android:name=".io.calls.TService" >
</service>
</application>
</manifest>
So, this is it, it's working perfectly with my Samsung Galaxy s6 Edge+, Ive tested it on Galaxy Note 4 and on Samsung J5, a big thank you to the authors of this post and the post about receiving phone calls.

The accepted answer is perfect, except it does not record outgoing calls. Note that for outgoing calls it is not possible (as near as I can tell from scouring many posts) to detect when the call is actually answered (if anybody can find a way other than scouring notifications or logs please let me know). The easiest solution is to just start recording straight away when the outgoing call is placed and stop recording when IDLE is detected. Just adding the same class as above with outgoing recording in this manner for completeness:
private void startRecord(String seed) {
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record" + seed;
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging == true) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
startRecord("incoming");
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
startRecord("outgoing");
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state != null) {
if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
}
}
}
}

The answer of pratt is bit uncomplete, because when you restart your device your app will working stop, recording stop, its become useless.
i m adding some line that copy in your project for complete working of Pratt answer.
<receiver
android:name=".DeviceAdminDemo"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.admin"
android:resource="#xml/device_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.category.HOME" />
</intent-filter>
</receiver>
put this code in onReceive of DeviceAdminDemo
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
context.stopService(new Intent(context, TService.class));
Intent myIntent = new Intent(context, TService.class);
context.startService(myIntent);
}

There is a simple solution to this problem using this library. I store an instance of the CallRecord class in MyService.class. When the service is first initialized, the following code is executed:
public class MyService extends Service {
public static CallRecord callRecord;
#Override
public void onCreate() {
super.onCreate();
callRecord = new CallRecord.Builder(this)
.setRecordFileName("test")
.setRecordDirName("Download")
.setRecordDirPath(Environment.getExternalStorageDirectory().getPath()) // optional & default value
.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB) // optional & default value
.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB) // optional & default value
.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION) // optional & default value
.setShowSeed(false) // optional, default=true ->Ex: RecordFileName_incoming.amr || RecordFileName_outgoing.amr
.build();
callRecord.enableSaveFile();
callRecord.startCallReceiver();
}
#Override
public void onDestroy() {
super.onDestroy();
callRecord.stopCallReceiver();
}
}
Next, do not forget to specify permissions in the manifest. (I may have some extras here, but keep in mind that some of them are necessary only for newer versions of Android)
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.PROCESS_INCOMING_CALLS" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Also it is crucial to request some permissions at the first start of the application. A guide is provided here.
If my code doesn't work, alternative code can be found here. I hope I helped you.

Related

Unstoppable Service not working

I'm trying to use an unstoppable background service so that I can get call detail for the new call in the alert dialog every time and notify the user with an alert dialog. The problem is that service is stopped after close app. I'm not entirely sure what I have wrong.
I've tested on my phone it's working fine even after closing the app
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.jenya1.didbizdialer">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-permission android:name="android.permission.READ_CALL_LOG" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.ACTION_MANAGE_OVERLAY_PERMISSION" />
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme.NoActionBar">
<activity android:name=".activity.MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".activity.DialerActivity"></activity>
<service android:name=".service.PhoneCallStatesService"
android:stopWithTask="false" />
<receiver android:name=".service.ReceiverCall">
<intent-filter>
<action android:name="com.android.techtrainner" />
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
</application>
The BootReceiver should start the Service
public class ReceiverCall extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("Service Stops", "Ohhhhhhh");
context.startService(new Intent(context, PhoneCallStatesService.class));;
}
}
The service PhoneCallStatesService is set to display a call details dialog
public class PhoneCallStatesService extends Service {
private static final String TAG = PhoneCallStatesService.class.getSimpleName();
private TelephonyManager telephonyManager;
private PhoneStateListener listener;
private boolean isOnCall;
private static boolean isIncoming;
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static String savedNumber; //because the passed incoming is only valid in ringing
public IBinder onBind(Intent arg0) {
return null;
}
#Override
public void onCreate() {
super.onCreate();
showToast("service started");
isOnCall = false;
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
}
protected BroadcastReceiver stopReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "received stop broadcast");
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
listener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if(lastState == state){
//No change, debounce extras
return;
}
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
if(lastState == TelephonyManager.CALL_STATE_RINGING){
//Ring but no pickup- a miss
onMissedCall(getApplicationContext(), savedNumber, callStartTime);
}
else if(isIncoming){
onIncomingCallEnded(getApplicationContext(), savedNumber, callStartTime, new Date());
}
else{
onOutgoingCallEnded(getApplicationContext(), savedNumber, callStartTime, new Date());
}
if (isOnCall) {
showToast("Call state: idle");
isOnCall = false;
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(lastState != TelephonyManager.CALL_STATE_RINGING){
isIncoming = false;
callStartTime = new Date();
showToast("Outgoing start ");
onOutgoingCallStarted(getApplicationContext(), savedNumber, callStartTime);
}
else
{
isIncoming = true;
callStartTime = new Date();
showToast("Incoming answered ");
onIncomingCallAnswered(getApplicationContext(), savedNumber, callStartTime);
}
isOnCall = true;
break;
case TelephonyManager.CALL_STATE_RINGING:
isIncoming = true;
callStartTime = new Date();
savedNumber = incomingNumber;
onIncomingCallReceived(getApplicationContext(), incomingNumber, callStartTime);
showToast("call state: ringing");
break;
}
lastState = state;
}
};
// Register the listener with the telephony manager
telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
return START_STICKY;
}
protected void onIncomingCallReceived(Context ctx, String number, Date start)
{
Toast.makeText(ctx, "received", Toast.LENGTH_SHORT).show();
Log.e("received","received");
}
protected void onIncomingCallAnswered(Context ctx, String number, Date start)
{
Toast.makeText(ctx, "upadyo", Toast.LENGTH_SHORT).show();
Log.e("upadyo","upadyo");
}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end)
{
Toast.makeText(ctx, "incoming call end", Toast.LENGTH_SHORT).show();
Log.e("incoming call end","incoming call end");
startactivity(ctx);
}
protected void onOutgoingCallStarted(Context ctx, String number, Date start)
{
Toast.makeText(ctx, "outcall call start", Toast.LENGTH_SHORT).show();
Log.e("outcall call start","outcall call start");
}
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end)
{
Toast.makeText(ctx, "Outgoing call end", Toast.LENGTH_SHORT).show();
Log.e("Outgoing call end","Outgoing call end");
startactivity(ctx);
}
protected void onMissedCall(Context ctx, String number, Date start)
{
Toast.makeText(ctx, "missed call", Toast.LENGTH_SHORT).show();
Log.e("missed call","missed call");
startactivity(ctx);
}
private void showToast(String msg) {
Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
}
public void startactivity(final Context ctx) {
AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(ctx, R.style.myDialog);
LayoutInflater inflater = (LayoutInflater)ctx.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View dialogView = inflater.inflate(R.layout.popupdialog, null);
dialogBuilder.setView(dialogView);
LinearLayout reminder=(LinearLayout)dialogView.findViewById(R.id.lnreminder);
LinearLayout savecontact=(LinearLayout)dialogView.findViewById(R.id.lnsavecontact);
LinearLayout contactblock=(LinearLayout)dialogView.findViewById(R.id.lnspam);
AlertDialog alertDialog = dialogBuilder.create();
WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
lp.copyFrom(alertDialog.getWindow().getAttributes());
lp.width = WindowManager.LayoutParams.MATCH_PARENT;
lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
lp.gravity = Gravity.BOTTOM;
lp.windowAnimations = R.style.DialogAnimation;
alertDialog.getWindow().setAttributes(lp);
alertDialog.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ALERT);
alertDialog.show();
reminder.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(ctx, "reminder", Toast.LENGTH_SHORT).show();
}
});
savecontact.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(ctx, "Saved", Toast.LENGTH_SHORT).show();
}
});
contactblock.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Toast.makeText(ctx, "block", Toast.LENGTH_SHORT).show();
}
});
}
#Override
public void onDestroy() {
try{
if(stopReceiver!=null)
unregisterReceiver(stopReceiver);
stopSelf();
}catch(Exception e)
{
Log.e("Service Destroy Error",e.getMessage());
}
}
}
Any help or example would be highly appreciated
In Redmi devices, the service gets killed after you close the app although you have written all the code to restart it after killing the app. You need to enable Autostart for this particular app.
Apps such as WhatsApp etc have their services running because they have marked their apps with Xiaomi. But we can't do it.
Or you can use JobScheduler or AlarmManager to make your service run.

Record call even after my app is closed and cleared from recents

I am developing an Android application, where I have asked to implement the call record ,I have gone through SO and found One Solution which is working fine when my app is opened. If I close my app or clear it from recent apps, Call record is not working. Tried searching in the Google and SO but no luck. I am posting my code here, Can some one help me in getting the solution.
CallreCorder Service class:
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
private Handler handler;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging == true) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
Log.d("TService", "onReceive: "+sampleDir);
String file_name = "Outgoing";
try {
audiofile = File.createTempFile(file_name, ".wav", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
// recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
Log.d("TService", "onReceive: "+sampleDir);
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".wav", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
// recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.DEFAULT);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
}
LocalBroadcastManager.getInstance(context).sendBroadcast(new Intent("callRecord"));
}
}
}
Receiver class:
public class DeviceAdminDemo extends DeviceAdminReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
public void onEnabled(Context context, Intent intent) {
};
public void onDisabled(Context context, Intent intent) {
};
}
MainActivity Class
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 0;
private DevicePolicyManager mDPM;
private ComponentName mAdminName;
private static final int PERMISSION_REQUEST_CODE= 123;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if (checkPermission()){
Toast.makeText(this, "Permission granted", Toast.LENGTH_SHORT).show();
}else{
requestPermission();
}
try {
// Initiate DevicePolicyManager.
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mAdminName = new ComponentName(this, DeviceAdminDemo.class);
if (!mDPM.isAdminActive(mAdminName)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
startActivityForResult(intent, REQUEST_CODE);
} else {
// mDPM.lockNow();
// Intent intent = new Intent(MainActivity.this,
// TrackDeviceService.class);
// startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
LocalBroadcastManager.getInstance(MainActivity.this).registerReceiver(receiver, new IntentFilter("callRecord"));
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equalsIgnoreCase("callRecord")) {
Toast.makeText(MainActivity.this, "Call record", Toast.LENGTH_SHORT).show();
}
}
};
private boolean checkPermission(){
if (ContextCompat.checkSelfPermission(MainActivity.this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
return true;
}else{
return false;
}
}
private void requestPermission(){
if (ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.ACCESS_FINE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.ACCESS_COARSE_LOCATION)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.CALL_PHONE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.SEND_SMS)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this,Manifest.permission.READ_CONTACTS)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_PHONE_STATE)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.PROCESS_OUTGOING_CALLS)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.RECORD_AUDIO)
|| ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.CAPTURE_AUDIO_OUTPUT)){
Toast.makeText(MainActivity.this,"Allow Us pemissions. Please allow in App Settings for additional functionality.",Toast.LENGTH_LONG).show();
} else {
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.CALL_PHONE, Manifest.permission.SEND_SMS, Manifest.permission.READ_CONTACTS,
Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_PHONE_STATE,
Manifest.permission.PROCESS_OUTGOING_CALLS, Manifest.permission.RECORD_AUDIO, Manifest.permission.CAPTURE_AUDIO_OUTPUT}, PERMISSION_REQUEST_CODE);
}
}
#Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
switch (requestCode) {
case PERMISSION_REQUEST_CODE:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
Toast.makeText(this, "Permission Granted, ", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Permission not Granted", Toast.LENGTH_SHORT).show();
}
break;
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (REQUEST_CODE == requestCode) {
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
}
#Override
public void onResume() {
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, new IntentFilter("callRecord"));
super.onResume();
}
#Override
public void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
}
}
Manifest file
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.practice.callrecorder">
<uses-permission android:name="android.permission.CAPTURE_AUDIO_OUTPUT"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.SEND_SMS"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:roundIcon="#mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver
android:name=".DeviceAdminDemo"
android:description="#string/app_name"
android:label="#string/app_name"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/my_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
</intent-filter>
</receiver>
<service
android:name=".TService"
android:enabled="true"
android:exported="true">
</service>
</application>
my_admin.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<force-lock />
</uses-policies>
any help would be grateful!!!
Thanks in advance!!
use START_STICKY as return param of onStartCommand() so when you kill you app it will restart the service
for reference you can check android developer guide
https://developer.android.com/reference/android/app/Service.html

Outgoing calls not recording

I am trying add one thing in my app. What i am trying is whenever user get phone call or user make phone call, at same time recording should be start and recording must store in sd card after cutting the call.
Issues
1)Incoming call record work sometimes
2)Outgoing not working
MainActivity.java
public class MainActivity extends AppCompatActivity {
private static final int REQUEST_CODE = 0;
private DevicePolicyManager mDPM;
private ComponentName mAdminName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PackageManager p = getPackageManager();
p.setComponentEnabledSetting(getComponentName(), PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);
try {
// Initiate DevicePolicyManager.
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mAdminName = new ComponentName(this, DeviceAdminDemo.class);
if (!mDPM.isAdminActive(mAdminName)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
startActivityForResult(intent, REQUEST_CODE);
} else {
// mDPM.lockNow();
// Intent intent = new Intent(MainActivity.this,
// TrackDeviceService.class);
// startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (REQUEST_CODE == requestCode) {
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
}
}
TService
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging == true) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
System.out.println("PATH"+path);
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
}
}
}
}
}
Remove this if (wasRinging == true) from TService, this wasRining Boolean checks if the phone was ringing some time before, i.e. when phone receives a call, in case of outgoing call it stays false so, the recorder part is skipped. Just change that and it should work.
Just replace your TService code with this..
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
public boolean didMakeACall = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging || didMakeACall) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
System.out.println("PATH"+path);
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
didMakeACall = true;
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
}
}
}
}
}
I'm afraid community wouldn't like external links here so I'm posting my quick demo project here...
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS"/>
<uses-permission android:name="android.permission.RECORD_AUDIO"/>
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".TService"/>
</application>
MainActivity.java
I'm starting TService in its onCreate method, please note that this could be any activity in your project, or any context you can start a service from.
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
startService(new Intent(this, TService.class));
}
}
and now finally,
TService.java
I've tested this in Kitkat and Lollipop and it's working, for newer versions you need to explicitly ask for Manifest permissions during run time and it should work just as fine.
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
boolean didMakeACall = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging || didMakeACall) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/MyRecorder");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
System.out.println("PATH"+path);
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
didMakeACall = true;
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
}
}
}
}
}

How to record calls in android [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking us to recommend or find a tool, library or favorite off-site resource are off-topic for Stack Overflow as they tend to attract opinionated answers and spam. Instead, describe the problem and what has been done so far to solve it.
Closed 8 years ago.
Improve this question
I am new to android.I have seen many examples.but all doesn't help me.I want example or tutorial for How to Record incoming and outgoing calls in android.can anyone refer good tutorial for this?
Ok, for this first of all you need to use Device Policy Manager, and need to make your device Admin device. After that you have to create one BroadCaast receiver and one service. I am posting code here and its working fine.
MainActivity:
public class MainActivity extends Activity {
private static final int REQUEST_CODE = 0;
private DevicePolicyManager mDPM;
private ComponentName mAdminName;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
try {
// Initiate DevicePolicyManager.
mDPM = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
mAdminName = new ComponentName(this, DeviceAdminDemo.class);
if (!mDPM.isAdminActive(mAdminName)) {
Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mAdminName);
intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION, "Click on Activate button to secure your application.");
startActivityForResult(intent, REQUEST_CODE);
} else {
// mDPM.lockNow();
// Intent intent = new Intent(MainActivity.this,
// TrackDeviceService.class);
// startService(intent);
}
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (REQUEST_CODE == requestCode) {
Intent intent = new Intent(MainActivity.this, TService.class);
startService(intent);
}
}
}
//DeviceAdminDemo class
public class DeviceAdminDemo extends DeviceAdminReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
}
public void onEnabled(Context context, Intent intent) {
};
public void onDisabled(Context context, Intent intent) {
};
}
//TService Class
public class TService extends Service {
MediaRecorder recorder;
File audiofile;
String name, phonenumber;
String audio_format;
public String Audio_Type;
int audioSource;
Context context;
private Handler handler;
Timer timer;
Boolean offHook = false, ringing = false;
Toast toast;
Boolean isOffHook = false;
private boolean recordstarted = false;
private static final String ACTION_IN = "android.intent.action.PHONE_STATE";
private static final String ACTION_OUT = "android.intent.action.NEW_OUTGOING_CALL";
private CallBr br_call;
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onDestroy() {
Log.d("service", "destroy");
super.onDestroy();
}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// final String terminate =(String)
// intent.getExtras().get("terminate");//
// intent.getStringExtra("terminate");
// Log.d("TAG", "service started");
//
// TelephonyManager telephony = (TelephonyManager)
// getSystemService(Context.TELEPHONY_SERVICE); // TelephonyManager
// // object
// CustomPhoneStateListener customPhoneListener = new
// CustomPhoneStateListener();
// telephony.listen(customPhoneListener,
// PhoneStateListener.LISTEN_CALL_STATE);
// context = getApplicationContext();
final IntentFilter filter = new IntentFilter();
filter.addAction(ACTION_OUT);
filter.addAction(ACTION_IN);
this.br_call = new CallBr();
this.registerReceiver(this.br_call, filter);
// if(terminate != null) {
// stopSelf();
// }
return START_NOT_STICKY;
}
public class CallBr extends BroadcastReceiver {
Bundle bundle;
String state;
String inCall, outCall;
public boolean wasRinging = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_IN)) {
if ((bundle = intent.getExtras()) != null) {
state = bundle.getString(TelephonyManager.EXTRA_STATE);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
inCall = bundle.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
wasRinging = true;
Toast.makeText(context, "IN : " + inCall, Toast.LENGTH_LONG).show();
} else if (state.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (wasRinging == true) {
Toast.makeText(context, "ANSWERED", Toast.LENGTH_LONG).show();
String out = new SimpleDateFormat("dd-MM-yyyy hh-mm-ss").format(new Date());
File sampleDir = new File(Environment.getExternalStorageDirectory(), "/TestRecordingDasa1");
if (!sampleDir.exists()) {
sampleDir.mkdirs();
}
String file_name = "Record";
try {
audiofile = File.createTempFile(file_name, ".amr", sampleDir);
} catch (IOException e) {
e.printStackTrace();
}
String path = Environment.getExternalStorageDirectory().getAbsolutePath();
recorder = new MediaRecorder();
// recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_CALL);
recorder.setAudioSource(MediaRecorder.AudioSource.VOICE_COMMUNICATION);
recorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_NB);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(audiofile.getAbsolutePath());
try {
recorder.prepare();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
recorder.start();
recordstarted = true;
}
} else if (state.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
wasRinging = false;
Toast.makeText(context, "REJECT || DISCO", Toast.LENGTH_LONG).show();
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
}
}
} else if (intent.getAction().equals(ACTION_OUT)) {
if ((bundle = intent.getExtras()) != null) {
outCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, "OUT : " + outCall, Toast.LENGTH_LONG).show();
}
}
}
}
}
//Permission in manifest file
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.STORAGE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
//Declare following thing in manifest:
Declare DeviceAdminDemo class to manifest:
<receiver
android:name="com.example.voicerecorder1.DeviceAdminDemo"
android:description="#string/device_description"
android:label="#string/device_admin_label"
android:permission="android.permission.BIND_DEVICE_ADMIN" >
<meta-data
android:name="android.app.device_admin"
android:resource="#xml/my_admin" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLED" />
<action android:name="android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED" />
</intent-filter>
</receiver>
<service android:name=".TService" >
</service>
//my_admin.xml
<device-admin xmlns:android="http://schemas.android.com/apk/res/android" >
<uses-policies>
<force-lock />
</uses-policies>
</device-admin>
well you could use an android app called Call Recorder from Google Play
Call Recorder
i've never tried it before but it was the first link in go*gle
good luck with that.
Aaron PM

Android : Can't call BroadcastReceiver Class using Activity

Here is my code. I am not able to call my receiver class from main activity class. Please help.
public class RecorderActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
Intent i = new Intent(this, CallRecorder.class);
startActivity(i);
}
}
/////////////////////////////////////
class CallRecorder extends BroadcastReceiver {
private static final String AUDIO_RECORDER_FOLDER = "AudioRecorder";
private MediaRecorder recorder = null;
boolean recordstarted = false;
String phonenbr = null;
TelephonyManager telManager;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equalsIgnoreCase(Intent.ACTION_ANSWER))
{
try
{
phonenbr = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Log.v("GDHGDHGHDGDHGDHGHDGHDGH", phonenbr);
recorder = new MediaRecorder();
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
recorder.setOutputFile(getFilename());
recorder.prepare();
recorder.start();
recordstarted = true;
telManager = (TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE);
}
catch(Exception e)
{
e.printStackTrace();
}
final PhoneStateListener phoneListener = new PhoneStateListener()
{
#Override
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
//
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
//
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
if (recordstarted) {
recorder.stop();
recordstarted = false;
}
break;
}
default: { }
}
} catch (Exception ex) {
}
}
};
telManager.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
private String getFilename(){
String filepath = Environment.getExternalStorageDirectory().getPath();
File file = new File(filepath,AUDIO_RECORDER_FOLDER);
if(!file.exists()){
file.mkdirs();
}
return (file.getAbsolutePath() + "/" + phonenbr + System.currentTimeMillis() + ".mp4");
}
}
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<receiver android:name=".CallRecorder" android:enabled="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.PHONE_STATE" />
</intent-filter>
</receiver>
<activity
android:name=".RecorderActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
BroadcastReceiver receiver = new CallRecorder();
in Youractivity.onStart() :
IntentFilter intentFilter = new ItentFilter("some_string-to_call_receiver");
registerReceiver(receiver, intentFilter);
and in Youractivity.onStop() :
uregisterReceiver(receiver);
and call your receiver everywhere:
sendBroadcast(new Intent("some_string-to_call_receiver"));

Categories

Resources