1

We are experiencing a weird issue. Our app is already uploaded to Google Play. When I download our app from Google Play, I found out that 2 shortcuts are created for our app. One is created during download and install of our app at Google Play. When I click to run our app in the Google Play, our splash screen activity would be launched which would create another shortcut ( our code does check if the shortcut is already created or not).

Now both shortcuts are there and are acting differently. If I launched my app from first shortcut, and entered some information in the screen and then go back to home screen. and click the same shortcut again, those entered information is still there. However if I click on another shortcut after I go to home screen, the splash screen would show again, all the entered data is gone. If I see the running app (press Home and hold), I could see only one running activity for our app.

Here is the code we create the shortcut:

    public static void createShortcut(Activity activity, int iconResId,
        int appNameResId) {
    Intent shortcutIntent = new Intent(
            "com.android.launcher.action.INSTALL_SHORTCUT");
    shortcutIntent.putExtra("duplicate", false);
    shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_NAME,
            activity.getString(appNameResId));
    Parcelable icon = Intent.ShortcutIconResource.fromContext(
            activity.getApplicationContext(), iconResId);
    shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);
    Intent extraIntent = new Intent(activity.getApplicationContext(),
            activity.getClass());
    extraIntent.setAction("android.intent.action.MAIN");
    extraIntent.addCategory("android.intent.category.LAUNCHER");
    shortcutIntent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, extraIntent);

    activity.sendBroadcast(shortcutIntent);

}

here is code which we are checking if duplicate shortcut is already created, basically we are checking if a shortcut with our app name is already created which I know that it is not bulletproof since other app would use same name as our app as well such as I saw couple "Flashlight" app. Another thing is that it is obvious our app doesn't detect the shortcut created from Google Play app:

    public static Boolean isShortcutInstalled(Activity activity,
        int appNameResId) {
    final ContentResolver cr = activity.getContentResolver();
    String authorityString = null;
    if (Build.VERSION.SDK_INT >= 8) {
        authorityString = "com.android.launcher2.settings";
    } else {
        authorityString = "com.android.launcher.settings";
    }
    Uri contentUri = Uri.parse("content://" + authorityString
            + "/favorites?notify=true");
    Cursor cursor = cr.query(contentUri, new String[] { "title",
            "iconResource" }, "title=?",
            new String[] { activity.getString(appNameResId) }, null);
    if (cursor != null && cursor.getCount() > 0) {
        return true;
    }
    return false; 
}

by the way, here is another question on SO: Is it possible to prevent the Google Play app from creating a shortcut of my App on install?, however the answer on it doesn't really address the question fully though.

I am really confused now, could someone shed some lights here?

Update 1 (Dec 17):

here is the android manifest file ( I replaced some name to remove some sensitive information). The SplashActivity is the entry point for our app.

<?xml version="1.0" encoding="utf-8"?>

<uses-sdk
    android:minSdkVersion="9"
    android:targetSdkVersion="17" />

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT"/>
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>

<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

