I want to block out going calls based on some logic.
I am using below code
public class OutgoingCallReceiver extends BroadcastReceiver {
private OutgoingCallListener customPhoneListener = null;
public static boolean check = true;
#Override
public void onReceive(Context context, Intent intent) {
String originalNumber = intent
.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
TelephonyManager telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
customPhoneListener = new OutgoingCallListener(context,
originalNumber);
telephony.listen(customPhoneListener,
PhoneStateListener.LISTEN_CALL_STATE);
}
}
}
// Blocking call
public void blockCall(Context context) {
try {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony telephonyService = (ITelephony) m.invoke(tm);
telephonyService = (ITelephony) m.invoke(tm);
// telephonyService.silenceRinger();
telephonyService.endCall();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<receiver android:name="com.demo.example.OutgoingCallReceiver" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
The issue is :: When i am calling from my mobile. Onreceive is calling multiple times and it giving different numbers.
Please help me. Thank you.
I am also facing same issue. It's because of using .
Here first store your number in some object. see my code below.
<receiver android:name="com.perumaltt.cloud.receiver.ProcessCall" >
<intent-filter>
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
public class ProcessCall extends BroadcastReceiver {
public static String number;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
String originalNumber = intent
.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
System.out.println("originalNumber :::: " + originalNumber);
if (originalNumber != null) {
number = originalNumber;
}
TelephonyManager telephony = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
MyPhoneStateListener listener = new MyPhoneStateListener(context,originalNumber);
telephony.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
// My listener
public class MyPhoneStateListener extends PhoneStateListener {
Context context;
String outGoingCall;
public MyPhoneStateListener(Context context, String outGoingCall) {
super();
this.context = context;
this.outGoingCall = outGoingCall;
}
#Override
public void onCallStateChanged(int state, String callingNumber) {
System.out.println("callingNumber MyPhoneStateListener before"
+ callingNumber);
// Log.i("callingNumber :::: MyPhoneStateListener ", outGoingCall);
// if(callingNumber == null || callingNumber.trim().length() < 3){
// return;
// }
// if(outGoingCall == null || outGoingCall.trim().length() < 3){
// return;
// }
System.out.println("callingNumber MyPhoneStateListener after"
+ callingNumber);
System.out.println("state ::: "+state);
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// handle out going call
callOut(outGoingCall);
break;
case TelephonyManager.CALL_STATE_RINGING:
// handle in coming call
endCallIfBlocked(callingNumber);
break;
default:
break;
}
super.onCallStateChanged(state, callingNumber);
}
synchronized private void callOut(String outGoingCall1) {
if(outGoingCall1 == null){
return;
}
if(ProcessCall.number.equalsIgnoreCase(outGoingCall1)){
System.out.println("yes same ******** ");
}else {
System.out.println("not same ******* ");
return;
}
System.out.println("call out :::: "+outGoingCall1);
if (UserDetials.getInstance().getCallController().ismCallOutList()
&& outGoingCall != null) {
ArrayList<ContactsModel> numbers = CloudApplication.database
.getContacts(MySQLiteHelper.COLUMN_PHONE_NUMBER,
outGoingCall);
if (numbers.size() > 0) {
ContactsModel model = numbers.get(0);
System.out.println("type :::: " + model.getType());
if (model.getType() != Constants.CALL_OUT) {
CommonMethods.getInstance().blockCall(context,outGoingCall1,Constants.CALL_OUT);
}
}else{
CommonMethods.getInstance().blockCall(context,outGoingCall1,Constants.CALL_OUT);
}
}
}
private void endCallIfBlocked(String callingNumber) {
System.out.println("endCallIfBlocked :::: endCallIfBlocked");
ArrayList<ContactsModel> numbers = CloudApplication.database
.getContacts(MySQLiteHelper.COLUMN_PHONE_NUMBER, callingNumber);
if (UserDetials.getInstance().getCallController().ismCallInList()) {
if (numbers.size() > 0) {
ContactsModel model = numbers.get(0);
if (model.getType() != Constants.CALL_IN) {
CommonMethods.getInstance().blockCall(context,callingNumber,Constants.CALL_IN);
}
} else {
CommonMethods.getInstance().blockCall(context,callingNumber,Constants.CALL_IN);
}
} else if (UserDetials.getInstance().getCallController().ismBlockList()) {
if (numbers.size() > 0) {
ContactsModel model = numbers.get(0);
if (model.getType() == Constants.BLOCK_LIST) {
CommonMethods.getInstance().blockCall(context,callingNumber,Constants.BLOCK_LIST);
}
}
}
}
}
// Blocking code
public void blockCall(Context context) {
try {
TelephonyManager tm = (TelephonyManager) context
.getSystemService(Context.TELEPHONY_SERVICE);
Class<?> c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
ITelephony telephonyService = (ITelephony) m.invoke(tm);
telephonyService = (ITelephony) m.invoke(tm);
telephonyService.endCall();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
That's it. Enjoy
Related
I have developed an Android app for recording audio when the phone called. I know, I can't record the audio of the caller person but I want to record my voice when I answered the phone or start a call with another person. I can do this on some devices but on some devices when my phone starts to ringing, the voice is recorded but after I answered the phone, I can't record any voice. Or my voice is recorded when I start to call to person but after the person answered me, recording voice is stopped!
I use the below code:
private void startRecord(){
mRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);*/
mRecorder.setOutputFile(savePath);
}
BroadCastReceiver:
private final PhoneStateListener phoneListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
//Toast.makeText(context,"phoneListener Start",Toast.LENGTH_LONG).show();
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING: {
startedCall = true;
//Toast.makeText(context,"CALL_STATE_RINGING",Toast.LENGTH_LONG).show();
if (incomingNumber != null) {
//incoming call
//Toast.makeText(context,"Go to start forground service->ringing",Toast.LENGTH_LONG).show();
startForegroundService(incomingNumber);
}
break;
}
case TelephonyManager.CALL_STATE_OFFHOOK: {
//Toast.makeText(context,"CALL_STATE_OFFHOOK",Toast.LENGTH_LONG).show();
startedCall = true; // Newly added code
if (incomingNumber != null) {
//Toast.makeText(context,"Go to start forground service->OffHook",Toast.LENGTH_LONG).show();
//outgoing call
startForegroundService(incomingNumber);
}
break;
}
case TelephonyManager.CALL_STATE_IDLE: {
//Toast.makeText(context,"CALL_STATE_IDLE",Toast.LENGTH_LONG).show();
if (startedCall) {
stopForegroundService();
}
break;
}
default: {
}
}
} catch (Exception ex) {
}
}
};
You have to use the AccessibilityService in Android 10 and above.
MainActivity code:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (Build.VERSION.SDK_INT >= 29) {
if (!isAccessibilityServiceEnabled()) {
startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));
}
}
}
private boolean isAccessibilityServiceEnabled() {
int accessibilityEnabled = 0;
final String service = getPackageName() + "/" + RecordingAccessibilityService.class.getCanonicalName();
try {
accessibilityEnabled = Settings.Secure.getInt(getApplicationContext().getContentResolver(), Settings.Secure.ACCESSIBILITY_ENABLED);
} catch (Settings.SettingNotFoundException e) {
}
TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');
if (accessibilityEnabled == 1) {
String settingValue = Settings.Secure.getString(getApplicationContext().getContentResolver(), Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);
if (settingValue != null) {
mStringColonSplitter.setString(settingValue);
while (mStringColonSplitter.hasNext()) {
String accessibilityService = mStringColonSplitter.next();
if (accessibilityService.equalsIgnoreCase(service)) {
return true;
}
}
}
}
return false;
}
AccessibilityService code:
public class RecordingAccessibilityService extends AccessibilityService {
#Override
protected void onServiceConnected() {
instance = this;
super.onServiceConnected();
TelephonyManager mgr = (TelephonyManager) getSystemService(TELEPHONY_SERVICE);
PhoneStateListener phoneStateListener = new PhoneStateListener() {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
Toast.makeText(getApplicationContext(), "onServiceConnected", Toast.LENGTH_SHORT).show();
updateNotification();
startRecord();
}
if (state == TelephonyManager.CALL_STATE_IDLE) {
stopRecord();
}
super.onCallStateChanged(state, incomingNumber);
}
};
if (mgr != null) {
mgr.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
}
Manifest Code:
<service
android:name=".RecordingAccessibilityService"
android:exported="false"
android:label="#string/accessibility_description"
android:permission="android.permission.BIND_ACCESSIBILITY_SERVICE">
<intent-filter>
<action android:name="android.accessibilityservice.AccessibilityService" />
</intent-filter>
<meta-data
android:name="android.accessibilityservice"
android:resource="#xml/accessibility_service_config" />
</service>
accessibility service config code:
<accessibility-service xmlns:android="http://schemas.android.com/apk/res/android"
android:accessibilityEventTypes="typeWindowContentChanged|typeWindowStateChanged"
android:accessibilityFeedbackType="feedbackGeneric"
android:accessibilityFlags="flagReportViewIds|flagRetrieveInteractiveWindows"
android:canRetrieveWindowContent="true"
android:description="#string/accessibility_description"
android:label="#string/app_name"
android:notificationTimeout="100" />
also must use BroadcastReceiver:
public class CallBroadcastReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
String numberToCall = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
// Log.d("CallRecorder", "CallBroadcastReceiver intent has EXTRA_PHONE_NUMBER: " + numberToCall);
}
PhoneListener phoneListener = new PhoneListener(context);
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
telephony.listen(phoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
documentation:
https://developer.android.com/reference/android/accessibilityservice/AccessibilityService
I am trying to end the call the user dialed. Basically I would allow some number that user would be able to dial and call, else all other call would be end up and User would not be able to call other then those numbers.
Now the problem is I have tried several ways to do so , but its not working
What I am Doing:
I have a broadcast receiver Which got fired when User call the Number
Under It I gets the dialed number , if it is not my desired number I try to end it.
Here is what I am doing in my on Receive method.
public void onReceive(Context context, Intent intent) {
Log.d(OutgoingCallReceiver.class.getSimpleName(), intent.toString());
//TODO: Handle outgoing call event here
String phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
disconnectCall();
Toast.makeText(context, "DisConnecting! = "+phoneNumber, Toast.LENGTH_LONG).show();
killCall(context);
TelephonyManager tm=(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Method m1 = null;
try {
m1 = tm.getClass().getDeclaredMethod("getITelephony");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
m1.setAccessible(true);
Object iTelephony = null;
try {
iTelephony = m1.invoke(tm);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
Method m2 = null;
try {
m2 = iTelephony.getClass().getDeclaredMethod("silenceRinger");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
Method m3 = null;
try {
m3 = iTelephony.getClass().getDeclaredMethod("endCall");
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
// try {
// // m2.invoke(iTelephony);
// } catch (IllegalAccessException e) {
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// e.printStackTrace();
// }
try {
m3.invoke(iTelephony);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
TelephonyManager telephony = (TelephonyManager)
context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class c = Class.forName(telephony.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
telephonyService = (ITelephony) m.invoke(telephony);
//telephonyService.silenceRinger();
telephonyService.endCall();
} catch (Exception e) {
e.printStackTrace();
}
// }
}
and Endig Call method as well
public void disconnectCall(){
try {
String serviceManagerName = "android.os.ServiceManager";
String serviceManagerNativeName = "android.os.ServiceManagerNative";
String telephonyName = "com.android.internal.telephony.ITelephony";
Class<?> telephonyClass;
Class<?> telephonyStubClass;
Class<?> serviceManagerClass;
Class<?> serviceManagerNativeClass;
Method telephonyEndCall;
Object telephonyObject;
Object serviceManagerObject;
telephonyClass = Class.forName(telephonyName);
telephonyStubClass = telephonyClass.getClasses()[0];
serviceManagerClass = Class.forName(serviceManagerName);
serviceManagerNativeClass = Class.forName(serviceManagerNativeName);
Method getService = // getDefaults[29];
serviceManagerClass.getMethod("getService", String.class);
Method tempInterfaceMethod = serviceManagerNativeClass.getMethod("asInterface", IBinder.class);
Binder tmpBinder = new Binder();
tmpBinder.attachInterface(null, "fake");
serviceManagerObject = tempInterfaceMethod.invoke(null, tmpBinder);
IBinder retbinder = (IBinder) getService.invoke(serviceManagerObject, "phone");
Method serviceMethod = telephonyStubClass.getMethod("asInterface", IBinder.class);
telephonyObject = serviceMethod.invoke(null, retbinder);
telephonyEndCall = telephonyClass.getMethod("endCall");
telephonyEndCall.invoke(telephonyObject);
} catch (Exception e) {
e.printStackTrace();
Log.d("Receiver",
"FATAL ERROR: could not connect to telephony subsystem");
Log.d("Receiver", "Exception object: " + e);
}
}
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
Log.d("Receiver","PhoneStateReceiver **" + ex.toString());
return false;
}
return true;
}
As We can see I am using 4 different types of ways I found on internet to end the call , but its not working. At the moment I am trying this code on jelly beans. But its not working. Please help me if any one has I dea how to end the call and what is a proper way please help.
Code to kill call
public boolean killCall(Context context) {
try {
// Get the boring old TelephonyManager
TelephonyManager telephonyManager =
(TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
// Get the getITelephony() method
Class classTelephony = Class.forName(telephonyManager.getClass().getName());
Method methodGetITelephony = classTelephony.getDeclaredMethod("getITelephony");
// Ignore that the method is supposed to be private
methodGetITelephony.setAccessible(true);
// Invoke getITelephony() to get the ITelephony interface
Object telephonyInterface = methodGetITelephony.invoke(telephonyManager);
// Get the endCall method from ITelephony
Class telephonyInterfaceClass =
Class.forName(telephonyInterface.getClass().getName());
Method methodEndCall = telephonyInterfaceClass.getDeclaredMethod("endCall");
// Invoke endCall()
methodEndCall.invoke(telephonyInterface);
} catch (Exception ex) { // Many things can go wrong with reflection calls
LogUtil.warn(TAG, "PhoneStateReceiver **" + ex.toString());
return false;
}
return true;
}
Code for different states
public abstract class PhoneCallReceiver extends BroadcastReceiver {
private static final String TAG = "PhoneCallReceiver";
//The receiver will be recreated whenever android feels like it. We need a static variable to remember data between instantiations
private static int lastState = TelephonyManager.CALL_STATE_IDLE;
private static Date callStartTime;
private static boolean isIncoming;
private static String savedNumber; //because the passed incoming is only valid in ringing
#Override
public void onReceive(Context context, Intent intent) {
//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);
// Added this line to remove broadcast from caller application
// abortBroadcast();
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
telephonyManager.listen(new PhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);
}
}
//Derived classes should override these to respond to specific events of interest
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
}
protected void onOutgoingCallStarted(Context ctx, String number, Date start) {
}
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
}
protected 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;
onIncomingCallStarted(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();
onOutgoingCallStarted(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) {
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
} else {
onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
}
break;
}
lastState = state;
}
class PhoneStateListener extends PhoneStateListener {
//private static final String TAG = "PhoneStateChanged";
Context context; //Context to make Toast if required
public PhoneStateListener(Context context) {
super();
this.context = context;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
super.onCallStateChanged(state, incomingNumber);
switch (state) {
case TelephonyManager.DATA_CONNECTED:
LogUtil.debug(TAG, "Data connected send broadcast");
Intent dataConnectedIntent = new Intent(PhoneCallTimerService.DATA_CONNECTED);
context.sendBroadcast(dataConnectedIntent);
break;
case TelephonyManager.DATA_DISCONNECTED:
LogUtil.debug(TAG, "Data disconnected send broadcast");
Intent dataDisConnectedIntent = new Intent(PhoneCallOutgoingService.DATA_DISCONNECTED);
context.sendBroadcast(dataDisConnectedIntent);
break;
default:
break;
}
}
}
}
public class CallReceiver extends PhoneCallReceiver {
private static final String TAG = "CallReceiver";
#Override
protected void onIncomingCallStarted(Context ctx, String number, Date start) {
}
#Override
protected void onOutgoingCallStarted(final Context ctx, final String number, Date start) {
LogUtil.debug(TAG, "Outgoing call started from :: " + number);
final String name = Utils.getContactName(ctx, number);
Handler outgoingCallHandler = new Handler();
outgoingCallHandler.postDelayed(new Runnable() {
#Override
public void run() {
if (!Utils.isMyServiceRunning(PhoneCallOutgoingService.class, ctx) && !Utils.isMyServiceRunning(PhoneCallTimerService.class, ctx)) {
Intent outGoingCallService = new Intent(ctx, PhoneCallOutgoingService.class);
if (name != null && name.length() > 0) {
outGoingCallService.putExtra(CallReceiver.CALLER_NUMBER, name);
} else {
outGoingCallService.putExtra(CallReceiver.CALLER_NUMBER, number);
}
ctx.startService(outGoingCallService);
} else {
LogUtil.error(TAG, "Outgoing call service already started");
}
}
}, 2000);
}
#Override
protected void onIncomingCallEnded(Context ctx, String number, Date start, Date end) {
LogUtil.debug(TAG, "Incoming call end from :: " + number);
Intent callTerminatedIntent = new Intent(ACTION_CALL_TERMINATED);
ctx.sendBroadcast(callTerminatedIntent);
}
#Override
protected void onOutgoingCallEnded(Context ctx, String number, Date start, Date end) {
LogUtil.debug(TAG, "Outgoing call ended from :: " + number);
Intent dataDisConnectedIntent = new Intent(PhoneCallOutgoingService.DATA_DISCONNECTED);
ctx.sendBroadcast(dataDisConnectedIntent);
}
#Override
protected void onMissedCall(Context ctx, String number, Date start) {
LogUtil.debug(TAG, "Missed call from :: " + number);
Intent missedCallIntent = new Intent(ACTION_CALL_MISSED);
ctx.sendBroadcast(missedCallIntent);
}
Of-course there is some code which is not important for your app so please comment or delete just delete that line.
Hi I searched a lot on this forum for correct result but unable to find. I need details of last outgoing call once call is ended. For this I am using BroadcasteReceiver here is code for my receiver
public class CallStateBroadcaster extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
((TelephonyManager)context.getSystemService(Context.TELEPHONY_SERVICE)).listen(new CustomPhoneStateListener(context), PhoneStateListener.LISTEN_CALL_STATE);
}}
Here is code for PhoneStateListener
public class CustomPhoneStateListener extends PhoneStateListener{
private Context context;
public CustomPhoneStateListener(Context paramContext)
{
this.context = paramContext;
}
#Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
super.onCallStateChanged(state, incomingNumber);
((TelephonyManager)this.context.getSystemService("phone")).listen(this, PhoneStateListener.LISTEN_NONE);
if(TelephonyManager.CALL_STATE_IDLE == state)
{
try {
Thread.sleep(1500L);
Intent intent = new Intent(this.context,LastCallInfoActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.context.startActivity(intent);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
Here is code for my activity which fetch call details for call log
public class LastCallInfoActivity extends Activity{
String addtolist;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
Cursor callDetailCursor = getContentResolver().query(CallLog.Calls.CONTENT_URI, null,null,null,android.provider.CallLog.Calls.DATE + " DESC limit 1");
int phoneNumber= callDetailCursor.getColumnIndex(CallLog.Calls.NUMBER);
int callType=callDetailCursor.getColumnIndex(CallLog.Calls.TYPE);
int callDate=callDetailCursor.getColumnIndex(CallLog.Calls.DATE);
int callDuration=callDetailCursor.getColumnIndex(CallLog.Calls.DURATION);
Log.i(">>CAllDetails", "getsCallLogs" );
if(callDetailCursor.getCount()>0)
{
while(callDetailCursor.moveToNext())
{
String phoneNumberString=callDetailCursor.getString(phoneNumber);
String contactName= getContactName(this, phoneNumberString);
String callTypeString =callDetailCursor.getString(callType);
String callDateString=callDetailCursor.getString(callDate);
String callDurationString=callDetailCursor.getString(callDuration);
Date callDayTime=new Date(Long.valueOf(callDateString));
int callCode = Integer.parseInt(callTypeString);
int calldur=Integer.parseInt(callDurationString);
if (callCode==2 && calldur>=1)
{
Double callCost=Double.parseDouble(callDurationString);
String callCostString= String.valueOf( callCost);
Log.i(">>CAllDetails", "getsLocation" );
addtolist= "Name :"+contactName+"\n"+
"Phone Number: "+phoneNumberString+"\n"+"Call Duration :"+
callDurationString+" Seconds\n"+"Call Date: "+callDayTime+"\n"+
callCostString;
}
}
}callDetailCursor.close();
Toast.makeText(this, addtolist, Toast.LENGTH_LONG).show();
}
public String getContactName(Context context, String phoneNumber) {
ContentResolver cr = context.getContentResolver();
Uri uri = Uri.withAppendedPath(PhoneLookup.CONTENT_FILTER_URI, Uri.encode(phoneNumber));
Cursor cursor = cr.query(uri, new String[]{PhoneLookup.DISPLAY_NAME}, null, null, null);
if (cursor == null) {
return null;
}
String contactName = null;
if(cursor.moveToFirst()) {
contactName = cursor.getString(cursor.getColumnIndex(PhoneLookup.DISPLAY_NAME));
}
if(cursor != null && !cursor.isClosed()) {
cursor.close();
}
return contactName;
}
}
My this program show toast even before my call got disconnected and start my activity. Please help me and correct my code so that it will get executed after call ends
thanks
just try this add an additional if statement for checking previous sate was off hook.
boolean wasoffhook=false;
if(TelephonyManager.CALL_STATE_OFFHOOK == state)
{
wasoffhook=true;
}
if(TelephonyManager.CALL_STATE_IDLE == state&&wasoffhook)
{
try {
Thread.sleep(1500L);
Intent intent = new Intent(this.context,LastCallInfoActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TASK);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
this.context.startActivity(intent);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
In your onreceive method of Callstatebroadcaster add this code and it would work fine.I just solved it.
#Override
public void onReceive(Context context, Intent intent)
{
try
{
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL"))
{
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
Toast.makeText(context,"the no. is"+savedNumber,Toast.LENGTH_LONG).show();
// onOutgoingCallStarted(context,"",callStartTime);
}
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)) {
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.d("Testing", "Outgoing call has been disconnect");
intent = new Intent(context, MyCustomDialog.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
context.startActivity(intent);
System.out.println("CAll has been disconnect...............");
// Toast.makeText(this, "CAll has been disconnect", Toast.LENGTH_LONG).show();
break;
}
}
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);
}
}
catch (Exception e)
{
e.printStackTrace();
}
}
And in Callstatechanged method add this code.
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;
// onIncomingCallStarted(context, number, callStartTime);
// onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
// onOutgoingCallEnded(context, savedNumber, callStartTime, new Date());
// wasRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if (!wasRinging) {
// Start your new activity
onIncomingCallEnded(context,savedNumber,callStartTime,new Date());
onOutgoingCallEnded(context,savedNumber,callStartTime,new Date());
} else {
onIncomingCallStarted(context,savedNumber,callStartTime);
// Cancel your old activity
}
// this should be the last piece of code before the break
break;
case TelephonyManager.CALL_STATE_IDLE:
if(isIncoming)
{
onIncomingCallEnded(context, savedNumber, callStartTime, new Date());
}
}
lastState = state;
}
This would work.
I want to delete the messages from a specific mobile no. in android phone.
For this,I am using the following code..
The Problem in this code is that it is deleting all the conversations from the phone..
So help me please to resolve this problem.
THANX IN ADVANCE...
public class MainActivity extends Activity
{
#Override
protected void onCreate(Bundle savedInstanceState)
{
// String specificPhoneNumber = "+91" ;
super.onCreate(savedInstanceState);
long V;
MainActivity thr = new MainActivity();
V =thr.getThreadId(thr);
Uri thread = Uri.parse("content://sms/inbox/8767564523" + V);
getContentResolver().delete(thread, null, null);
}
private long getThreadId(Context context)
{
long threadId = 0;
String SMS_READ_COLUMN = "read";
String WHERE_CONDITION = SMS_READ_COLUMN + " = 0";
String SORT_ORDER = "date DESC";
int count = 0;
Uri uri1 = Uri.parse("content://sms/inbox/");
Cursor cursor = context.getContentResolver().query(uri1,new String[] { "_id", "thread_id", "address", "person", "date", "body" },WHERE_CONDITION,null,SORT_ORDER);
if (cursor != null) {
try {
count = cursor.getCount();
if (count > 0) {
cursor.moveToFirst();
threadId = cursor.getLong(1);
}
} finally {
cursor.close();
}
}
return threadId;
}
}
Oh...Got it ..It is Working 100%,
public void onReceive(Context context, Intent intent) {
//Bundle bundle = intent.getExtras();
// if(null == bundle)
// return;
// SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
try {
// Java reflection to gain access to TelephonyManager's
// ITelephony getter
tm = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
Log.v("1","BYE BYE BYE" );
Class c = Class.forName(tm.getClass().getName());
Method m = c.getDeclaredMethod("getITelephony");
m.setAccessible(true);
// com.android.internal.telephony.ITelephony
telephonyService = (ITelephony) m.invoke(tm);
Bundle b = intent.getExtras();
incommingNumber = b.getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Toast.makeText(context, incommingNumber, Toast.LENGTH_LONG).show();
Log.v("2","BYE BYE BYE" );
for(int i=0;i<1;i++)
{
if ( incommingNumber.equals(BINO[i]) )
{
}
else{
Toast.makeText(context,incommingNumber, Toast.LENGTH_LONG).show();
telephonyService = (ITelephony) m.invoke(tm);
//telephonyService.silenceRinger();
telephonyService.endCall();
Log.v("3","BYE BYE BYE" );
//telephonyService.answerRingingCall();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};//BroadcastReceiver
/**
* Broadcast receiver to detect the outgoing calls.
*/
public class OutgoingReceiver extends BroadcastReceiver
{
public OutgoingReceiver() {
}
#Override
public void onReceive(Context context, Intent intent)
{
String number = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
// setResultData(null);
int c = (number).indexOf("YOUR NO...");
Toast.makeText(context, String.valueOf(c), Toast.LENGTH_LONG).show();
for(int i =0;i<2;i++)
{
if ((number).indexOf(BONO[i])!= -1)//||number.contentEquals("+917204302689")||number.contentEquals("07204302689"))
{
setResultData(null);
Toast.makeText(context, "This call is not allowed!", Toast.LENGTH_LONG).show();
}
}
}
}
public class MessageReceiver extends BroadcastReceiver
{
public void onReceive(Context context, Intent intent)
{
Bundle bundle = intent.getExtras();
//Bundle bundle = intent.getExtras();
if ( bundle != null )
{
// do you manipulation on String then if you can abort.
}
Object messages[] = (Object[]) bundle.get("pdus");
SmsMessage smsMessage[] = new SmsMessage[messages.length];
for (int n = 0; n <messages.length; n++)
{
smsMessage[n] = SmsMessage.createFromPdu((byte[]) messages[n]);
}
for(int i=0;i<1;i++)
{
if(MINO[i].equalsIgnoreCase(smsMessage[0].getOriginatingAddress()))
{
//abortBroadcast();
String Body=smsMessage[0].getMessageBody();
if (Body.startsWith("START"))
{
Toast toast4 = Toast.makeText(context,"There is START ", Toast.LENGTH_LONG);toast4.show();
abortBroadcast();
}
}
else
{
abortBroadcast();
}
}
// show first message
Toast toast1 = Toast.makeText(context,"Received SMS: " + smsMessage[0].getOriginatingAddress()+ "\nBody: "+smsMessage[0].getMessageBody(), Toast.LENGTH_LONG);
toast1.show();
}
};//BroadcastReceiver
String incommingNumber;
private Context ctx;
private TelephonyManager tm;
//private CallStateListener callStateListener;
ITelephony telephonyService;
private OutgoingReceiver outgoingReceiver;
private IncomingReceiver incomingReceiver;
private MessageReceiver messageReceiver;
public CallHelper(Context ctx)
{
this.ctx = ctx;
//callStateListener = new CallStateListener();
outgoingReceiver = new OutgoingReceiver();
incomingReceiver = new IncomingReceiver();
messageReceiver = new MessageReceiver();
}
/**
* Start calls detection.
*/
public void start() {
//tm = (TelephonyManager) ctx.getSystemService(Context.TELEPHONY_SERVICE);
//tm.listen(callStateListener, PhoneStateListener.LISTEN_CALL_STATE);
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_NEW_OUTGOING_CALL);
ctx.registerReceiver(outgoingReceiver, intentFilter);
IntentFilter filter= new IntentFilter("android.intent.action.PHONE_STATE");
ctx.registerReceiver(incomingReceiver, filter);
IntentFilter filter1= new IntentFilter("android.provider.Telephony.SMS_RECEIVED");
ctx.registerReceiver(messageReceiver, filter1);
}
/**
* Stop calls detection.
*/
public void stop()
{
//tm.listen(callStateListener, PhoneStateListener.LISTEN_NONE);
ctx.unregisterReceiver(outgoingReceiver);
ctx.unregisterReceiver(incomingReceiver);
ctx.unregisterReceiver(messageReceiver);
}
}
I want to block a certain phone number from calling me. I coded everything and it's working fine when I put the number within application. But I don't know how to make a custom list of phone numbers that I manually enter after the application is installed. I want to change any number and save it. In PhoneCallStateListener I made a new class of type Resource.java where I extract the number. But it did not work. Please help.
Here is my code:
public class PhoneCallReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
TelephonyManager telephony = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
PhoneCallStateListener customPhoneListener = new PhoneCallStateListener(context);
telephony.listen(customPhoneListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
public class PhoneCallStateListener extends PhoneStateListener {
private Context context;
public PhoneCallStateListener(Context context){
this.context = context;
}
#SuppressWarnings("unchecked")
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
AudioManager audioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
//Turn ON the mute
audioManager.setStreamMute(AudioManager.STREAM_RING, true);
//i want to getnum from here
Resource res=new Resource();
String get=res.et.getText().toString();
//end of getting num
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
try {
Class clazz = Class.forName(telephonyManager.getClass().getName());
Method method = clazz.getDeclaredMethod("getITelephony");
method.setAccessible(true);
ITelephony telephonyService = (ITelephony) method.invoke(telephonyManager);
//Checking incoming call number
if (incomingNumber.equalsIgnoreCase(get)) {
telephonyService.silenceRinger();
}
} catch (Exception e) {
e.printStackTrace();
}
//Turn OFF the mute
audioManager.setStreamMute(AudioManager.STREAM_RING, false);
break;
}
super.onCallStateChanged(state, incomingNumber);
}
}
Resource.java file:
public class Resource extends Activity {
Button btsave,btcancel;
EditText et;
#Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.numbers);
et=(EditText)findViewById(R.id.editNumber);
btsave=(Button)findViewById(R.id.buttonSave);
btcancel=(Button)findViewById(R.id.buttonCancel);
edittext();
}
public void edittext() {
// TODO Auto-generated method stub
InputStreamReader is=new InputStreamReader(this.getResources().openRawResource(R.raw.numtext));
BufferedReader buff=new BufferedReader(is);
StringBuilder finaltext=new StringBuilder();
String line = null;
try{
while((line= buff.readLine())!=null)
{
finaltext.append(line);
}
}
catch(Exception e)
{
e.printStackTrace();
}
et.setText(finaltext);
}
}