Trying to UNINSTALL_SHORTCUT but shortcut won't go away - android

I created a test Activity that installs a shortcut of itself on the Android Home screen. When you click a button, the Activity is supposed to remove the same shortcut it just created. However, nothing I do seems to delete the shortcut.
Here is the Java code (ShortcutTest.java):
import java.net.URISyntaxException;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
public class ShortcutTest extends Activity {
String shortcutUri;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
addShortcut(getBaseContext());
Button button = (Button)findViewById(R.id.Button01);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
removeShortcut(getBaseContext());
finish();
}
});
}
public void addShortcut(Context context) {
Intent shortcutIntent = new Intent();
shortcutIntent.setClassName("com.telespree.android.client", "com.telespree.android.client.ShortcutTest");
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "ShortcutTest");
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(context, R.drawable.icon));
intent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
shortcutUri = intent.toUri(MODE_WORLD_WRITEABLE);
context.sendBroadcast(intent);
}
public void removeShortcut(Context context) {
Intent intent = null;
try {
intent = Intent.parseUri(shortcutUri, 0);
} catch (URISyntaxException e) {
}
intent.setAction("com.android.launcher.permission.UNINSTALL_SHORTCUT");
context.sendBroadcast(intent);
}
}
Here is the Manifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.telespree.android.client"
android:versionCode="1"
android:versionName="1.0">
<permission
android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"
android:permissionGroup="android.permission-group.SYSTEM_TOOLS"
android:protectionLevel="normal"
/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".ShortcutTest"
android:label="#string/app_name" android:theme="#android:style/Theme.Translucent">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<!--
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
-->
<uses-sdk android:minSdkVersion="7" />
</manifest>
I'm almost positive there is some kind of permissions problem, though I've seen other posts on the Internet that indicates this should be possible.
Any advice is greatly appreciated.
Thanks.

