Android application getting killed because of incoming call - java

In my application I am copying all the Call Logs into a Database in an Async Task. But If a call comes in between my application can get terminated leading to incomplete data. So first of all I want to stop my application from getting terminated in such scenario, so what should I do? Also I want to keep track of cursor such that when application is opened again it will continue from the exact same place where it stopped and complete the job.

This is the code that helped me save my game state during incoming call.. Hope it helps you too...
TelephonyManager tm;
private PhoneStateListener mPhoneListener = new PhoneStateListener() {
public void onCallStateChanged(int state, String incomingNumber) {
try {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
Toast.makeText(GameActivity.this, "CALL_STATE_RINGING", Toast.LENGTH_SHORT).show();
//Your function to save state right here...
stopTimer();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Toast.makeText(GameActivity.this, "CALL_STATE_OFFHOOK", Toast.LENGTH_SHORT).show();
break;
case TelephonyManager.CALL_STATE_IDLE:
Toast.makeText(GameActivity.this, "CALL_STATE_IDLE", Toast.LENGTH_SHORT).show();
break;
default:
Toast.makeText(GameActivity.this, "default", Toast.LENGTH_SHORT).show();
Log.i("Default", "Unknown phone state=" + state);
}
} catch (Exception e) {
Log.i("Exception", "PhoneStateListener() e = " + e);
}
}
};

Related

onActivityResult() never gets called

I have a class used as interface inside my MainActivity.java:
public class prova{
prova(){
}
#JavascriptInterface
public void displayGPSRequest() {
result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
#Override
public void onResult(LocationSettingsResult result) {
final Status status = result.getStatus();
switch (status.getStatusCode()) {
case LocationSettingsStatusCodes.SUCCESS:
Log.i(TAG, "All location settings are satisfied.");
break;
case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
Log.i(TAG, "Location settings are not satisfied. Show the user a dialog to upgrade location settings ");
try {
// Show the dialog by calling startResolutionForResult(), and check the result
// in onActivityResult().
status.startResolutionForResult(MainActivity.this, REQUEST_CHECK_SETTINGS);
} catch (IntentSender.SendIntentException e) {
Log.i(TAG, "PendingIntent unable to execute request.");
}
break;
case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
Log.i(TAG, "Location settings are inadequate, and cannot be fixed here. Dialog not created.");
break;
}
}
public void onActivityResult(int requestCode, int resultCode, Intent data)
{
//final LocationSettingsStates states = LocationSettingsStates.fromIntent(data);
switch (requestCode)
{
case REQUEST_CHECK_SETTINGS:
switch (resultCode)
{
case Activity.RESULT_OK:
{
// All required changes were successfully made
Toast.makeText(MainActivity.this, "Location enabled by user!", Toast.LENGTH_LONG).show();
break;
}
case Activity.RESULT_CANCELED:
{
// The user was asked to change settings, but chose not to
Toast.makeText(MainActivity.this, "Location not enabled, user cancelled.", Toast.LENGTH_LONG).show();
break;
}
default:
{
break;
}
}
break;
}
}
});
}
}
Inside the function displayGPSRequest() I have startResolutionForResult() that should call the method onActivityResult() but it never does. I tried to see other posts where they used fragments but I don't have really understood them. I hope you can help with this.
onActivityResult should be overriden in the associated Activity - currently you're just declaring a method in the ResultCallback which never gets called.

How count missed call or reject call in android studio