<application
    android:name=".xxApplication"
    android:allowBackup="true"
    android:icon="@drawable/xx_logo"
    android:label="@string/app_label"
    android:theme="@style/xxTheme.Holo" >
    <activity
        android:name="com.xx.xx.android.MainActivity"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name="com.xx.xx.android.TestActivity"
        android:label="TestActivity"
        android:screenOrientation="portrait" >

        <!--
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        -->
    </activity>
    <activity
        android:name="com.LS.zxing22.android.CaptureActivity"
        android:configChanges="orientation|keyboardHidden"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar"
        android:windowSoftInputMode="stateAlwaysHidden" >
    </activity>
    <activity
        android:name=".ui.EnrollmentActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar" >
    </activity>
    <activity
        android:name=".ui.LoginActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar" >
    </activity>
    <activity
        android:name=".ui.AgreementActivity"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name=".ui.UsagePolicyActivity"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name=".ui.FinishActivity"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name=".ui.MainActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.Holo.Menu" >
    </activity>
    <activity
        android:name=".ui.AccessPasswordActivity"
        android:label="@string/activity_label_access_password"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name=".ui.LoginCodeActivity"
        android:label="@string/activity_label_login_code"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name="org.wordpress.passcodelock.PasscodeUnlockActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar" >
    </activity>
    <activity
        android:name="org.wordpress.passcodelock.PasscodePreferencesActivity"
        android:screenOrientation="portrait" >
    </activity>
    <activity
        android:name="org.wordpress.passcodelock.PasscodeManagePasswordActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar" >
    </activity>
    <activity
        android:name=".ui.SplashActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar.Splash" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity
        android:name=".ui.TutorialActivity"
        android:screenOrientation="portrait">
        <intent-filter>
            <action android:name="com.xx.xx.android.ui.TutorialActivity.Action" />

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </activity>

    <service
        android:name="com.xx.xx.android.services.xxService"
        android:enabled="true" >
        <intent-filter>
            <action android:name="com.xx.xx.android.services.IxxServiceRemoteInterface" />
        </intent-filter>
    </service>
    <service
        android:name="com.xx.xx.android.services.NetworkIntentService"
        android:enabled="true" >
    </service>
    <service
        android:name="com.xx.xx.android.services.xxAppIntentService"
        android:enabled="true" >
    </service>
    <service
        android:name="com.xx.xx.android.services.DeviceAttributeUploadIntentService"
        android:enabled="true" >
    </service>
    <service
        android:name="com.xx.xx.android.services.HeartbeatIntentService"
        android:enabled="true" >
    </service>
    <service
        android:name="com.xx.xx.android.services.DeviceWipeIntentService"
        android:enabled="true" >
    </service>
</application>

Community
  • 1
  • 1
windfly2006
  • 1,703
  • 3
  • 25
  • 48
  • In a recent update, did you change the name (or package name) of the root activity (the one with ACTION=MAIN and CATEGORY=DEFAULT)? – David Wasser Dec 16 '13 at 18:08
  • we did change the package name to make it all lower case to match java naming convention. so I unpublished original app at the Google Play and republished this out. However I did uninstall the old app before installing the new app. The new app is first time published to Google Play with that package name (lower case name) – windfly2006 Dec 16 '13 at 18:51
  • please share your manifest... – Rachit Mishra Dec 16 '13 at 21:34
  • @twntee, I just edit my original post with our Android app manifest file. Please let me know what's wrong here, Thanks very much. – windfly2006 Dec 17 '13 at 14:53

1 Answers1

3

Because in your Manifest you are declaring your SplashActivity with a Main intent filter

<activity
        android:name=".ui.SplashActivity"
        android:screenOrientation="portrait"
        android:theme="@style/xxTheme.NoTitleBar.Splash" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
</activity>

That intent filter, puts a shortcut in the device's launcher. The second shortcut is the one you create in runtime

noni
  • 2,927
  • 19
  • 18
  • Thanks for the response. Great that we found out the cause although I am a little confused. Obviously we need to have the Main intent filter for the first activity to be launched, so that would mean that we don't need to have those code to create shortcuts for our app then, just wonder why there are still a lot of sample code for creating shortcut then. It seems not necessary at all. Another thing is that I didn't see that shortcut is always created for app installed from Google Play although I might be wrong (I would think that they need to have that Main intent filter). – windfly2006 Dec 17 '13 at 15:36
  • 1
    Because it depends on the Launcher you are running. Let's put this way. Android Launchers are like normal apps, packaged on APKs. They listen to intent like another app (I.E. when you click a IMDB link on CHROME it will ask you to open IMDB app). OK, if the user replaces it's launcher with another that DO NOT CREATE shortcuts on its app Drawer, that code will give you the chance to create an icon on user's home. Obviously most of the people use a Launcher that show the icons on its drawer – noni Dec 17 '13 at 15:50
  • Great info, thanks very much for the insight. Another question, for our code there which is used to check whether shortcut is created or not. Any idea why we could not find the shortcut created by Google Play? I think that we might remove code to create shortcut, so this code could be irrelevant for our app, however I just would like to understand more here. :-) – windfly2006 Dec 17 '13 at 16:50
  • Probably that code detects shortcuts inside App Drawer, but no inside Home Desktop, I really don't know the answer for that but maybe this would help you: http://stackoverflow.com/questions/4668396/how-to-detect-shortcut-in-home-screen – noni Dec 17 '13 at 17:09