DEPRECATED; KEPT SOLELY FOR HISTORICAL PURPOSES
This answer was posted in 2014, when the described method relied on functionality that existed in most Android devices. However, as mentioned by Adrian-Costin Țundrea, this functionality was removed a couple of years ago from Launcher3, which is the AOSP launcher upon which the Google Now Launcher is based1. The commit message said:
Removing support due to its flacky design. Removing a shortcut
causes a full reload. Also we do not have any concept of owner, so
any app can remove any shortcut.
As of March 2017, this launcher, too, is being phased out in favor of "Google Search Launcher Services", which means that manufacturers could integrate a certain Google library into their own custom launchers, instead of relying on a standardized launcher provided by Google.
Considering that each manufacturer is free to implement their launcher whichever way they want, and assuming some of them are based off Launcher3, it's difficult to tell which devices the method below will work on, as Launcher3 was made to run even on some Android 4.1 devices, which are among the oldest devices still in use.
Greetings!
I have just dealt with the same exact problem, and would like to share my experience after successfully resolving it. tl;dr - skip to "In Conclusion" below.
Some background:
While working on the "next version" of an app, a need arose to change the default entry point (i.e. to rename the "Main Activity"). This is frowned upon because users who would be upgrading from an old version will still have the old shortcut, pointing to the wrong place. In order to avoid problems as much as possible, on the first launch, unbeknownst to them, the old shortcut was to be replaced with a new one.
Step 1: Setting up a new entry point
This is the easiest part. To declare an entry point the only essential thing to do is to put the following <action ...> tag in the appropriate activity declaration inside your Manifest:
<activity
android:name="YOUR_PACKAGE_NAME.YOUR_ACTIVITY_NAME"
android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>
</activity>
What makes an entry point default in some sense, is that the launcher shortcut points to it. This is why developers usually also include this in the <intent-filter>:
<category android:name="android.intent.category.LAUNCHER"/>
It should be noted that every activity that has this in its <intent-filter> will create an item in your app drawer - this is why for most cases 1 instance is all you need.
Step 2: Figuring out how the old shortcut is working
Having a rooted device, I could access the database table where the launcher/homescreen/desktop items are stored (see image of what the SQLite entries looks like) that's located in:
/data/data/com.android.launcher/databases/launcher.db -> SELECT * FROM favorites`
Here's a more readable version of the highlighted entry from the image:
#Intent;
action=android.intent.action.MAIN;
category=android.intent.category.LAUNCHER;
launchFlags=0x10200000;
package=gidutz.soft.bluecard;
component=gidutz.soft.bluecard/.LoadingScreen;
end
Note the 0x10200000 - this is explained in Step 4 - Attempt 1 below.
Step 3: Figuring out what the Shortcut Uninstaller is expecting
Lines 38-42 in UninstallShortcutReceiver.java tell us that:
Intent intent = data.getParcelableExtra(Intent.EXTRA_SHORTCUT_INTENT);
String name = data.getStringExtra(Intent.EXTRA_SHORTCUT_NAME);
boolean duplicate = data.getBooleanExtra(Launcher.EXTRA_SHORTCUT_DUPLICATE, true);
if (intent != null && name != null) { ... }
Meaning that the "uninstallation intent" has to have both Intent.EXTRA_SHORTCUT_INTENT and Intent.EXTRA_SHORTCUT_NAME or else it will not even consider executing.
Step 4: Finding the Right Syntax
This is a case of trial an error with a happy ending.
Attempt 1: Reconstructing the intent
Intent oldShortcutIntent = new Intent();
oldShortcutIntent.setAction(Intent.ACTION_MAIN);
oldShortcutIntent.addCategory(Intent.CATEGORY_LAUNCHER);
oldShortcutIntent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED +
Intent.FLAG_ACTIVITY_NEW_TASK);
oldShortcutIntent.setPackage("gidutz.soft.bluecard");
oldShortcutIntent.setComponent(new ComponentName("gidutz.soft.bluecard",
".LoadingScreen"));
// The above line is equivalent to:
Intent oldShortcutIntent = new Intent(getApplicationContext(),LoadingScreen.class);
Intent uninstaller = new Intent();
uninstaller.putExtra(Intent.EXTRA_SHORTCUT_INTENT, oldShortcutIntent);
uninstaller.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Blue Card");
uninstaller.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(uninstaller);
Result: Icon not removed.
The 0x10200000 is actually a sum of two arguments as explained here.
Attempt 2: Using as-is code from viralpatel
Intent shortcutIntent = new Intent(getApplicationContext(),LoadingScreen.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Blue Card");
addIntent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(addIntent);
Result: Icon not removed.
Attempt 3: "Brute Force"
Trying to copy-paste the intent exactly as it appears in the launcher.db:
Intent intent = new Intent();
String oldShortcutUri = "#Intent;action=android.intent.action.MAIN;category=android.intent.category.LAUNCHER;launchFlags=0x10200000;package=gidutz.soft.bluecard;component=gidutz.soft.bluecard/.LoadingScreen;end";
try {
Intent altShortcutIntent = Intent.parseUri(oldShortcutUri,0);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, altShortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "Blue Card");
} catch (URISyntaxException e) {
}
intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(intent);
Result: Icon removed!!
In Conclusion
Make sure that your "Icon Uninstaller" intent uses the exact same URI used to create the icon you're trying to delete, by either storing the URI used to create it, or by obtaining it from launcher.db.
Wait about 2-3 seconds for the "icon removed" toast to appear.
Sources
1) This guide at viralpatel.net
2) Google's implementation of UninstallShortcutReceiver.java
3) This thread at xdadevelopers
P.S.
In order to simulate and debug a Google Play update (which keeps the old shortcut) I did the following:
Installed the old version of the app from the store - an icon with the "old shortcut" was automatically placed on my screen.
Backed-up my launcher.db using Total Commander.
Installed the new version through my IDE (you can also use an .apk for that) - the "old shortcut" was now gone.
Opened Total Commander and minimized it (so that a shortcut is available in the "ALT-TAB" menu).
Went to the Device Settings >> Apps >> ALL, found my launcher (for me it was "Trebuchet" since I'm on CM11) and Force stopped it.
ALT-TAB into Total Commander and restored the DB.
Clicked the hardware "home" button to re-launch the launcher.
Viola! The old shortcut was now restored.
Note1: In retrospective, it might have been easier to create the old shortcut manually using the URI obtained from the database instead of going through all backing-up and force-stopping ordeal.
Note2: I haven't tried removing icons belonging to other apps using this method, but it might just be crazy enough to work.

While both solutions from Dev-iL and Funt work be advised they do so until Marshmallow. With Android 6.0 (which has Launcher v3) Google has removed the UninstallShortcutReceiver because of its security problems (probably because it became apparent here). So do not expect it to work with Android 6.0. Hopefully in some future release it will be readded in a form or another.
PS: Normally this should be a comment, but I am not allowed to comment because of the reputation...

You need to setAction for shortcutIntent like:
shortcutIntent.setAction(Intent.ACTION_MAIN);

Try to use
public void removeShortcut(Context context) {
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "ShortcutTest");
try {
Intent shortcutIntent = Intent.parseUri(shortcutUri, 0);
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
} catch (URISyntaxException e) {
}
intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
context.sendBroadcast(intent);
}
Note: You do not have to save shortcutUri to remove the shortcut. Instead you can use
Intent shortcutIntent = new Intent();
shortcutIntent.setClassName("com.telespree.android.client",
"com.telespree.android.client.ShortcutTest");
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
shortcutIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
Intent intent = new Intent();
try {
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
Intent.parseUri(shortcutIntent.toUri(0), 0));
} catch (URISyntaxException e) {
e.printStackTrace();
}
...
intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");
context.sendBroadcast(intent);
If you want to use intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent); instead of
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,
Intent.parseUri(shortcutIntent.toUri(0), 0));
then you need to set action for shortcutIntent each time , i.e. while installing as well as while uninstalling e.g. Intent shortcutIntent = new Intent(Intent.ACTION_MAIN);

It took me about an hour of debugging and trying out every example on stackoverflow, but the solution was very easy. There's a typo in your code: You need to use com.android.launcher.action.UNINSTALL_SHORTCUT (as opposed to permission, as it is in the Manifest)
intent.setAction("com.android.launcher.action.UNINSTALL_SHORTCUT");

Related

No application can perform this action - Shared code with different flavors

I am trying to create a new application ("My New App") from the source of another application that I have ("My Previous App").
In order to do it, I've created a new flavor, changed the app name and new icons for the new flavor, and everything goes ok.
But I've encountered that I can't launch (at least) one activity.
The activity is declared in a library included as a module and is defined in this way in the library manifest.xml:
<activity android:name="com.my.company.core.views.download.VersionActivity"
android:label="#string/app_name"
android:exported="false"
android:screenOrientation="portrait" />
And I am trying to launch that activity in the following way:
Intent intent = new Intent(CurrentActivity.this, VersionActivity.class);
startActivity(intent);
If I have only one app, for example "My New App" installed in the terminal it works perfect. But if I have installed both apps "My New App" and "My Previous App" when I try to launch the activity as described Android says "No application can perform this action".
Can't I share code between apps? Is there a problem with the declaration of the activity in thee manifest? By the way, I've tried with exported="true" but it didn't work anyway.
Thanks in advance.
You can specify that your current app should handle the intent using setPackage.
Intent intent = new Intent();
intent.setAction("com.my.company.core.views.download.VersionActivity");
intent.setPackage(context.getPackageName());
startActivity(intent);

creating android app shortcut on the home screen

I need to add a shortcut for my app on the home screen (programmatically).
I know that the app store do this by default, but for start, the app won't be on the google app store.
I searched a lot, and found basically the same lines of code over and over, and it doesn't seem to work for me.
the code I used:
in the manifest:
<activity android:name=".MainScreenActivity" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
in the onCreate method I called the function that does the following:
private boolean createShortcut()
{
//create shortcut intent
Intent shortcutIntent = new Intent(getApplicationContext(),MainScreenActivity.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
//create intent to add and define the shortcut
Intent addingIntent = new Intent();
addingIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT,shortcutIntent);
addingIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME,"SenseGuard");
addingIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE,Intent.ShortcutIconResource.fromContext(getApplicationContext(),R.drawable.peak_detection_icon));
addingIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
getApplicationContext().sendBroadcast(addingIntent);
}
I tried switching "getApplicationContext()" to "this".
I tried with an actual tablet and on an emulator but I can't get it to work.
Do like This:
Step 1:
Update your manifest.xml :
<uses-permission
android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
Step 2:
in your MainActivity.java create addShortcut() method and in it`s block put this code :
private void addShourcut(){
Intent shortCutIntent = new Intent(getApplicationContext() ,MainActivity.class);
shortCutIntent.setAction(Intent.ACTION_MAIN);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT , shortCutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME , "Convertor");
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE ,
Intent.ShortcutIconResource.fromContext(getApplicationContext() , R.mipmap.ic_launcher));
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
addIntent.putExtra("duplicate" , false);
getApplicationContext().sendBroadcast(addIntent);
}
Step3:
set onClickListener for your view that be create shortcut :
img_pin = (ImageView) findViewById(R.id.img_pin);
img_pin.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
addShourcut();
Toast.makeText(MainActivity.this, "shortcut created !", Toast.LENGTH_SHORT).show();
}
});
This is worked for me ...
happy codinngggg...:)
That code isn't guaranteed to work. That broadcast is also sent by ShortcutManagerCompat (which you should probably be using instead of manually sending the broadcast).
However, there are two problems with this.
Your default launcher isn't guaranteed to listen for this broadcast. Nova Launcher, for example, has this behavior disabled by default. Other launchers might not even listen for that action at all.
On Android Oreo (26) and above, this won't work how you expect it to (read the comments on the method I linked for more details).
You can use this logic still and hope that it works for some of your users, but keep in mind that many default launchers no longer even have app drawers, so adding a shortcut could give your users duplicate icons. Also, I know that, at least for me, I have my home screen organized how I want, and if I install an app, it would be really annoying for it to add itself to my home screen.
If you are using the default AOSP launcher (or a close fork), however, and it isn't working, make sure you add this to your manifest:
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />

