How to show something on Incoming Call Screen - android

I am developing an app that shows the location of the caller when an incoming call come on incoming call screen. I am succesfully fetching the location from my algorithm but I am not able to display it on Deafult Incoming Screen.
If i use A toast then it just appears for 1 or 2seconds, I want ihe information shoulkd appear till the call picked.
What should I use Toast, Notification or something , and how to do that.
In short how can I show something on Incoming Call Screen till the call picked up
class IncomingCallREceiver extends BroadcastReciever
{
void onRecieve()
{
// here I want to show the Information
}
}

You are not able to override Android's call screen, and with good reason, things may get spoofed!
With that said, a Dialog would most likely be the best solution to showing something before the user picks up. The easiest way to make a Dialog is with DialogFragments. However since Dialogs cannot be shown from receivers, you will need to start an Activity. So your onReceive() code should look something like this:
void onReceive(Context context, Intent intent)
{
Intent showDialogIntent = new Intent (context, DialogActivity.class);
showDialogIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startIntent (showDialogIntent);
}
And then when your DialogActivity is started, it's onCreate() method would make the Dialog and show it to the user.

Related

StartActivity in Broadcastreceiver opens up the app every time it is called

I have a BroadcastReceiver, and on its OnReceive I am supposed to call a method which is defined in the MainActivity. wherever I searched I found that I will have to write the following code.
Bundle bundle = intent.Extras;
Intent callingIntent = new Intent(context, typeof(MainActivity));
callingIntent.PutExtra("isSynched", true);
callingIntent.AddFlags(ActivityFlags.NewTask);
callingIntent.AddFlags(ActivityFlags.SingleTop);
context.StartActivity(callingIntent);
Now this calls my method, but the app keeps opening up. I don't want that to happen. I want the method to be called when the app is in background and want the app to be in background. What should I do? I am using xamarin to write the code.
I have created a service that gets the data but after I receive data I have to call a method in MainActivity to update the calendar. I am currently doing it in OnReceive like this, public override void
OnReceive(Context context, Android.Content.Intent intent)
{
if (context.GetType().Equals(typeof(MainActivity)))
{
((MainActivity)context).SyncCalendar();
}
}
this context is coming as restrictedaccess. So not able to call SyncCalendar Method
Depending on whether you need or not execute that code all the time your app lives, I'd recommend:
AsyncThread: This is somelike an improved version of a Thread as it already implements some of the mechanisms you would need to set manually with a Thread, but it's not recommended to execute all your app life, just for ending processes. You may find more info there
Service: Otherwise, if your function is intended to run all your app's life long, Service is the correct choice. It's a bit harder to understand than the AsyncThread, as it's a class that it's executed until you stop it paralelly to your main UI, but it's not a thread. You may find this useful and also this.

How can I tell from my Application whether it was started from my BroadcastReceiver or not?

How can I tell from my Application whether it was started/resumed from my BroadcastReceiver or not?
I intercept outgoing calls (android.intent.action.NEW_OUTGOING_CALL). If getString(Intent.EXTRA_PHONE_NUMBER) is one of a set of numbers, I abort that call (setResultData(null)) and instead startActivity my app, putExtraing the particular number. If (and only if) coming from the BroadcastReceiver, I want to be able to put up an alert that's basically "use this app with this number/return to call". However, sometimes when I return to the app from elsewhere, the number still seems to be in the extras of the intent, even though I haven't come from the BroadcastReceiver. I tried checking for the FLAG_ACTIVITY_NEW_TASK flag, but it shows up sometimes when not coming from the BroadcastReceiver.
As you said: you can pass any parameters to your activity, indicating that it was called from your BroadcastReceiver. However, when resuming to your activity some code might be executed again - potentially causing unwanted outcomes. When I had once a similar issue I stored/overwrote some information in the intent, e.g.
myActivity.getIntent().putExtra("phoneNumber", "nil");
What worked for me was, that I overwrote the extra in the intent after it has been processed while finishing an ActionMode (let's say with "nil"). So later I was able to evaluate that information in onResume(), e.g.:
#Override
public void onResume() {
super.onResume();
String phoneNumber = getIntent().getExtras().getString("phoneNumber")
if ("nil".equals(PhoneNumber)) {
...
}
}
Just did a small test and it works pretty well.
Hope this helps ... Cheers!

how to pop up alarm even when the application is closed

I'm developing a location based alarm which is an Android application.
All the coding part has been done.
But the alarm alert dialog is not displaying when the application is closed.
Please help me, I'm trying to pop up the alarm even when user is using another application or is in the home screen.
The code of my alarm at the moment is shown below:
final MediaPlayer mp = MediaPlayer.create(LocAlarmProject.this, R.raw.airtel);
mp.start();
// LocAlarmProject.this below is what's causing the problem:
final AlertDialog.Builder builder=new AlertDialog.Builder(LocAlarmProject.this);
builder.setTitle(disp_title);
builder.setMessage(disp_desc);
builder.setIcon(R.drawable.alarm);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
mp.stop();
}
});
builder.show();
I am pretty sure you are looking for Service.
Copied and Paste:
A Service is an application component representing either an
application's desire to perform a longer-running operation while not
interacting with the user or to supply functionality for other
applications to use. Each service class must have a corresponding
declaration in its package's AndroidManifest.xml. Services
can be started with Context.startService() and Context.bindService().
Use Notification service to keep track of the status.....visit......http://developer.android.com/guide/topics/ui/notifiers/notifications.html
The proper way to do this requires a few steps. Sorry, it's not trivial if you haven't done it before:
First, you're going to use Android's built-in AlarmManager to schedule the time you want your app to be activated. You schedule a new alarm with the time to wake up and a PendingIntent.
Second, create your PendingIntent that's used to activate your app for the time to show the alarm.
Third, you can handle this Intent several ways, the most common is to create a class that extends BroadcastReceiver to receive the Intent. This class is notified when it's time to show the alarm. The Intent that you created and put inside your PendingIntent is passed to its onReceive() method. You pass this information to your app to display the alert dialog. --- You can alternatively just register your main app to receive the Intent instead, then override the onNewIntent(Intent) method in your Activity.
Four, register your BroadcastReceiver in your AndroidManifest.xml file. This is also the place to register this receiver to listen for the Intent you created. You do this using the <intent-filter> tag.
Five, (optional) if you want your alarm to display even if the phone is asleep, and you want to make sure it doesn't go back to sleep before the user acknowledges the alarm, you'll need to obtain a WAKE_LOCK to do so.
The reason this is preferable to using a Service is it doesn't consume resources just to wait for the alarm, and also it still works if Android decides to kill your app free up memory. Good luck and happy coding!

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