Here I make a call from my app and I want to count missed or reject call
and I use a counter (counterNoiseCalling) to count missed or reject call but in node in Firebase counter still always equal 0 and I don't know why.
private class MyPhoneListener extends PhoneStateListener {
private boolean onCall = false;
String userNameCalling = UserDetails.username;
int counterNoisingCall = 0;
#Override
public void onCallStateChanged(int state, String incomingNumber) {
switch (state) {
case TelephonyManager.CALL_STATE_RINGING:
// phone ringing...
Toast.makeText(Call.this, incomingNumber + " calls you", Toast.LENGTH_LONG).show();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
// one call exists that is dialing, active, or on hold
Toast.makeText(Call.this, "on call...", Toast.LENGTH_LONG).show();
if(!onCall) {
//because user answer the incoming call
Toast.makeText(Call.this, "The call is being answered", Toast.LENGTH_SHORT).show();
}else {
// reject call or missed call
Toast.makeText(Call.this, "Number Busy Or No Reply", Toast.LENGTH_SHORT).show();
counterNoisingCall++;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
// in initialization of the class and at the end of phone call
// detect flag from CALL_STATE_OFFHOOK
if (onCall == true) {
Toast.makeText(Call.this, "restart app after call to Users List", Toast.LENGTH_LONG).show();
// restart our application to return to Our Contact
Intent restart = new Intent(Call.this , Users.class);
restart.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
startActivity(restart);
onCall = false;
}
break;
default:
break;
}
Firebase childRef = mRootRef.child(userNameCalling);
childRef.setValue(counterNoisingCall);
}
}
If you can debug and see that counterNoisingCall variable is not 0 then the problem seem to be related to Firebase.
I guess that may be is related to security rules. Maybe the user does not have permission write on the Firebase node.
I would put a complete listener on setValue to see that the command completed with success.
Try this.
Firebase childRef = mRootRef.child(userNameCalling);
childRef.setValue(counterNoisingCall).addOnCompleteListener(new OnCompleteListener<Void>() {
#Override
public void onComplete(#NonNull Task<Void> task) {
if (!task.isSuccessful()) {
Log.d("",task.getException().getMessage());
}
}
});

How do I switch layout when connected to a Bluetooth device in a Handler?

So I would like to change the layout once i'm successfully connected to a Bluetooth device. I would like to do this in my Handler, but I don't know how. As you can see in my Handler code below , I've tried this in my case BTHandler.STATE_CONNECTED: (this is just copied from BluetoothChat) but I dont know how.
private Handler mHandler = new Handler() {
#Override
public void handleMessage(Message msg) {
switch (msg.what) {
case Constants.MESSAGE_STATE_CHANGE:
switch (msg.arg1) {
case BTHandler.STATE_CONNECTED:
setStatus(getString(R.string.title_connected_to, mConnectedDeviceName));
mConversationArrayAdapter.clear();
break;
case BTHandler.STATE_CONNECTING:
Toast.makeText(getApplicationContext(), "Connecting…", Toast.LENGTH_SHORT).show();
Log.v("Log", "connecting");
break;
case BTHandler.STATE_LISTEN:
case BTHandler.STATE_NONE:
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
Log.v("Log", "connected");
break;
}
}
}
};
Solved the problem by myself.
guiHandler(Constants.CONNECTION_STATUS, Constants.STATE_CONNECTED, "");
This is written in my run method that's inside a ConnectThread.

How to get more information on incoming call

I have set up my virtual phone numbers to forward calls on my cell phone. When the call is forwarded, I am receiving the incoming number, but not what number they dialed us to reach.
Is it possible to get the number they dialed us to reach?
public class MyPhoneStateListener extends PhoneStateListener {
private String[] projection = new String[] {
People._ID, People.NAME, People.NUMBER
};
public void onCallStateChanged(int state,String incomingNumber){
switch(state)
{
case TelephonyManager.CALL_STATE_IDLE:
Log.d("DEBUG", "IDLE");
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
if(!incomingNumber.equals("")){
handleCall(incomingCall);
}
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d("DEBUG", "RINGING");
break;
}
}
From what I have learnt, it is only possible to get the incoming number.

How to "properly" send sms when call is received?

I am trying to have an Android Service listen for an incoming phone call and when one does occur, grab the incoming number and text it a message.
In my service I have made a PhoneStateListener:
TelephonyManager tManager = (TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE);
PhoneStateListener listener = new PhoneStateListener()
{
#Override
public void onCallStateChanged(int state, String incomingNumber)
{
switch(state)
{
case TelephonyManager.CALL_STATE_IDLE:
Log.d(TAG, "Phone: Idle");
break;
case TelephonyManager.CALL_STATE_RINGING:
Log.d(TAG, "Phone: Ringing.");
Log.i(TAG, "Incoming call from: " + incomingNumber);
sendSms();
break;
case TelephonyManager.CALL_STATE_OFFHOOK:
Log.d(TAG, "Phone: Off Hook");
break;
}
}
};
tManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
My sendSms() function is as follows:
private void sendSms()
{
SmsManager manager = SmsManager.getDefault();
wakeLock.acquire();
Log.d(TAG, "Wake Lock Acquired!");
if (getMessageContent(getInformStatus()).length() > 160)
{
ArrayList<String> messagelist = manager.divideMessage(getMessageContent(getInformStatus()));
manager.sendMultipartTextMessage(getReturnAddress(), null, messagelist, null, null);
Log.i(TAG, "Multipart Text Message Sent!");
}
else
{
manager.sendTextMessage(getReturnAddress(), null, getMessageContent(getInformStatus()), sentPI, null);
Log.i(TAG, "Text Message Sent!");
}
wakeLock.release();
Log.d(TAG, "Wake Lock Released!");
}
I even have an SMS_SENT Broadcast Receiver to check if the text message sent out correctly that will recall the sendSms() function if it did not sent for whatever reason:
resend = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
switch (getResultCode())
{
case SmsManager.RESULT_ERROR_GENERIC_FAILURE:
Log.e(TAG, "Text did NOT send (GENERIC_FAILURE)");
Log.i(TAG, "Attempting to resend");
sendSms();
break;
case SmsManager.RESULT_ERROR_NO_SERVICE:
Log.e(TAG, "Text did NOT send (NO_SERVICE)");
Log.i(TAG, "Attempting to resend");
sendSms();
break;
case SmsManager.RESULT_ERROR_RADIO_OFF:
Log.e(TAG, "Text did NOT send (RADIO_OFF)");
Log.i(TAG, "Attempting to resend");
sendSms();
break;
}
}
};
registerReceiver(resend, new IntentFilter("android.provider.Telephony.SMS_SENT"));
This works on my phone fine, however on other people's phones it likes to sometimes toggle back and forth between RINGING and IDLE in the PhoneStateListener a few times before "sending".. The phone actually says that the application is trying to send multiple text messages and asks the user if that is okay. When they click yes, it just asks again.
To make it better, it never actually sends the text message either..
On another phone, it doesn't do this at all.. The other phone will go through the motions and the logcat is identical to mine.. It actually says it sends, but the recipient never gets the SMS..
It is suppose to be an auto-response service of sorts and I wanted to try and make it work on at least Froyo, Gingerbread, and Ice Cream Sandwich..
By the way, it works 100% on my:
Galaxy Nexus (toro) (Android 4.0.3)
Droid 1 (sholes) (Android 2.3.7)
HTC Thunderbolt (mecha) (Android 2.3.7)
However, if it's my friend's:
Nexus S 4G (crespo4g) (Android 4.0.3)
or my other friend's
Galaxy Nexus (toro) (Android 4.0.3)
It does not work..
What I really don't understand is that it doesn't work with my friend with the exact same phone as me..
I feel like this code implementation is a hit or miss and was wondering if anyone had some insight to help out.
Appreciate it!
I think I figured it out. What I ended up doing is putting a Handler that called a Runnable 30 seconds after the phone call was initially received.. This gave the phone time to finish the phone call (assuming it was in your pocket) and then cleanly send the text message..
I hope this is the only issues I was having, but it seems to work on my friends Galaxy Nexus (toro) now..
Hope this helps anyone else wondering about this..
Cheers!

Categories