Reputation: 681
I'm developing an app that will only be used in house for testing purpose. I have searched a lot and tried different suggestions as suggested in different post but none seems to be working for me.
I'm open to any suggestions like Reflections, Accessibility Service, root or any other hack. Please help.
Regards
Upvotes: 1
Views: 3591
Reputation: 314
You can use accessibility events to detect the call duration and from that you can detect if the outgoing call is answered or not..
I have answered it in detail in Here` you can check that.
Upvotes: 1
Reputation: 103
TRY THIS
Set all required permission in manifest.xml file.
Call this class in Service
public class PhoneListener extends PhoneStateListener {
private static PhoneListener instance = null;
/**
* Must be called once on app startup
*
* @param context - application context
* @return
*/
public static PhoneListener getInstance(Context context) {
if (instance == null) {
instance = new PhoneListener(context);
}
return instance;
}
public static boolean hasInstance() {
return null != instance;
}
private final Context context;
private CallLog phoneCall;
private PhoneListener(Context context) {
this.context = context;
}
AtomicBoolean isRecording = new AtomicBoolean();
AtomicBoolean isWhitelisted = new AtomicBoolean();
/**
* Set the outgoing phone number
* <p/>
* Called by {@link MyCallReceiver} since that is where the phone number is available in a outgoing call
*
* @param phoneNumber
*/
public void setOutgoing(String phoneNumber) {
if (null == phoneCall)
phoneCall = new CallLog();
phoneCall.setPhoneNumber(phoneNumber);
phoneCall.setOutgoing();
// called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
}
@Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE: // Idle... no call
if (isRecording.get()) {
RecordCallService.stopRecording(context);
phoneCall = null;
isRecording.set(false);
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK: // Call answered
if (isWhitelisted.get()) {
isWhitelisted.set(false);
return;
}
if (!isRecording.get()) {
isRecording.set(true);
// start: Probably not ever usefull
if (null == phoneCall)
phoneCall = new CallLog();
if (!incomingNumber.isEmpty()) {
phoneCall.setPhoneNumber(incomingNumber);
}
// end: Probably not ever usefull
RecordCallService.sartRecording(context, phoneCall);
}
break;
case TelephonyManager.CALL_STATE_RINGING: // Phone ringing
// DO NOT try RECORDING here! Leads to VERY poor quality recordings
// I think something is not fully settled with the Incoming phone call when we get CALL_STATE_RINGING
// a "SystemClock.sleep(1000);" in the code will allow the incoming call to stabilize and produce a good recording...(as proof of above)
if (null == phoneCall)
phoneCall = new CallLog();
if (!incomingNumber.isEmpty()) {
phoneCall.setPhoneNumber(incomingNumber);
// called here so as not to miss recording part of the conversation in TelephonyManager.CALL_STATE_OFFHOOK
isWhitelisted.set(Database.isWhitelisted(context, phoneCall.getPhoneNumber()));
}
break;
}
}
}
And use Broadcast Receiver
public class MyCallReceiver extends BroadcastReceiver {
public MyCallReceiver() {
}
static TelephonyManager manager;
@Override
public void onReceive(Context context, Intent intent) {
Log.i("JLCreativeCallRecorder", "MyCallReceiver.onReceive ");
if (!AppPreferences.getInstance(context).isRecordingEnabled()) {
removeListener();
return;
}
if (Intent.ACTION_NEW_OUTGOING_CALL.equals(intent.getAction())) {
if (!AppPreferences.getInstance(context).isRecordingOutgoingEnabled()) {
removeListener();
return;
}
PhoneListener.getInstance(context).setOutgoing(intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER));
} else {
if (!AppPreferences.getInstance(context).isRecordingIncomingEnabled()) {
removeListener();
return;
}
}
// Start Listening to the call....
if (null == manager) {
manager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
}
if (null != manager)
manager.listen(PhoneListener.getInstance(context), PhoneStateListener.LISTEN_CALL_STATE);
}
private void removeListener() {
if (null != manager) {
if (PhoneListener.hasInstance())
manager.listen(PhoneListener.getInstance(null), PhoneStateListener.LISTEN_NONE);
}
}
}
I hope you get some help from this code.
Thanks
Upvotes: 0
Reputation: 902
You need this permission in manifest
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
TelephonyManager
has a listener to get phone state. implement this tho know if the phone is ringing or in a call.
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener callStateListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
// TODO React to a incoming call.
try {
if (state == TelephonyManager.CALL_STATE_RINGING) {
Toast.makeText(getApplicationContext(), "Phone Is Ringing" + incomingNumber, Toast.LENGTH_LONG).show();
number = incomingNumber;
//g.setPhoneNo(incomingNumber);
AndroidNetCommunicationClientActivity.mMsgSendRequest("CommandMsgCallIncoming" + number);
} else if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
Toast.makeText(getApplicationContext(), "Phone is Currently in A call" + incomingNumber, Toast.LENGTH_LONG).show();
//number = mIntent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
number = incomingNumber;
} else if (state == TelephonyManager.DATA_DISCONNECTED) {
number = "";
CallID = "";
}
} catch (Exception e) {
// TODO Auto-generated catch block
//conn.MessageBox(MainActivity.this, e.getMessage());
e.printStackTrace();
}
super.onCallStateChanged(state, incomingNumber);
}
};
telephonyManager.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
Upvotes: -1