Ask for password before uninstalling application

First of all, I have researched a lot about my issue, but I could not find a proper solution so I am posting my query here. Hope to get a better solution to the issue:
I have a requirement where I need to ask for password to the user before user deletes my app from settings or from any other application like MyAppSharer. I have found one solution where I can successfully be able to call my activity when user clicks on Uninstall button. I have applied trick here, and calling service. In service, I run timer which runs every 1 second and in that one second, it checks for top most activity of running task. This is running perfectly as per expected.
Now, my issue is, this activity apppears on each of application user tries to uninstall. I need that the activity which I call, should only appear for my application when user tries to uninstall my application.
Here is my code:
public static final String PACKAGE_INSTALLER = "com.android.packageinstaller";
public static final String PACKAGE_INSTALLER_UNINSTALL_ACTIVITY = "com.android.packageinstaller.UninstallerActivity";
alarmTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
mActivityManager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);;
ComponentName topActivity = mActivityManager.getRunningTasks(1).get(0).topActivity;
final String packageName = topActivity.getPackageName();
String className = topActivity.getClassName();
Log.v(TAG, "packageName:" + packageName);
Log.v(TAG, "className:" + className);
if (PACKAGE_INSTALLER.equals(packageName)
&& PACKAGE_INSTALLER_UNINSTALL_ACTIVITY.equals(className)) {
//Here I need to apply one condition where package name received to be matched with my package name. But I am not sure how to fetch package name of selected application for uninstalling
//To Cancel Existing UninstallerActivity and redirect user to home.
Intent homeIntent = new Intent();
homeIntent.setAction(Intent.ACTION_MAIN);
homeIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
homeIntent.addCategory(Intent.CATEGORY_HOME);
startActivity(homeIntent);
//To open my activity
Intent loginActivity = new Intent(UninstallService.this, Act_Login.class);
loginActivity.putExtra(Constants.KEY_IS_FROM_SERVICE, true);
loginActivity.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(loginActivity);
}
}
}, 0, 1000);
you should try something like the following :
1st - declare your broadcast recevier in the Manifest file , that will listen to QUERY_PACKAGE_RESTART :
<receiver android:name=".UninstallReceiver">
<intent-filter android:priority="999999">
<action android:name="android.intent.action.QUERY_PACKAGE_RESTART" />
<data android:scheme="package" />
</intent-filter>
</receiver>
2nd - your UnunstallIntentReceiver java class like the following :
public class UninstallReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
// fetching package names from extras
String[] packageNames = intent.getStringArrayExtra("android.intent.extra.PACKAGES");
if(packageNames!=null){
for(String packageName: packageNames){
if(packageName!=null && packageName.equals("application_package")){
// start your activity here and ask the user for the password
}
}
}
}
}
and please give me some feedback
Hope That Helps.
If this is a corporate requirement (if you want to block a regular user from uninstalling your app, no chance, thanks Google for protecting us from bad devs), you should create a device administrator application. This way, although the user still can delete the app, it's one extra step if you want to prevent accidental erasing.
Before deleting your app, if it's enabled as device admin, the user must first disable the app as administrator, and the app receives this broadcast.
In your XML, put
<activity android:name=".app.DeviceAdminSample"
android:label="#string/activity_sample_device_admin">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.SAMPLE_CODE" />
</intent-filter>
</activity>
<receiver android:name=".app.DeviceAdminSample$DeviceAdminSampleReceiver"
android:label="#string/sample_device_admin"
android:description="#string/sample_device_admin_description"
android:permission="android.permission.BIND_DEVICE_ADMIN">
<meta-data android:name="android.app.device_admin"
android:resource="#xml/device_admin_sample" />
<intent-filter>
<action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
</intent-filter>
</receiver>
In the receiver, you have at least two methods worth noticing:
#Override
public CharSequence onDisableRequested(Context context, Intent intent) {
…
}
#Override
public void onDisabled(Context context, Intent intent) {
…
}
This way you know the user is potentially going to erase your app.
Complete guide for device administration is at https://developer.android.com/guide/topics/admin/device-admin.html
If you have root permissions make your app system (remove your apk-file from /data to /system directories). Then reboot device. After reboot your app is not available to delete by user (not superuser).
The only way i see, is to provide your own uninstaller as part of your app (= an activity that lists all apps and allows to uninstall them). Your service could then check if your app was the one that started the packageinstaller and if not redirect the user.
It is not possible (at least on the Android 4.4 I tested with) to grab the uninstaller activity data without root or being a system app. This is because the uninstaller is not called as an independent task, but as an activity on the stack of the starting task (which is the Settings app when uninstalling from settings, etc). You can only see the Task details of the calling task.
However there might be some really dirty possibility left, that i didn't test to the end: You could register the hidden interface IThumbnailReceiver [1] with the hidden three argument version of ActivityManager.getRunningTasks [2]. It seems like only the GET_TASKS permission is needed to grab a thumbnail (see [3]). It should be possible to find out which app is going to be removed from the app thumbnail... - But as this solution uses hidden APIs, there is no guarantee that it will work with older/newer/vendored Android versions.
https://github.com/omnirom/android_frameworks_base/blob/android-4.4/core/java/android/app/IThumbnailReceiver.aidl
https://github.com/omnirom/android_frameworks_base/blob/android-4.4/core/java/android/app/ActivityManager.java#L766
https://github.com/omnirom/android_frameworks_base/blob/android-4.4/services/java/com/android/server/am/ActivityManagerService.java#L6725

