17

Is there any way to know if an application has been downloaded from Amazon App Store or Google Play Store? I meant within the app itself, of course.

I have deployed an app to both sites and I rather like to know from where the customer has downloaded it within the application. I know, I can deploy different applications to each service, but this adds some maintenance work that could be avoided if there were some manner to solve it just with a conditional within the app using the same package.

Harnirvair Singh
  • 583
  • 7
  • 23
Fran Marzoa
  • 4,293
  • 1
  • 37
  • 53
  • 3
    why not just have a variable within each of the releases showing where it was uploaded to? Or have an OptionPane as the user... – David Kroukamp Jun 17 '12 at 14:42
  • 10
    `PackageManager` and `getInstallerPackageName()` will tell you what the installer was. You would have to run experiments to see what that returns under your different scenarios. – CommonsWare Jun 17 '12 at 15:12
  • @Fran if you did experiment what did you come up with? – ahsteele Jul 24 '12 at 05:11
  • @ashteele I finally used another approach, based on an Android library project on Eclipse for common things, and different app projects using that library for each market. – Fran Marzoa Nov 18 '12 at 15:38
  • Then please put that as an answer. – Warpzit Feb 20 '13 at 09:09
  • please provide getInstallerPackageName() definition –  Apr 08 '16 at 06:31

2 Answers2

17

In Code:

final PackageManager packageManager = getPackageManager();

try {
    final ApplicationInfo applicationInfo = packageManager.getApplicationInfo(getPackageName(), 0);
    if ("com.android.vending".equals(packageManager.getInstallerPackageName(applicationInfo.packageName))) {
        // App was installed by Play Store
    }
} catch (final NameNotFoundException e) {
    e.printStackTrace();
}

"com.android.vending" tells you it came from the Google Play Store. I'm not sure what the Amazon Appstore is, but it should be easy to test using the above code.

Via ADB:

adb shell pm dump "PACKAGE_NAME" | grep "vending"

Example:

adb shell pm dump "com.android.chrome" | grep "vending"

installerPackageName=com.android.vending
Jared Burrows
  • 54,294
  • 25
  • 151
  • 185
Scott Kennedy
  • 1,346
  • 12
  • 23
  • This yields an `installerPackageName` of `null` when attached to the Android Studio debugger and building direct to both a Google Nexus 7 as well as a Kindle Fire HD. Is that expected when connected to the debugger? And it'll return legit strings when it's a release.apk? – Alfie Hanssen Oct 24 '13 at 22:38
  • 1
    Yes and no. `null` is expected when the app is not installed via an app store, or when the installing app store does not set the field. The installer used by Android Studio does not set the field, so it is null. (For me, as seen in the "Run" tab `DEVICE SHELL COMMAND: pm install -r "/data/local/tmp/com.mypackage.myapp"`) In any case, Android Studio would almost certainly not set the value to `com.android.vending`, but more likely to `com.android.studio` or something. – nmr Jan 13 '14 at 20:54
6

While in most cases you can get the store name by including a check similar to this:

final PackageManager packageManager = getPackageManager();

try {
    final ApplicationInfo applicationInfo = packageManager.getApplicationInfo(getPackageName(), 0);
    if ("com.android.vending".equals(packageManager.getInstallerPackageName(applicationInfo.packageName))) {
        // App was installed by Play Store
    }  else if ("com.amazon.venezia".equals(packageManager.getInstallerPackageName(applicationInfo.packageName))) {
        // App was installed by Amazon Appstore
    } else {
        // App was installed from somewhere else
    }
} catch (final NameNotFoundException e) {
    e.printStackTrace();
}

"com.android.vending" is Google Play Store and
"com.amazon.venezia" is the Amazon Appstore, and
null when it was sideloaded

The results could be unreliable however, as for example during beta testing a store might not set this value, and besides it's possible to sideload your app specifying the installer's package name that could be interpreted as a store name:

adb install -i <INSTALLER_PACKAGE_NAME> <PATH_TO_YOUR_APK>

You might want to consider having different application IDs for different stores, for example "com.example.yourapp" for Google and "com.example.yourapp.amazon" for Amazon -- you can easily set those in your Gradle script.

Levon
  • 1,681
  • 2
  • 18
  • 40