Android Launch foreign application from my own - android

I am trying to get the following code to execute:
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setComponent(new ComponentName(" **Home package** "," **Home class** "));
startActivity(intent);
Essentially I am looking for a way to specifically target and load the exact, original, home application.

Technically, you have no way of always knowing "the exact, original, home application".
You can use PackageManager and queryIntentActivities() to find find who all responds to MAIN/HOME Intents. If there are two answers, and yours is one (which I am guessing is your situation), then the other is "the exact, original, home application" pretty much by definition. You can further verify this by getting to the ApplicationInfo object associated with the resolved activity and checking for FLAG_SYSTEM to see if it is installed in the system image. This approach is probably not completely bulletproof, but it may be close enough for your needs.
Yet another option is for you to simply record the current default MAIN/HOME activity when you are run for the first time. Odds are decent that your application will be run before the user elects to make you the default. Again, this has holes (e.g., they make you the default before running you for the first time).

EDIT: SOLUTION:
PackageManager pm=getPackageManager();
Intent main=new Intent(Intent.ACTION_MAIN, null);
main.addCategory(Intent.CATEGORY_HOME);
List<ResolveInfo> launchables=pm.queryIntentActivities(main, 0);
Collections.sort(launchables,
new ResolveInfo.DisplayNameComparator(pm));
int launcher_flag = findLauncherApp(launchables);
ResolveInfo launchable = launchables.get(launcher_flag);
ActivityInfo activity=launchable.activityInfo;
ComponentName name=new ComponentName(activity.applicationInfo.packageName,
activity.name);
Intent i=new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
startActivity(i);
Where findLaucherApp() turns the List into an array of strings and interrogates each one to see if it contains "com.android.launcher2" and then returns its id.

Related

Android - can't go back to mainActivity after starting a different app

Okay, I think I'm missing something here but can't seem to find a way around it :\
So this is my scenario, I have two apps, A and B. A Opens a B with the following intent:
PackageManager pm = getPackageManager();
Intent n = pm.getLaunchIntentForPackage(currAppInfo.getName());
n.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(n);
(currAppInfo is a custom object and getName returns the package name.)
Anyway, B is installing APKs. A receives the package installed broadcast and should be now moved back to front, how ever if I'm starting app A with an intent
Intent serviceIntent = new Intent();
serviceIntent.setClass(context, MainActivity.class);
serviceIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(serviceIntent);
Instead of seeing A's mainActivity screen all I see is B's main activity screen.
Why is that? Is it the way I open the apps with the intents or am I missing something more basic here?

Intent chooser in Notification

