I have seen ways to make shortcuts, but I need to find a way to get a list of shortcuts installed on the phone.
I want my user to be able to select one of his/her shortcuts and launch it from my application. Is there a way to do this (an API) or will I need a reflection method to call a system service?
Here is how it is done in the Launcher...
Intent shortcutsIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
List<ResolveInfo> shortcuts = getPackageManager().queryIntentActivities(shortcutsIntent, 0);
The shortcuts are private to Launcher. There is no API, and anything you try to do will be very fragile as different launcher implementations (and versions) will have different storage structures.
In addition to Jonathan,
Each app can do shortcuts. Each shortcut specified in app's manifest. So you can get shortcuts list (this method in activity):
Kotlin
fun printShortcuts() {
val shortcutIntent = Intent(Intent.ACTION_CREATE_SHORTCUT)
val shortcuts = packageManager.queryIntentActivities(shortcutIntent, 0)
shortcuts.forEach {
println("name = ${it.activityInfo.name}, label = ${it.loadLabel(packageManager)}")
}
}
It will print something like:
I/System.out: name = com.whatsapp.camera.CameraActivity, label = WhatsApp Camera
I/System.out: name = com.android.contacts.ContactShortcut, label = Contact
I/System.out: name = alias.DialShortcut, label = Direct dial
I/System.out: name = alias.MessageShortcut, label = Direct message
I'm trying to do the same and there a lot of things not clear about this topic, at least not clear to me...........An example is Openapp market that create shortcuts everytime you "download" an app, but the shortcuts it is actually only a link to an html page. Anyway i have 2 android phones and in the firstone is working in the second one is not creating any shortcuts.......
in may app i do the following:
Intent shortcutIntent = new Intent(this,FinestraPrincipaleActivity.class);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
shortcutIntent.putExtra("someParameter", "HelloWorld");
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Shortcut Name");
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(this, R.drawable.icon));
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
this.sendBroadcast(addIntent);
But someone told me that the is wrong but i didn't find anyother way to create shortcuts....
Related
I have a watch face that I've created and I was looking into adding an "About" screen in the watch settings (on the watch). This screen would show the current version and show a button to open a URL leading to a changelog. I want the user to be able to click the button on their watch, and have it open the specified URL on the phone.
Is this possible without me creating a mobile companion application?
You can do this if the watch is running Android Wear 2 using a RemoteIntent, as such:
Intent intent = new Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(Uri.parse("http://www.google.com"));
RemoteIntent.startRemoteActivity(context, intent, null);
...replacing http://www.google.com with your desired URL, of course.
AFAIK, there's no way to accomplish this on Wear 1.x without sending a message to your handheld app and programming it to open the URL itself.
Note the new way to do this is with RemoteActivityHelper:
val remoteActivityHelper = RemoteActivityHelper(context, Executors.newSingleThreadExecutor())
val result = remoteActivityHelper.startRemoteActivity(
Intent(Intent.ACTION_VIEW)
.addCategory(Intent.CATEGORY_BROWSABLE)
.setData(
Uri.parse("http://www.google.com/")
),
null
)
and if you want to show the nice "Open on phone" animation, use ConfirmationActivity:
startActivity(
Intent(this, ConfirmationActivity::class.java)
.putExtra(ConfirmationActivity.EXTRA_ANIMATION_TYPE, ConfirmationActivity.OPEN_ON_PHONE_ANIMATION))
My app forwards users to a different app to perform a specific action (e.g. ACTION_SHARE, except that the apps that I forward users to do not implement an intent filter) Since they don't implement intent filters, I have a list of package names that support the action.
This part is working fine, like this:
for (String knownApp : knownApps) {
Intent intent = pm.getLaunchIntentForPackage(knownApp);
if (intent != null) {
ResolveInfo resolveInfo = pm.resolveActivity(intent, 0);
intentList.add(new LabeledIntent(intent, knownApp, resolveInfo.loadLabel(pm), resolveInfo.icon));
}
}
LabeledIntent[] extraIntents = intentList.toArray(new LabeledIntent[intentList.size()]);
Intent openInChooser = Intent.createChooser(actionIntent, getString(R.string.perform_action_with));
openInChooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, extraIntents);
startActivity(openInChooser);
If the user has none of the apps installed, I want to give the user a choice of apps to download to fulfill the action.
Currently that looks like this.
As you can see it's lacking both icon and name. For regular apps I use an intent chooser which needs LabledIntent, but on one hand, I can't get the name and icon from the playstore unless I scrape them (which is not allowed by google, besides LabledIntent requires a resourceId as the Icon, which I can't get for downloaded files.), on the other the intent chooser won't seem to display the intent unless the package name of the intent and LabeledIntent match. This does not work for URIs which I'm using to access the Play Store in the first place.
Now I'm looking for ideas on how to get the following code to display both the correct name and app icon, as well as forward to the correct page on the play store.
protected void showPlayStoreOptions(List<String> knownApps) {
Intent chooserIntent = new Intent();
Intent showIntent = Intent.createChooser(chooserIntent, "You need one of these Apps on Google Play..."); //googles brand guidelines state that "on Google Play" has to be used
List<Intent> list = new ArrayList<>();
for (String knownApp : knownApps) {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=" + knownApp)); //normally you would try an uri with market:// first, catch the exception if no playstore is installed and then use this, but the intent chooser seems to automatically forward correctly.
list.add(intent);
//list.add(new LabeledIntent(intent, "https://play.google.com/store/apps/details?id=" + knownApp, "test name", R.drawable.icon_info));
//list.add(new LabeledIntent(intent, ""+Uri.parse("https://play.google.com/store/apps/details?id=" + knownApp), "test name", R.drawable.icon_info));
}
showIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, list.toArray(new Intent[list.size()]));
startActivity(showIntent);
}
So to sum up my questions.
How can I get a resource Id from a downloaded image file, or how can I use the downloaded image file with a LabledIntent.
(Extending LabledIntent does not work due to issues with parceling (and those methods are package private))
How can I display a LabledIntent in a choose intent with an URI?
I realize it's probably easier to write my own chooser, but I want to wrangle this into the default android system.
is it possible to ask website visitors to save your website on their home-screen?
android
Check out this answer here, on how to create a shortcut:
How to add android bookmark on homescreen from web page?
If you're writing an Android app, you can use this approach. However, if this is a website, this approach will not work, as it looks like the Android Intent system ignores website generated actions.
you can create a web page shortcut on home screen using this code. Provide the necessary info like url, title etc..
final Intent in = new Intent();
final Intent shortcutIntent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
long urlHash = url.hashCode();
long uniqueId = (urlHash << 32) | shortcutIntent.hashCode();
shortcutIntent.putExtra(Browser.EXTRA_APPLICATION_ID, Long.toString(uniqueId));
in.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
in.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);
in.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,
Intent.ShortcutIconResource.fromContext(
BrowserBookmarksPage.this,
R.drawable.ic_launcher_shortcut_browser_bookmark));
in.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
//or in.setAction(Intent.ACTION_CREATE_SHORTCUT);
sendBroadcast(in);
Now i am working on a Home Launcher application.I want to clear defaults of default home launcher(eg: Samsung Home). ie.I want to show Settings-> Applications->Manage Application->Samsung Home->clear defaults programmatically.
How to show this through code?
Thanks in Advance
NOTE: Since this question is limited to accessing the Manage Application Settings options, my answer covers just that. You will have to figure out a way of getting the actual Package Name.
Also, if the idea is to also Clear the Defaults automatically via code, then that, to the best of my knowledge, cannot be done. Someone can correct me if I am wrong on this.
That being said, this piece of code will open the specific application's Manage Application screen from your app (the package name must be supplied).
Intent showSettings = new Intent();
showSettings.setAction(android.provider.Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uriAppSettings = Uri.fromParts("package", "THE_APP_PACKAGE_NAME", null);
showSettings.setData(uriAppSettings);
startActivity(showSettings);
For example, if the package name of the Google Maps application is com.google.android.apps.maps, the replace THE_APP_PACKAGE_NAME with it and the code will open the Manage Application screen for the Google Maps application.
UPDATE:
The PackageManager has a method, clearPackagePreferredActivities used to clear the default via code. However, that doesn't seem to work in newer Android versions: https://stackoverflow.com/a/10246711/450534
Other posts worth reading:
https://stackoverflow.com/a/7750187/450534
https://groups.google.com/forum/?fromgroups=#!topic/android-developers/Rzv8VU-EUAw
Just for complete the picture, for getting "THE_APP_PACKAGE_NAME" youc can use something like that :
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
ResolveInfo resolveInfo = getPackageManager().resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
String packageName = resolveInfo.activityInfo.packageName;
I would like to start a default application: browser, contact-book, phone, email, music app, etc. I have found many q/a, like browser opening a specific URL or blank, and here the answer is even "No not possible". But I would like to just open/launch it without telling it to go to a specific URL or sending a mail to someone, etc.
However, I also saw some Home applications where this seems to be working (at least for some apps). On my colleague's device there is for example a different contact-book (no google) which is detected and opened correctly.
I have seen in the Android documentation some intent categories that point to these problems, but these are only >= API.11. So I can't use/test them on my device.
Question: Is it not somehow possible to launch a default application (having the app chooser is of course ok) without providing extra data? If no, what do you think are these Home apps doing (perhaps workarounds are somehow possible).
PS: for the phone app I think, I have a workaround using Intent.ACTION_DIAL without any other information which will open simply the dialer.
UPDATE: I modified the title. Some applications like the address book may not be the same on different devices. So in this case I would like to start the address-book app, whichever this is.
This answer is not a 100% answer, but some workarounds on some typical applications.
Still open are: music player, address book
Browser: I get a list of applications that handle "http"-data intents, and then I look if one is available in the list of preferred applications.
Intent appFilter = new Intent(Intent.ACTION_VIEW);
appFilter.setData(Uri.parse("http://www.google.com"));
List<ResolveInfo> browserInfoList = pm.queryIntentActivities(appFilter, 0);
List<IntentFilter> outFilters = new ArrayList<IntentFilter>();
List<ComponentName> outActivities = new ArrayList<ComponentName>();
pm.getPreferredActivities(outFilters, outActivities, null);
if(outActivities.size() > 0) {
for(ComponentName cn : outActivities) {
String cnClass = cn.getClassName();
String cnPkg = cn.getPackageName();
for (ResolveInfo info : browserInfoList) {
if(info.activityInfo.name.equals(cnClass) &&
info.activityInfo.packageName.equals(cnPkg)) {
return cn;
}
}
}
}
In case no default is found, I open a browser chooser dialog, see here.
Phone: as described in the question:
Intent intent = new Intent(Intent.ACTION_DIAL);
startActivity(intent);
You can start apps by the function "startActivity" if you know about the canonical app name
like "android.com.browser". Do this simple by searching for AndroidManifest.xml in the app
source code (look at Codeaurora.com or at github/Cyanogenmod) and grab the app name you want.
After you know about the App name ("Activity") implement the code as follows:
Intent intent = new Intent();
intent.setClassName(this, "com.android.browser");
intent.setCategory(Intent.ACTION_MAIN);
startActivity(intent);
THIS is only a example, sometimes you have to put intent extras or data values, this information can be found in the app's AndroidManifest.xml too.