stop android emulator call - android

I am working on an Android application, having functionality like voicemail.
I am using BroadcastReceiver to get dialing events.
I have to get the event "WHEN CALL IS UNANSWERED (not picked after few rings) FROM RECEIVER".
I will do some actions on caller end against this event.
I am using AVD emulator, and
I do call from one instance to another instance and it calls perfectly,
but the problem is: It continuously calls until I reject or accept the call.
This way I cannot detect that "CALL IS UNANSWERED AFTER A NUMBER OF RINGS".
So I want the Caller emulator to drop the call after a number of rings (if unanswered) like a normal phone.
I can do it (drop the call after some time) by writing some code, but I need the natural functionality of phone in the emulator.
Can anyone please guide me? Is there any settings in the emulator? Or something else?
The code is shown below in case it helps:
public class MyPhoneReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent)
{
Bundle extras = intent.getExtras();
if (extras != null)
{
String state = "my call state = " + extras.getString(TelephonyManager.EXTRA_STATE);
Log.w("DEBUG", state);
}
}

Hi i think this is impossible with reference to the link:
http://android.bigresource.com/Track/android-sr1t1eagx/
Regards

Related

Bring app to front from foreground service

I have an app that enables people to send alarms to groups of other users and I have implemented support to trigger alarms from a BLE device. It all works as expected, except for when the app is in background.
I use a foreground service to listen for the device event and a local broadcast to trigger the actual alarm. The alarm get triggered as expected and all code runs (sending alarm to server, playing audio, etc) but the app stays in background.
I have tried several solutions but failed to come up with a working one. Either the answers are too old or they just do not work (as in unwanted results).
I want the exact same result as when tapping the foreground notification = resume the current activity without passing destroy.
I'm actually surprised how hard this seems to be, in my opinion it should be easy as "bringToFront()" since the activity is obviously running.
Any help would be much appreciated!
I don't think any of my code would help to understand my problem, but here's some anyways:
AlarmDeviceService.java - The service listening for BLE events:
private void sendAlarmTriggerBroadcastMessage(String deviceName){
Intent intent = new Intent();
intent.setAction(ALARM_DEVICE_TRIGGERED);
intent.putExtra(INTENT_EXTRA_SOURCE_NAME, deviceName);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);
}
AlarmDeviceBroadcastReceiver.java:
public void onReceive(Context context, Intent intent){
String action = intent.getAction();
Log.d(TAG, "Received: "+ action);
if(mReceiver != null){
if(action.equals(AlarmDeviceService.ALARM_DEVICE_TRIGGERED)) {
mReceiver.onDeviceAlarmBroadcast();
}
else if(action.equals(AlarmDeviceService.ALARM_DEVICE_CONNECTED)){
String mac = intent.getStringExtra(AlarmDeviceService.INTENT_EXTRA_SOURCE_MAC);
mReceiver.onAlarmDeviceConnected(mac);
}
else if(action.equals(AlarmDeviceService.ALL_DEVICES_CONNECTED)){
mReceiver.onAllDevicesConnected();
}
}
}
AlarmActivity.kt - The activity that should be brought to front:
override fun onDeviceAlarmBroadcast(){
if (alarmUtilities?.alarmSentHandler?.currentSentAlarm == null) {
Log.d(LOG, "Doing it!")
triggerDefaultAlarm()
}else{
alarmUtilities?.alarmSentHandler?.cancelAlarm()
}
}
If my question is poorly put, please excuse me - it's my first post.

Android- Telephone app that keeps focus on outgoing & incoming phoneCall