I have a problem (2 problems to be exact) with launching intents from a Notification.
My current situation is that I have a family of apk that all can use a remote service launched by the first of them. The service creates an Notification and when clicked the opens back the application that launched the service. This works ok.
I wanted to improve that so when there is more than one application from the family installed, instead of just going to the apk that launched the service an chooser Intent would appear and the user would be able to choose the apk to come back to.
I managed to do this.
ArrayList<String> myApps = Lists.newArrayList(
"com.myapp1",
"com.myapp2",
"com.myapp3",
"com.myapp4"
);
List<Intent> targetedIntents = new ArrayList<Intent>();
Intent baseIntent = new Intent(Intent.ACTION_MAIN, null);
baseIntent.addCategory("android.intent.category.LAUNCHER");
final PackageManager packageManager = getApplicationContext().getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(baseIntent, 0);
for (ResolveInfo resolveInfo : list) {
String packageName = resolveInfo.activityInfo.packageName;
if (packageName != null && myApps.contains(packageName)) {
Intent targetedIntent = new Intent();
targetedIntent.setPackage(packageName);
targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name);
targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
targetedIntents.add(targetedIntent);
}
}
Intent intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to");
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, intent, intent.getFlags());
notification.setLatestEventInfo(this, notificationTitle, notificationMessage, contentIntent);
This works mostly as it should. The chooser appears and the selected option launches the desired apk.
But I came across 2 problems:
I. When I create the intent chooser with only the intents that interest me, the chooser is empty with the message "no application can perform this action"
intent = Intent.createChooser(targetedIntents.get(0), "Select app to return to");
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
But if I put an existing apk there first (such as google play) everything works and my options show along with the google play option.
intent = Intent.createChooser(new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=whatever")), "Select app to return to");
intent.putExtra(Intent.EXTRA_INITIAL_INTENTS, targetedIntents.toArray(new Parcelable[]{}));
This is something I can live with, but it would be better if onlye the proper apks were there.
II. When I click the apk from the list, instead of coming back from the background (if the apk was already running there) it restarts it. I have the proper flags set.
Intent targetedIntent = new Intent();
targetedIntent.setPackage(packageName);
targetedIntent.setClassName(packageName, resolveInfo.activityInfo.name);
targetedIntent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Before using the chooser I launched only one intent and it resummed the background apk normally.
intent = new Intent(this, MainActivity.class);
intent.setAction("android.intent.action.MAIN");
intent.addCategory("android.intent.category.LAUNCHER");
Not sure what I am doing wrong here that the apk restarts insted of resuming.
For the first problem (chooser issue), the reason you are getting the error "no application can perform this action" is because the Intent you are passing to getChooser() doesn't have an ACTION in it that Android can use to search for applications that can handle the Intent. getChooser will use the ACTION, CATEGORY and DATA in the Intent to search for suitable applications. It will then use package and component names to filter this list. In your case, because you've only provided the package and component names (but haven't specified ACTION), Android can't find any suitable applications. I'm not sure there's a way around this, since you want to build a list with different packages. You may just need to create your own chooser dialog (which is probably the correct thing to do here anyway, as you don't really get any advantages using the Android chooser because you've already decided what the list should contain).
For the second problem (if application is in background, it gets restarted) you need to use the following flags:
targetedIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
Specifying Intent.FLAG_ACTIVITY_NEW_TASK when launching the root activity of a task will bring an already existing task to the foreground.
NOTE: If you want to just bring the existing task to the foreground (in whatever state it happens to be), then just use Intent.FLAG_ACTIVITY_NEW_TASK and remove the other 2 flags.

Find class to use with ComponentName class in Android

I have a single widget that call another application, here is the most important part of the code:
final Intent intent = new Intent(Intent.ACTION_MAIN, null);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
final ComponentName cn = new ComponentName("com.android.settings",
"com.android.settings.wifi.WifiSettings");
intent.setComponent(cn);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
ctxt.startActivity( intent);
The important part is
final ComponentName cn = new ComponentName("com.android.settings", "com.android.settings.wifi.WifiSettings");
This call the wifi settings in android, but I found this code in a web site, I want to know how I can call the data roaming and other settings in the system, where I can see this?
com.android.settings is the name of the package. If you go here you can find all the settings available in this package. The roaming settings are in package com.android.phone - see here.
EDIT : it appears that using package names is not portable. Your best bet is to use :
startActivity(new Intent(Settings.ACTION_DATA_ROAMING_SETTINGS));
The list of intents is in the Settings class
You may also need to add FLAG_ACTIVITY_NEW_TASK to your intent

Open third party app from intent

I am working on an app were I am going to open other apps. The only problem is that I do not know how to refer to third party apps. I am planing to use an intent. Can you refer to it useing only the packagename, or do you need the Main Activity intent. Are there any simple ways of finding the right intent, and then refer to it.
I am working on an app were I am going to open other apps.
I am interpreting this as meaning that you are creating a launcher, akin to the ones found on home screens.
Can you refer to it useing only the packagename, or do you need the Main Activity intent.
Launchers use an ACTION_MAIN/CATEGORY_LAUNCHER Intent.
Are there any simple ways of finding the right intent, and then refer to it.
Use PackageManager to find all the possible ACTION_MAIN/CATEGORY_LAUNCHER activities on the device, and then display those to the user to choose from. You can then construct a suitable Intent for starting up their specific choice.
Here is a sample project that implements a launcher.
To come up with the list of things that could be launched, that sample app uses:
PackageManager pm=getPackageManager();
Intent main=new Intent(Intent.ACTION_MAIN, null);
main.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> launchables=pm.queryIntentActivities(main, 0);
And here is the actual launching logic, based upon the user clicking on one of those "launchables" in a ListActivity:
#Override
protected void onListItemClick(ListView l, View v,
int position, long id) {
ResolveInfo launchable=adapter.getItem(position);
ActivityInfo activity=launchable.activityInfo;
ComponentName name=new ComponentName(activity.applicationInfo.packageName,
activity.name);
Intent i=new Intent(Intent.ACTION_MAIN);
i.addCategory(Intent.CATEGORY_LAUNCHER);
i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
i.setComponent(name);
startActivity(i);
}

open android own launcher from my application

hi Its been 2 days looking for this simple problem. I want to launch Android own launcher from my application EVEN if its not set as default.
final PackageManager packageManager=getPackageManager();
Intent intent = packageManager.getLaunchIntentForPackage("com.android.launcher");
this return null for Android own launcher but if I try custom launcher is give me successfully
Found the solution, after investigating source code of getLaunchIntentForPackage. As per documentation,
The current implementation will look first for a main activity in the
category CATEGORY_INFO, next for a main activity in the category
CATEGORY_LAUNCHER, or return null if neither are found.
So, the function don't look for CATEGORY_HOME, i rewrote it in following way, it worked perfectly.
Intent intentToResolve = new Intent(Intent.ACTION_MAIN);
intentToResolve.addCategory(Intent.CATEGORY_HOME);
intentToResolve.setPackage("com.android.launcher");
ResolveInfo ri = getPackageManager().resolveActivity(intentToResolve, 0);
if (ri != null)
{
Intent intent = new Intent(intentToResolve);
intent.setClassName(ri.activityInfo.applicationInfo.packageName, ri.activityInfo.name);
intent.setAction(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
startActivity(intent);
}
Are you sure the default Google Android Launcher being installed on your device? If not, then it's truly NULL.

Categories

Resources