How to get a callback from Android system to the app? - android

I'm making an app in which you can chat and call with other contacts. But in case of calling, I've designed the app in such a way that after typing the number and clicking on the call icon, it takes you to native calls app for calling and updates the call log in my current app.
For this process, this is the code I've written:
if (nativeCall(mobileNumber)) {
Intent intent = new Intent(Intent.ACTION_CALL).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intent.setData(Uri.parse("tel:" + mobileNumber));
if (((BaseActivity) context).isNetworkOk()) {
addToUserCallLogs(context, DateUtils.convertTimestampToDate(), contactUri, "Out", System.currentTimeMillis());
}
context.startActivity(intent);
return true;
}
You can see that I'm putting mobile number into the intent and starting it. And I'm using addToUserCallLogs() function to show it in my app's call logs.
This works fine usually, but in the issue is in the following case.
When the user has multiple calling applications(For eg, the user has installed application named SMARTalk. Now he has native caller app and SMARTalk app to call from), in that case the Android system gives options to chose from like this:
Now, if he choses from one of them, even in that case there is no issue. Say he didn't chose any of those and clicked on the other part of the screen. Then this options bar will be closed. Since all this is happening after starting the intent, this call will be added in the call logs of the app from the function addToUserCallLogs(). But I don't want the call to be shown in the call Logs because I haven't done any call.
But according to the code I've written, before starting the intent, I'm adding into my app's call logs database. Is there a way the information of whether the call has happened or not can be sent back from the system to the app?
Or a way to get these options to be shown manually from the app?
Please comment if you need any more explanation.

I guess no way to receive the callback information because ACTION_CALL does not return a result. You can see the output is nothing from docs even you use startActivityForResult

Related

Getting user's answer (System dialog - Android)

I am a newbie on Android and I am creating a launcher. I want apps to be removed (uninstalled) so I have a list and I invoke system to uninstall it.
How can I know if the user pressed "Cancel" or "Ok" in the system dialog?
(I know the system will unisntall the app if I press "Ok" or wont if I press "Cancel", I just need to know how to get the answer to remove or not the app of my list [ArrayList]).
If you cant know it, how can I do to remove an app from a list without knowing if the user is going to uninstall it or not?
public void uninstall (int position){
Uri package1 = Uri.parse("package:"+apps_block.get(position).name.toString());
Intent uninstall = new Intent(Intent.ACTION_DELETE, package1);
startActivity(uninstall);
AppDetail toRemove = adapter_block.getItem(position);
adapter_block.remove(toRemove);
}
With this code, the app is always removed from my list even I press "Cancel".
You are removing the item from the list immediately after startActivity(). The user has not even seen the dialog yet by that point.
You could listen for the ACTION_PACKAGE_REMOVED system broadcast, confirm that it was for your requested package, and remove the package from the list at that point. By doing this from your activity via registerReceiver(), you can find out fairly quickly and have easy access to your UI code to update the list.

ObservableObject updateValue doesn't reach the right instance after startActivity