Using this simple example to create a PhoneCall application that dials out a hard coded # and monitors phone state.
http://www.mkyong.com/android/how-to-make-a-phone-call-in-android/
Unfortunately, on making the phone call, we always switch to the actual built -in phone application.
I want to avoid this, or at the very least hide the dialer pad button. The user SHOULD NOT have the option to enter a phone#.
Does anyone know of a way to achieve this?
i.e. keep the actual built-in phone application in the background
(I would need to add buttons for speaker, and end call in the primary application)
OR
alternatively, hide just the dial pad button in the native, built-in phone application?
Here is a solution I came up with to hide the caller app shortly after the call is placed. I don't believe there is a way to make it totally transparent without re-writing the Android system. I believe this could be improved by detecting when the caller app is set up and dialing instead of the postDelayed() I'm using which could be unreliable.
EDIT: I tried making a receiver to listen for NEW_OUTGOING_CALL to restart the original Activity, but it doesn't really improve anything, the dialer app must be running for an arbitrary amount of time before it can start it's background service.
EDIT: I tried making a PhoneStateListener that listens for CALL_STATE_OFFHOOK and re starts the Activity there. This doesn't work either as it happens before the dialing app is fully ready to go into the background.
EDIT: You can look at this thread: Reflection to access advanced telephony features, but I believe Google has since locked down all methods of placing a call outside the standard app.
This solution will start the dialing, and then switch back to the original Activity after a couple of seconds.
In my manifest I have:
android:launchMode="singleInstance"
on my Activity so I don't get a new instance.
public class MainActivity extends Activity
{
....
public void clickMe(View view)
{
startService(new Intent(this, PhoneService.class));
}
}
public class PhoneService extends Service
{
#Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Intent call = new Intent(Intent.ACTION_CALL);
call.setData(Uri.parse("tel:XXXXXXXXX"));
call.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(call);
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run()
{
Intent act = new Intent(PhoneService.this, MainActivity.class);
act.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(act);
}
}, 4000);
return super.onStartCommand(intent, flags, startId);
}
#Override
public IBinder onBind(Intent arg0)
{
// TODO Auto-generated method stub
return null;
}
}
I believe it impossible to provide a cleaner solution, given the constraints of the SDK.
The functionality you are wanting isn't possible without some type of hack-ish work around. The Android system only allows the Phone app to control the underlying RIL and telephony stack and the Phone app UI responds to the dial URI by presenting this user with the dial screen where they must confirm (or alter) the number. This is a security provision to prevent unwanted apps from using the telephone device without the user knowing about it. Also, due to the way the Intent system works in Android, it is possible for other apps to handle calls using SIP or other VoIP functionality (i.e. Skype). In this case the user may have set a global preference to always use the other app and you have no control over how that app behaves with the dial Intent.

Read Phone State Reciever not working on real device