How can I add my application's shortcut to the homescreen upon app installation? [duplicate]

This question already has answers here:
How can I place app icon on launcher home screen?
(6 answers)
Closed 5 years ago.
I want to create my app's shortcut/launcher icon on the homescreen as soon as I install my app (even before I start it). Is that possible? How might I do that?
Since ICS, you can do like this:
public void createShortCut(){
Intent shortcutintent = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
shortcutintent.putExtra("duplicate", false);
shortcutintent.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.shortcutname));
Parcelable icon = Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.drawable.icon);
shortcutintent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
shortcutintent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(getApplicationContext(), EnterActivity.class));
sendBroadcast(shortcutintent);
}
Please also refer to the source code of launcher at: this link
Edit : If somebody would miss reading comment so adding following line.
This requires "com.android.launcher.permission.INSTALL_SHORTCUT" permission
You forgot to add permissions:
<uses-permission
android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<uses-permission
android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />
Great tutorial here:
http://androidforbegineers.blogspot.in/2014/01/android-home-screen-shortcut.html#!
NOTE: This answer is now wrong. See, for instance, Robin's answer for a way to do this.
As far as I know, an app cannot force itself onto the home screen. It gets added to the app list that the launcher app maintains, but the home screen is generally under user control. Giving apps the ability to clutter up the home screen would be an open invitation for abuse.
If you install your application, neither your application, nor any services or other processes are active! Android want's the user to make the first step in "opening" the application. You are not able to install a shortcut directly! Thats the answer. Notice: On most devices the launcher will create a shortcut for your application itself.
Can you install shortcuts in runtime after the user has somehow started your app at least once? : yes (see Robins answer).
Is there a workaround?
Maybe, but no good one.
Update, Another hint: If you have already an application on the device of the user. (For example if your second app that gets installed is the key for "going pro" or something), then you actually can start the second application from the first one, without the user has started the second app ever (and add a shortcut).
Create function to call intent of shortcut:
private void criarAtalho() {
Intent shortcutIntent = new Intent(getApplicationContext(), SplashScreen.class);
shortcutIntent.setAction(Intent.ACTION_MAIN);
Intent addIntent = new Intent();
addIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
addIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME, "nomeDaApp");
addIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.mipmap.ic_launcher));
addIntent.setAction("com.android.launcher.action.INSTALL_SHORTCUT");
addIntent.putExtra("duplicate", false); //may it's already there so don't duplicate
getApplicationContext().sendBroadcast(addIntent);
}
write on OnCreat the call of function:
if(!getSharedPreferences("APP_PREFERENCE", Activity.MODE_PRIVATE).getBoolean("IS_ICON_CREATED", false)){
criarAtalho();
getSharedPreferences("APP_PREFERENCE", Activity.MODE_PRIVATE).edit().putBoolean("IS_ICON_CREATED", true).commit();
}
set the permissions on manifest:
<uses-permission
android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
First, add permission for adding shortcut to manifest:
<uses-permission
android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
Then, call the function below.
public void createShortcut(){
Intent intentShortcut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");
intentShortcut.putExtra(Intent.EXTRA_SHORTCUT_NAME, getString(R.string.app_name));
Parcelable appicon = Intent.ShortcutIconResource.fromContext(getApplicationContext(), R.drawable.ic_launcher);
intentShortcut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, appicon);
intentShortcut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, new Intent(getApplicationContext(), MainActivity.class));
intentShortcut.putExtra("duplicate", false);
sendBroadcast(intentShortcut);
}

Android: Homescreen shortcut to certain action within an app

In an android app I am making, I want to allow users to place shortcuts on their homescreen that will make my app perform certain actions. So far, I made it successfully create the shortcut (they are created through the launcher, not through the app directly). However, when I click on them, it says
Application isn't installed on your phone
Which I assume means I have created the shortcut wrong. The code I am using to create the shortcut is:
Intent shortcutIntent = new Intent(ShortcutActivity.this, com.example.myapp.MyActivity.class);
ShortcutIconResource iconResource = Intent.ShortcutIconResource.fromContext(ShortcutActivity.this, R.drawable.clean);
Intent intent = new Intent();
intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, shortcutIntent);
intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, shortcutName);
intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, iconResource);
setResult(RESULT_OK, intent);
Solved it myself. Realized I had to add the following to the activity in the manifest:
<intent-filter>
<action android:name="android.intent.action.MAIN" />
</intent-filter>

Categories

Resources