I have a basic Activity which mainly allows the user to change settings and save them. I also have a BroadcastReceiver which is launched on SMS_RECEIVED.
The main point of the app is to vibrate whenever a certain message is received until the user taps a button to make it stop. The activity is only there to allow the user to change settings and press the "Stop" button.
In my onReceive method (BroadcastReceiver), I get the content of the last message received and make the phone vibrate if the message is equal to a certain string. All of that is working perfectly, the problem is when I want to make it stop. Right now, I'm trying to make a "Stop" button appear in the Activity when the phone starts vibrating.
I understand that UI elements should remain in the Activity and so what I'm trying to do is communicate between the Activity and my BroadcastReceiver. I've found here how to do that with an Observer. The problem though is that I want the app to function at any time, even at boot time. It's very easy with a BroadcastReceiver but since it requires the Activity to be shown to allow the user to stop the vibration, I have to start the activity if it isn't started already.
So what I do is this:
Intent i = new Intent(context, MainActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
i.putExtra("SMSReceived", true);
context.startActivity(i);
ObservableObject.getInstance().updateValue(true);
The problem is, when there is no instance launched, it creates a new one and sends the extra boolean correctly but the updateValue method doesn't seem to get called at all (due to the previous instance I suppose?) and inversely, when there is an instance launched (in the background) the extra boolean doesn't get passed and the updateValue method gets called correctly.
I suppose I could just launch the Activity on boot and immediately put it in the background but it could cause problems if the user closes the application, at which point it would simply stop working until the user started it again since the Observer would have no instance to send data to.
Do you guys have any idea of what I could do to solve my problem?
If it's not clear I can try to explain further.

ANDROID: open an URL in external browser, while continuing the application

In the starting activity of my app I show a dialog to user and ask if he wants to see some contents in my website or not.
If he clicks No, the dialog disappears and I call continueActivity() to do some process and go from current activity to MainActivity.
If he click yes, I want to open the webpage in the external browser and again I call continueActivity() to do some process and go from current activity to MainActivity.
The problem is in positive state. This is my code in positive state:
Intent browserIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://www.aaa.ir"));
startActivity(browserIntent);
continueActivity();
Because of calling continueActivity(), the external browser can't open and if I don't call continueActivity(), the URL opens in the external browser and the app sticks in the current activity.
So how could I open the URL and at the same time, continue the process and go to other activities.
I usually use
startActivityForResult(browserIntent, BROWSER_REQUEST);
and override onActivityResult(int reqCode, int resultStat, Intent intent)
if(reqCode == BROWSER_REQUEST) {
continueActivity();
}
Once you call startActivity, your current Activity will follow through the exit of the Activity lifecycle. This is unavoidable.
If you have processing you want to continue in the meantime, you should consider a Service. If you want the App to return to its current state, you need to store relevant data and load your Activity to its previous state (or next intended state).
in both ways ContinueActivity is opening. i don't know you architecture. You could just add to intent some extra like
intent.putBoolean("openExternalLink", dialogResultHere);
Then in continueActivity you will got this intent like
getIntent().getBoolean("openExternalLink")
also dont forget to delete this option, otherwise you will open browser each time after Activity recreation (screen rotation, minimize, etc.)
getIntent().removeBoolean("openExternalLink");
P.S. signatures of methods could be littlebit different, but general idea is here

Android package installer - how to get "Open" and "Done" and activity result both?

My Android Application has an option to upgrade to the newer version, the newer version APK I keep it available under a path in sdcard. On click of Upgrade option I invoke following method.
public static void launchInstaller(Activity act, String apkPath)
{
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(new File(apkPath)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
act.startActivityForResult(intent, 0);
}
The reason I include FLAG_ACTIVITY_NEW_TASK, is because, after upgradation, I want to have "Open" & "Done" options, which aren't shown if I don't use this flag.
When the above code launches the package installer, it has two options OK & Cancel, when user press Cancel, I want to know user cancelled it. But I am unable to know because the onActivityResult is called pre-maturely. I come to a reason why is that happening after reading the following posts.
Android - startActivityForResult immediately triggering onActivityResult
onActivityResult() called prematurely
They ask me to make sure that the Intent I am using to launch the activity doesn't have FLAG_ACTIVITY_NEW_TASK set on it. See here:
http://developer.android.com/reference/android/content/Intent.html#FLAG_ACTIVITY_NEW_TASK
In particular note: "This flag can not be used when the caller is
requesting a result from the activity being launched."
If the activity is being launched as part of a new task then Android
will immediately call the onActivityResult() with RESULT_CANCELED
because an activity in one task can't return results to another task,
only activities in the same task can do so.
But in my case, I can't remove FLAG_ACTIVITY_NEW_TASK, because otherwise I will not get "Open" and "Done" options on successful upgradation.
Has anybody faced similar sort of problem? Kindly help me out, as it drives me nuts.
You should use package added broadcast intent. Create a broadcast receiver listen package added.
If added package equals your package, user confirm install otherwise dismiss install process. If you ask what kind extras can be return by android, android returns EXTRA_UID about package. PackageManager' s method convert uid to package.(getPackagesForUid(int uid) returns String array but it usualy return one item in the array in short usually array length equals 1.

Create new intent in background

I am looking for a way to launch another app from within my app but so that the focus is not changed from my app to the app launched.
I.e currently I have the new app launched via a intent, however when this is carried out the new app is launched and becomes the app in view, I need it to be kept in the background with my app still in view.
The reason for this?
I am developing an application for internal use that will act like a lock-screen to the device so although things must happen in the background the 'lock-screen' must always be on top.
I have done some research into intents and launching other apps but can not find anything about what I need.
Hope you can help thank you!
Currently the terminal is called like this:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.setComponent(new ComponentName("jackpal.androidterm", "jackpal.androidterm.RemoteInterface"));
intent.setAction("jackpal.androidterm.RUN_SCRIPT");
intent.putExtra("jackpal.androidterm.iInitialCommand", cmdString);
The reason it needs to be running in the background is so that the app can run commands in terminal without the user having access, but then they 'unlock' the screen they need to then be able to view the terminal and what commands are being run etc
You can not startActivity in Background.Instead start the activity and minimise the activity(in your case this activity is of different application) using moveTaskToBack(true);
In your case, put a condition based on your intent and its params and use moveTaskToBack(true); so that activity will be minimised only when your application launches.
This won't be possible, you will have to start a background Service that does the actual work and only launch the Activity you want to navigate to once your foreground Activity is finished. Depending on your architecture, you can store the Activity to call when your foreground Activity is finished and change it from the service. That way you will have your desire behaviour without having to actually call the Activity.
In addition to the answer from #Meher, in the intent for your current starting activity, you can add the flag FLAG_FROM_BACKGROUND.
With this you get rid of the "blinking" effect (the one where your activity shows for one fraction of second while it discovers wether to go to background)

Categories

Resources