I have tested my reciever on emulator and simulate face call to emulator and can log phone state even get calling number,
However if i try this on real device, it is not working. I added an activity and if it working background, it works. But why should i add it? Why has to activity run on background?
#Override
public void onReceive(Context cnx, Intent nt) {
Bundle bnd = nt.getExtras();
Log.e("EXTRA", "EXTRA");
if (bnd != null) {
String state = bnd.getString(TelephonyManager.EXTRA_STATE);
Log.i("PHONE STATE", state);
if (state.equals(TelephonyManager.EXTRA_STATE_RINGING)) {
Log.i("PHONE STATE",
bnd.getString(TelephonyManager.EXTRA_INCOMING_NUMBER));
}
}
Activity meant to be run in Foreground, If you want to run your process in Background you should use Services.
read here more
For your question, You should have separate class for receiver, Register receiver in Manifest file for Phone state change action and with permission to read phone state.

What is the correct way of handling the action NEW_OUTGOING_CALL while looping?

At the moment I am developing an application which catches the action NEW_OUTGOING_CALL with the help of a BroadcastReceiver. I am aborting the call by calling setResultData(null). After that I am showing the user a dialog which allows him to decide if he wants to use my application to rewrite its number. When the users decision has happened I am placing the new call depending on the decision. Now my broadcast receiver gets called up once again.
What is the correct way of getting to know that I have already processed the number? I got a working solution that uses a timestamp to guess if it could be already processed. Another solution would be to add a "+" at the end of the processed number.
These methods are working fine for my application being the only one catching the NEW_OUTGOING_CALL event. But what should I do when other applications (like Sipdroid or Google Voice) are also sitting there catching the NEW_OUTGOING_CALL broadcast aborting it and restarting it again? I don't see a possibility to get to know if we are still in the same "call flow" and if I already processed the number.
I would love to hear your ideas about this problem!
What API level are you working with? If it's >= 11, check out the new BroadcastReceiver.goAsync function that lets you extend the processing of the broadcast outside of the onReceive function of your receiver. This could bypass the need to loop altogether.
If, like me, you're stuck trying to do this before level 11, it is surprisingly tricky to do this elegantly. You may have done this as well, but I tried to include a "processed" flag as an extra in the ACTION_CALL intent that my code generated, hoping that it would somehow get included in the resulting ACTION_NEW_OUTGOING_CALL broadcast, but that sadly does not work.
The best solution I have been able to find is including a fragment in the URI for the ACTION_CALL intent that you generate. This fragment will be included for the resulting ACTION_NEW_OUTGOING_CALL broadcast, so your broadcast receiver can differentiate between the original call and the one that you generate, but it won't interfere with handlers that aren't looking for it.
Here's the basic code.
In your BroadcastReceiver for the ACTION_NEW_OUTGOING_CALL
public class YourBroadcastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// extract the fragment from the URI
String uriFragment = Uri.parse(
intent.getStringExtra("android.phone.extra.ORIGINAL_URI")).getFragment();
// if the fragment is missing or does not have your flag, it is new
if (uriFragment == null || !uriFragment.contains("your_flag")) {
// launch your activity, pass the phone number, etc.
// use getResultData to get the number in order to respect
// earlier broadcast receivers
...
// abort the broadcast
this.setResultData(null);
this.abortBroadcast();
}
// otherwise, your code is there, this call was triggered by you
else {
// unless you have a special need, you'll probably just let the broadcast
// go through here
// note that resultData ignores the fragment, so other receivers should
// be blissfully unaware of it
}
}
}
When the user first dials the number, the fragment will either be missing altogether or your flag won't be present, so you'll abort the broadcast and start your activity. In your activity, if you decide to place the call again, do something like the following:
startActivity(new Intent(Intent.ACTION_CALL,
Uri.parse("tel:" + modified_number + "#your_flag")));
The "your_flag" fragment will then be present in the subsequent NEW_OUTGOING_CALL broadcast and thus allow you to handle this case differently in your broadcast receiver.
The nice thing about this is the the fragment is completely ignored unless you look for it in the ORIGINAL_URI, so other broadcast receivers can continue to function. If you want to be really nice, you may want to look for an existing fragment and add your flag to it (perhaps with a comma separator).
I hope that helps. Good luck!
I don't see a possibility to get to
know if we are still in the same "call
flow" and if I already processed the
number.
Technically, you are not in the same "call flow" as placing a new call is asynchronous. You have to use hints (such as a timestamp) as you seem to be doing already.
If you are confident that other applications will not rewrite the number except to change the prefix or to add a suffix, you may want to add another "proximity check" hint to avoid false positives/negatives, but I'm afraid that's about all you can do.
The onReceive() method in Broadcast receiver receives an Intent as an argument.
Extract the Bundle from the Intent using Intent.getExtras().
This Bundle contains 3 key-value pairs as follows :
android.phone.extra.ALREADY_CALLED = null
android.intent.extra.PHONE_NUMBER = 98xxxxxx98
android.phone.extra.ORIGINAL_URI = tel:98xxxxxx98
98xxxxxx98 is the number dialled by the user.
When the onReceive() is called again, this number changes to 98xxxxxx98* or 0*
By checking for the asterisk(*) at the end of the dialled number, it can be inferred if the onReceive() method is called for the first time or the next subsequent times.
One of the answers would be to track the boolean extra in the intent. It is done in similar way by the Google Phone app. You can check this BroadcastReceiver here (look for alreadyCalled usage)
The other way would be just to pass that "rewritten" number from your broadcast to the next broadcast receiver down the road (can be any app, like Sipdroid, Google Voice, or custom VoIP app) without calling ACTION_CALL intent (this is why you get loop and you broadcast receiver called again) The following code is example of how I am handling call in my custom VoIP app. When I intercept NEW_OUTGOING_CALL in my broadcast receiver, I first check if there is internet connection. If phone is connected to internet I use custom defined intent action of my activity to place call through my VoIP app. If there is no internet connection, I just set original phone number to the broadcast receiver result data. This is used by the next broadcast receiver (probably default phone app, but doesn't have to be) in the flow to place a call.
public class BHTTalkerCallReceiver extends BroadcastReceiver {
private static final String TAG = "BHTTalkerCallReceiver";
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Broadcast successfull ... ");
// Extract phone number reformatted by previous receivers
String phoneNumber = getResultData();
if (phoneNumber == null) {
// No reformatted number, use the original
phoneNumber = intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
}
if (isNetworkAvailable(context)) { // Make sure this app handles call only if there is internet connection
// My app will bring up the call, so cancel the broadcast
setResultData(null);
// Start my app to bring up the call
Intent voipCallIntent = new Intent(context, TalkerActivity.class);
voipCallIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
voipCallIntent.putExtra(TalkerActivity.OUT_CALL_NUMBER, phoneNumber);
voipCallIntent.setAction(TalkerActivity.BHT_TALKER_OUT_CALL);
context.startActivity(voipCallIntent);
} else { //otherwise make a regular call...
// Forward phone data to standard phone call
setResultData(phoneNumber);
}
}
private boolean isNetworkAvailable(final Context context) {
final ConnectivityManager connectivityManager = ((ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE));
return connectivityManager.getActiveNetworkInfo() != null && connectivityManager.getActiveNetworkInfo().isConnected();
}
}

Is it possible for an Android app to end a call that it initiated?

Looking through forums, it seems that there is not a way to end calls, but on the Android Developers page, the permission PROCESS_OUTGOING_CALLS "Allows an application to monitor, modify, or abort outgoing calls." I can't find any documentation on how to end a call even with this permission. Is this possible, or is it just a mistake on the page?
http://developer.android.com/reference/android/Manifest.permission.html#PROCESS_OUTGOING_CALLS
The attention is not to end call that is already started, but to drop the call before that was started. The meaning is - you dial some number , press send , program receives the call request and aborts it , so the call never starts. It is also possible just to change the phone number (to extend short numbers to full one, etc.) and pass the call.
It works fine:
public class phoneReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_NEW_OUTGOING_CALL)) {
abortBroadcast();
if (getResultData()!=null) {
String number = null;
setResultData(number);
}
}
}
}

Categories

Resources