I have a project in Android using blocking a call and send sms back to the caller.
I search all here. But those codes not working. I need help.
I am using Android 2.2
Use this ex for sms manager
Button bttsendsms;
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
bttsendsms =(Button)findViewById(R.id.button1);
bttsendsms.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v) {
Toast.makeText(SmsActivity.this, "hello", 6000).show();
sendSMS("5556","hello friends");
sendSMS("5558","hello friends");
}
});
}
private void sendSMS(String phoneNumber,String message)
{
SmsManager sms=SmsManager.getDefault();
sms.sendTextMessage(phoneNumber,null,message,null,null);
}
}
try this code it....this is working working for me i am developing same application.
use this code in oncreate method.
TelephonyManager telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener callStateListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
// React to incoming call.
// number = PhoneNumberUtils.formatNumber(incomingNumber);
number = incomingNumber;
// If phone ringing
if (state == TelephonyManager.CALL_STATE_RINGING) {
new LoadStuff().execute(incomingNumber, message);
boolean isEnabled = Settings.System.getInt(
getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) == 1;
if (!isEnabled) {
Settings.System.putInt(getContentResolver(),
Settings.System.AIRPLANE_MODE_ON,
isEnabled ? 0 : 1);
// Post an intent to reload
Intent intent = new Intent(
Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", !isEnabled);
sendBroadcast(intent);
}
}
}
// If incoming call received
if (state == TelephonyManager.CALL_STATE_OFFHOOK) {
}
if (state == TelephonyManager.CALL_STATE_IDLE) {
boolean isEnabled = Settings.System.getInt(
getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, 0) == 1;
if (isEnabled) {
Settings.System.putInt(getContentResolver(),
Settings.System.AIRPLANE_MODE_ON, isEnabled ? 0
: 1);
// Post an intent to reload
Intent intent = new Intent(
Intent.ACTION_AIRPLANE_MODE_CHANGED);
intent.putExtra("state", !isEnabled);
sendBroadcast(intent);
}
}
}
};
telephonyManager.listen(callStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
}
and use this code outside oncreate method
public class LoadStuff extends AsyncTask<String, String, Void> {
#Override
protected Void doInBackground(String... params) {
// TODO Auto-generated method stub
String number = params[0];
String message = params[1];
boolean error = false;
try {
SmsManager sms = SmsManager.getDefault();
sms.sendTextMessage(number, null, message, null, null);
} catch (IllegalArgumentException e) {
error = true;
}
if (error) {
Toast.makeText(getBaseContext(), "SMS SENDING FAILED",
Toast.LENGTH_SHORT).show();
}
return null;
}
}
Related
I am working on fetching recent call log as call get disconnected(outgoing , incoming) either answered or unanswered.
I am using Phone state listener to fire broadcast when call get disconnected but it getting fired multiple time for one call why so..??
So Please tell me how to fire receiver only once for one call.
here is my code
public class BroadcastReceiver extends android.content.BroadcastReceiver{
static boolean iscallended= true;
Context mContext;
TelephonyManager telephony;
private static final String TAG = "CustomBroadcastReceiver";
CustomPhoneStateListener customPhoneStateListener;
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
mContext = context;
Bundle extras = intent.getExtras();
if (extras != null) {
String state = extras.getString(TelephonyManager.EXTRA_STATE);
Log.w("DEBUG", state);
telephony = (TelephonyManager)context.getSystemService(context.TELEPHONY_SERVICE);
if(customPhoneStateListener==null)
{
customPhoneStateListener = new CustomPhoneStateListener();
telephony.listen(customPhoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
}
}
}
private class CustomPhoneStateListener extends PhoneStateListener
{
private static final String TAG = "CustomPhoneStateListener";
Handler handler=new Handler();
#Override
public void onCallStateChanged(int state, String incomingNumber) {
// TODO Auto-generated method stub
System.out.println(iscallended+ " value of iscancelled ");
switch (state)
{
case TelephonyManager.CALL_STATE_RINGING:
if(!incomingNumber.equalsIgnoreCase(""))
{
//YOUR CODE HERE
}
break;
case TelephonyManager.CALL_STATE_IDLE:
if(iscallended)
{
iscallended = false;
System.out.println("IDLE called");
Toast.makeText(mContext, "IDLE", Toast.LENGTH_SHORT).show();
Intent it = new Intent(mContext,MainActivity.class);
it.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(it);
}
break;
default:
break;
}
super.onCallStateChanged(state, incomingNumber);
telephony.listen(customPhoneStateListener, PhoneStateListener.LISTEN_NONE);
}
}
}
Here's receiver in manifest
<receiver android:name="com.example.calllogs.BroadcastReceiver">
<intent-filter >
<action android:name="android.intent.action.PHONE_STATE"/>
</intent-filter>
</receiver>
Here is your answer :
https://stackoverflow.com/a/5497316/3479012
also specify permission in your manifest to access phone state.
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
also have a look at this
http://karanbalkar.com/2014/02/detect-incoming-call-and-call-hangup-event-in-android/
Yes you will get that.
private class MyPhoneStateListener extends PhoneStateListener {
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
//Hangup
case TelephonyManager.CALL_STATE_IDLE:
Log.d("IDLE", "Call Idle" + state);
if (isCallEnded) {
isCallEnded = false;
AlertDialog.Builder alertBuilder = new AlertDialog.Builder(getActivity());
.setCancelable(false)
.setPositiveButton(getString(R.string.Yes), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
// your method
}
})
.setNegativeButton(getString(R.string.No), new DialogInterface.OnClickListener() {
#Override
public void onClick(DialogInterface dialogInterface, int i) {
}
});
alertBuilder.show();
}
break;
//Outgoing
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d("OFFHOOK", "Call OffHook" + state);
isCallEnded = true;
break;
//Incoming
case TelephonyManager.CALL_STATE_RINGING:
Log.d("RINGING", "Call Ringing" + state);
break;
}
}
}
The above is sample, when you look at the device log you'll definitely see offhook multiple times as well as IDLE state.
Try to calculate that, it should be okay.
To avoid repetitive triggering, use MyPhoneStateListener as object and check lastCallState. Call makeMyPhoneStateListener from ServiceReceiver.
class MyPhoneStateListener () : PhoneStateListener() {
companion object {
var lastCallState: Int? = null
lateinit var context: Context
fun makeMyPhoneStateListener(_context: Context): MyPhoneStateListener
{
val myPhoneStateListener = MyPhoneStateListener()
context = _context
return myPhoneStateListener
}
}
override fun onCallStateChanged(state: Int, incomingNumber: String) {
when (state) {
TelephonyManager.CALL_STATE_IDLE -> {
if (lastCallState!= TelephonyManager.CALL_STATE_IDLE){
// some code for CALL_STATE_IDLE
lastCallState = TelephonyManager.CALL_STATE_IDLE
}
}
TelephonyManager.CALL_STATE_OFFHOOK -> {
if (lastCallState!= TelephonyManager.CALL_STATE_OFFHOOK) {
// some code for CALL_STATE_OFFHOOK
lastCallState = TelephonyManager.CALL_STATE_OFFHOOK
}
}
TelephonyManager.CALL_STATE_RINGING -> {
if (lastCallState!= TelephonyManager.CALL_STATE_RINGING) {
// some code for CALL_STATE_RINGING
lastCallState = TelephonyManager.CALL_STATE_RINGING
}
}
}
}
I have overcame this problem using this simple trick
In your receiver class
public class Receiver extends BroadcastReceiver {
public static final String TAG = "MADARA";
private static boolean callAnswered = false;
private static boolean callRinging = false;
private static boolean callEnded = false;
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("android.intent.action.PHONE_STATE")){
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
if (!callAnswered){
Log.d(TAG, "Call answered");
callAnswered = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> callAnswered = false, 2000);
}
}
else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_IDLE)) {
if (!callEnded){
Log.d(TAG, "Call ended");
callEnded = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> callEnded = false, 2000);
}
}
else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
if (!callRinging){
Log.d(TAG, "Call Ringing");
callRinging = true;
new Handler(Looper.getMainLooper()).postDelayed(() -> callRinging = false, 2000);
}
}
}
}
}
you will find the below description in Android Devlopers documnetation here
Broadcast intent action indicating that the call state on the device
has changed.
The EXTRA_STATE extra indicates the new call state. If a receiving app
has Manifest.permission.READ_CALL_LOG permission, a second extra
EXTRA_INCOMING_NUMBER provides the phone number for incoming and
outgoing calls as a String.
If the receiving app has Manifest.permission.READ_CALL_LOG and
Manifest.permission.READ_PHONE_STATE permission, it will receive the
broadcast twice; one with the EXTRA_INCOMING_NUMBER populated with the
phone number, and another with it blank. Due to the nature of
broadcasts, you cannot assume the order in which these broadcasts will
arrive, however you are guaranteed to receive two in this case. Apps
which are interested in the EXTRA_INCOMING_NUMBER can ignore the
broadcasts where EXTRA_INCOMING_NUMBER is not present in the extras
(e.g. where Intent#hasExtra(String) returns false).
Now listener fired twice one for call log permission and the other for phone state permission, only one of them will return with phone number and the other will be Null.
So, you should first check if phone number returen empty or not like this
String stateString = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
String savedNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
Now You should first check if savedNumber is null or not
Here is full onReceive method
private static String savedNumber;
int state;
Context ctx;
#Override
public void onReceive(Context context, #NonNull Intent intent) {
Log.d("TAG101", "onReceive: " + intent.getAction().toString());
ctx = context;
state = -1;
if (intent.getAction().equals("android.intent.action.NEW_OUTGOING_CALL")) {
savedNumber = intent.getExtras().getString("android.intent.extra.PHONE_NUMBER");
} else {
String stateString = intent.getStringExtra(TelephonyManager.EXTRA_STATE);
savedNumber = intent.getExtras().getString(TelephonyManager.EXTRA_INCOMING_NUMBER);
if(savedNumber != null) {
if (stateString.equals(TelephonyManager.EXTRA_STATE_OFFHOOK)) {
state = TelephonyManager.CALL_STATE_OFFHOOK;
} else if (stateString.equals(TelephonyManager.EXTRA_STATE_IDLE)) {
state = TelephonyManager.CALL_STATE_IDLE;
if (state == 0) {
onCallEnded();
}
} else if (stateString.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
state = TelephonyManager.CALL_STATE_RINGING;
}
}
}
}
I'm trying to use gcm to start calls in sinch, I send the push notification and I get it on the other side but when I try to start a call I get null pointer exception in my service at mCall.addCallListener( );
this is the part of the gcm intent service where I get the notification and start sinch service :
{
String callId = intent.getExtras().getString("callId");
Intent intent3 = new Intent(this, SinchClientService.class);
intent3.setAction(SinchClientService.ACTION_START_CALL);
intent3.putExtra(SinchClientService.INTENT_EXTRA_CALLID, callId);
startService(intent3);
}
this is what I do in the sinch service:
else if(intent.getAction().equals(ACTION_START_CALL))
{
String callId = intent.getStringExtra(INTENT_EXTRA_CALLID);
if(callId != null)
{
startCall(callId);
}
}
public void startCall(String callId) {
if (mCallClient != null) {
Call call = mCallClient.getCall(callId);
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
}
and this is how I start sinch client:
private void startSinchClient(String id, String userName) {
mSinchClient = Sinch.getSinchClientBuilder().context(this).userId(id).
applicationKey(APP_KEY).applicationSecret(APP_SECRET).environmentHost(ENVIRONMENT).build();
mSinchClient.addSinchClientListener(this);
mSinchClient.setSupportCalling(true);
mSinchClient.setSupportMessaging(true);
mSinchClient.setSupportPushNotifications(true);
mSinchClient.setSupportActiveConnectionInBackground(false);
//mSinchClient.startListeningOnActiveConnection();
mMessageClient = mSinchClient.getMessageClient();
mMessageClient.addMessageClientListener(this);
mCallClient = mSinchClient.getCallClient();
mCallClient.addCallClientListener(this);
mSinchClient.checkManifest();
mSinchClient.start();
}
and this is my onIcommingCall method:
#Override
public void onIncomingCall(CallClient client, Call call) {
Log.d(TAG, "Incoming call");
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
and this is the part of my call service where I get null pointer exception:
if(CurrentCall.currentCall == null)
stopSelf();
mCall = CurrentCall.currentCall;
mCall.addCallListener(this);
Note: my call service implements call listener
I never get the call, can someone help me?
Edit this is how I initialize a call:
in the sinch service:
public void callFriend(String id) {
if (mCallClient != null) {
Call call = mCallClient.callUser(id);
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
}
in the call service:
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
Log.d(LOG_TAG, "Should send push notification");
Log.d("payload", pushPairs.get(0).getPushPayload());
asyncTask = new sendPushNotifications(this, call.getRemoteUserId(), pushPairs, call.getCallId());
asyncTask.execute();
}
class sendPushNotifications extends AutoAsyncTask {
List<PushPair> pushPairs;
String message;
String senderId;
String message_id;
String time_stamp;
String callId;
public sendPushNotifications(Context context, String senderId, List<PushPair> pushPairs, String callId) {
super(context, false);
this.pushPairs = pushPairs;
this.senderId = senderId;
this.callId = callId;
}
#Override
protected Integer doInBackground(Void... params) {
boolean connectedToInternet = connManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI).isConnected()
|| connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected();
if (connectedToInternet)
{
String regId;
//JSONArray arrayList = new JSONArray();
for(PushPair p: pushPairs)
{
regId = new String(p.getPushData());
//arrayList.put(regId);
UserFunctions.sendCallPushNotifications(senderId, regId, "call", callId);
}
asyncTask = null;
return 0;
}
else
{
asyncTask = null;
return 1;
}
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result == 0)
{
Log.d("call push sent", "sent");
}
else if (result == 1)
{
Toast.makeText(getApplicationContext(),
"No Network Connection !!", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(
getApplicationContext(),
"Error occured,Please Try Again Later !!",
Toast.LENGTH_SHORT).show();
}
}
}
}
latest edit so I did what you said and I only get calls in the messaging activity, my new codes are:
in the call service:
#Override
public void onShouldSendPushNotification(Call call, List<PushPair> pushPairs) {
Log.d(LOG_TAG, "Should send push notification");
Log.d("payload", pushPairs.get(0).getPushPayload());
asyncTask = new sendPushNotifications(this, call.getRemoteUserId(), pushPairs, call.getCallId());
asyncTask.execute();
}
class sendPushNotifications extends AutoAsyncTask {
List<PushPair> pushPairs;
String message;
String senderId;
String message_id;
String time_stamp;
String callId;
public sendPushNotifications(Context context, String senderId, List<PushPair> pushPairs, String callId) {
super(context, false);
this.pushPairs = pushPairs;
this.senderId = senderId;
this.callId = callId;
}
#Override
protected Integer doInBackground(Void... params) {
boolean connectedToInternet = connManager.getNetworkInfo( ConnectivityManager.TYPE_WIFI).isConnected()
|| connManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected();
if (connectedToInternet)
{
String regId;
String payload;
//JSONArray arrayList = new JSONArray();
for(PushPair p: pushPairs)
{
regId = new String(p.getPushData());
payload = new String(p.getPushPayload());
//arrayList.put(regId);
UserFunctions.sendCallPushNotifications(senderId, regId, "call", callId, payload);
}
asyncTask = null;
return 0;
}
else
{
asyncTask = null;
return 1;
}
}
#Override
protected void onPostExecute(Integer result) {
super.onPostExecute(result);
if (result == 0)
{
Log.d("call push sent", "sent");
}
else if (result == 1)
{
Toast.makeText(getApplicationContext(),
"No Network Connection !!", Toast.LENGTH_SHORT).show();
}
else
{
Toast.makeText(
getApplicationContext(),
"Error occured,Please Try Again Later !!",
Toast.LENGTH_SHORT).show();
}
}
}
the gcm intent service:
else
{
String callId = intent.getExtras().getString("callId");
String payload = intent.getExtras().getString("payload");
Intent intent3 = new Intent(this, SinchClientService.class);
intent3.setAction(SinchClientService.ACTION_START_CALL);
intent3.putExtra(SinchClientService.INTENT_EXTRA_CALLID, callId);
intent3.putExtra(SinchClientService.INTENT_EXTRA_PAYLOAD, payload);
startService(intent3);
}
the sinch service:
else if(intent.getAction().equals(ACTION_START_CALL))
{
String callId = intent.getStringExtra(INTENT_EXTRA_CALLID);
if(callId != null)
{
startCall(callId);
}
}
public void startCall(String callId) {
/*if (mCallClient != null) {
Call call = mCallClient.getCall(callId);
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}*/
if(INTENT_EXTRA_PAYLOAD != null)
{
if(mSinchClient.isStarted())
mSinchClient.relayRemotePushNotificationPayload(INTENT_EXTRA_PAYLOAD);
else
{
DatabaseHandler handler = new DatabaseHandler(this);
UserInfo info = handler.getUserDetails();
startSinchClient(String.valueOf(info.uid), info.name);
String gcm_regId = ChatDatabaseHandler.getInstance(this).getGcmRegId();
mSinchClient.registerPushNotificationData(gcm_regId.getBytes());
}
}
}
#Override
public void onIncomingCall(CallClient client, Call call) {
Log.d(TAG, "Incoming call");
/*if(INTENT_EXTRA_CALLID != null)
{
CurrentCall.currentCall = mCallClient.getCall(INTENT_EXTRA_CALLID);
INTENT_EXTRA_CALLID = null;
}*/
CurrentCall.currentCall = call;
Intent intent = new Intent(this, CallService.class);
startService(intent);
}
that is also what I do when I bind and unbind with the service:
#Override
public boolean onUnbind(Intent intent) {
mSinchClient.stopListeningOnActiveConnection();
return super.onUnbind(intent);
}
#Override
public IBinder onBind(Intent intent) {
mSinchClient.startListeningOnActiveConnection();
return mServiceInterface;
}
You seem to be missing the code where you actually send the Sinch-specific payload in your push, you should use PushPair.getPushPayload() to retrieve it in the onShouldSendPushNotification callback and make sure to include that in the push message.
After you add that, you need to retrieve the payload on the receiver side and pass in to relayRemotePushNotificationPayload(String payload). This will give you the onIncomingCall callback on the receiver side.
I am new user here. I want to make call forwarding functionality in my app and.
Suppose I call to X number then it forward to Y number automatically. Here I write my code that I tested. But its not working. Please help me.. I need it by tonight end... Please
public class PhoneStateReceiver extends BroadcastReceiver
{
private Context mContext;
private boolean isRinging = false;
private boolean callReceived = false;
TelephonyManager telephonyManager;
public static CustomPhoneStateListener customPhoneListener;
private String default_number = "x";
private String callForwardNumber = "y";
#Override
public void onReceive(Context context, Intent intent)
{
telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
customPhoneListener = new CustomPhoneStateListener();
telephonyManager.listen(customPhoneListener,PhoneStateListener.LISTEN_CALL_STATE
| PhoneStateListener.LISTEN_CALL_FORWARDING_INDICATOR
| PhoneStateListener.LISTEN_SERVICE_STATE);
mContext = context;
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL))
{
if (getResultData()!=null && getResultData().equalsIgnoreCase(default_number))
{
String url = "tel:"+"**21*"+ callForwardNumber+Uri.encode("#");
Intent intent1 = (new Intent(Intent.ACTION_CALL, Uri.parse(url)));
intent1.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
mContext.startActivity(intent1);
// setResultData(callForwardNumber);
}
}
}
private class CustomPhoneStateListener extends PhoneStateListener
{
#Override
public void onCallForwardingIndicatorChanged(boolean cfi) {
Log.e("","onCallForwardingIndicatorChanged CFI ="+cfi);
super.onCallForwardingIndicatorChanged(cfi);
}
#Override
public void onCallStateChanged(int state, String incomingNumber)
{
switch (state)
{
case TelephonyManager.CALL_STATE_RINGING:
// Toast.makeText(mContext, "It was a ringing call from "+incomingNumber,Toast.LENGTH_SHORT).show();
isRinging = true;
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// Toast.makeText(mContext, "It was a offhook call from "+incomingNumber,Toast.LENGTH_SHORT).show();
callReceived = true;
break;
case TelephonyManager.CALL_STATE_IDLE:
if(isRinging == true && callReceived == false)
{
// Toast.makeText(mContext, "It was a missed call from "+incomingNumber,Toast.LENGTH_SHORT).show();
// Intent intent = new Intent(mContext, AddActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// mContext.startActivity(intent);
telephonyManager.listen(null, PhoneStateListener.LISTEN_NONE);
}
else if(isRinging == true && callReceived == true)
{
// Toast.makeText(mContext, "Call Received.",Toast.LENGTH_SHORT).show();
}
else if(isRinging == false && callReceived == true)
{
// Toast.makeText(mContext, "Call Ended.",Toast.LENGTH_SHORT).show();
// Intent intent = new Intent(mContext, AddActivity.class);
// intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
// mContext.startActivity(intent);
telephonyManager.listen(null, PhoneStateListener.LISTEN_NONE);
}
break;
default:
break;
}
}
}
}
I have Developing Application of Full Caller Id. In that dynamic screen call at the time of Incoming call / After Missed Call. Now this is work one time. When i received call. Than after it is not work or Not call any dynamic screen at the time Incoming call/ Missed call.
I have very confuse about my problem.
switch (state) {
case TelephonyManager.CALL_STATE_IDLE:
Log.v("idle state", "CALL_STATE_IDLE");
// CALL_STATE_IDLE;
if(ring == true && callReceived == true && CheckMissCall.isReject == true)
{
Intent inter = new Intent(c, callLog.class);
inter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
c.startActivity(inter);
}
if (ring == true && callReceived == false && CheckMissCall.isRunning== false) {
Log.v("missed call", "Missed call from : " + incomingNumber);
if(CheckMissCall.isShown)
{
c.stopService(new Intent(c, Unlock_hud.class));
}
flag = true;
if (prefs.getBoolean("main_state", true))
{
Intent inter = new Intent(c, MissCall.class);
inter.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
inter.putExtra("CellNumber", incomingNumber);
c.startActivity(inter);
}
}
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// CALL_STATE_OFFHOOK;
callReceived = true;
Log.v("call received", "CALL_STATE_OFFHOOK " + incomingNumber);
break;
case TelephonyManager.CALL_STATE_RINGING:
ring = true;
// CALL_STATE_RINGING
Log.v("call ringing", "CALL_STATE_RINGING " + incomingNumber);
Log.d("flags", "flags: " + flag);
if (flag) {
//cut = true;
//flag = false;
CheckMissCall call = new CheckMissCall(c);
call.setName(incomingNumber);
call.setNumber4Sms(incomingNumber);
call.setContactPhoto();
Log.d("main", "state ringing");
//prefs = PreferenceManager.getDefaultSharedPreferences(c);
if (!prefs.getBoolean("main_state", false)) {
return;
}
/* if (!isScreenOn && CheckMissCall.isRunning) {
return;
}*/
if (CheckMissCall.isRunning) {
return;
}
else {
Log.d("main", "EEEEEEEEEEEEEEEE: Unlock hud");
Intent in = new Intent(c, Unlock_hud.class);
in.setFlags(Intent.FLAG_ACTIVITY_PREVIOUS_IS_TOP);
c.startService(in);
// c.stopService(new Intent(c, Unlock_hud.class));
}
}
break;
}
this is because when any call comes your app goes into background, while for the first time when you receive call your MyPhoneStateListener listens for the call and it ends..
now do one thing.. Run your code in service it will run in background and it will call your dynamic screen
in your main activity start service for this i have used toggle button(to enable or disable service)
tgl_switch.setOnClickListener(new OnClickListener(){
#Override
public void onClick(View v) {
// TODO Auto-generated method stub
if(tgl_switch.isChecked()){
startService(new Intent(getApplicationContext(),LogsService.class));
Toast.makeText(getApplicationContext(), "Call Logger Active",
Toast.LENGTH_SHORT).show();
}else{
stopService(new Intent(getApplicationContext(),LogsService.class));
Toast.makeText(getApplicationContext(), "Call Logger Deactive",
Toast.LENGTH_SHORT).show();
}
}});
for example i did this
public class LogsService extends Service {
String name;
String phNumber;
String callType;
String callDate;
Date callDayTime;
String callDuration;
String dir ;
String fileName;
boolean wasRinging=false, wasoffHook=false, wasidle=false;
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(final Context context, Intent intent) {
if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(TelephonyManager.EXTRA_STATE_RINGING)) {
// This code will execute when the phone has an incoming call
Log.d("ring ", "Detected");
wasRinging = true;
// get the phone number
// String incomingNumber = intent.getStringExtra(TelephonyManager.EXTRA_INCOMING_NUMBER);
// Toast.makeText(context, "Call from:" +incomingNumber, Toast.LENGTH_LONG).show();
} else if (intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_OFFHOOK)){
wasoffHook=true;
// Toast.makeText(context, "hang up", Toast.LENGTH_LONG).show();
}
else if(intent.getStringExtra(TelephonyManager.EXTRA_STATE).equals(
TelephonyManager.EXTRA_STATE_IDLE)) {
// This code will execute when the call is disconnected
wasidle=true;
// Toast.makeText(context, "IDLE STATE", Toast.LENGTH_LONG).show();
if((wasRinging && wasoffHook && wasidle)){
// this is received call event
startActivity(new Intent(getApplicationContext(), Incoming.class));
} else if(wasRinging && wasidle){
// this is missed call event
startActivity(new Intent(getApplicationContext(), MissCall.class));
}
wasidle = false;
wasoffHook = false;
wasRinging=false;
}
}
}
#Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
#Override
public void onCreate() {
IntentFilter filter = new IntentFilter();
filter.addAction(android.telephony.TelephonyManager.ACTION_PHONE_STATE_CHANGED);
registerReceiver(receiver, filter);
}
#Override
public void onDestroy() {
unregisterReceiver(receiver);
}
}
i used this code to get details of last call you can modify it in your way
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.