8

I need to know which store is the App's installer so that I know which store to communicate with for in-App purchase functionality.

Is the definitive 100% reliable approach to generate two separate binaries? Or is there a 100% reliable code-based runtime approach?

There are many similar Stackoverflow questions. All have answers that suggest using methods like getInstallerPackageName on the PackageManager class. All also have comments or conflicting answers saying that this is not a reliable approach, suggesting that the only way to reliably check which store installed a given App is to generate two separate binaries, each with a storeFlag set, and upload one binary to Amazon and one to Google Play.

starball
  • 20,030
  • 7
  • 43
  • 238
Alfie Hanssen
  • 16,964
  • 12
  • 68
  • 74
  • Do you have a problem with using two separate binaries? It's literally a matter of changing a SINGLE line of code. – Cruncher Oct 25 '13 at 14:52
  • consider how you would detect the source store on a device with both? remember you can install the amazon store on any device and therefore you would have no way of knowing where it came from. – Eluvatar Oct 25 '13 at 14:52
  • @Cruncher, I can go the two separate binaries approach but it's a unique setup where a single binary is preferred. – Alfie Hanssen Oct 25 '13 at 15:22
  • @Eluvatar, if two stores were installed on the same device, I'd still need to know which store installed the App so that I can communicate with that store for IAP, no? – Alfie Hanssen Oct 25 '13 at 15:24
  • yes you would, I'd say if you want something reliable use separate builds, I suppose you could try to figure out the installer, but what if someone side loads the app (takes the apk from another device)? then what store would you use if you were trying to figure it out at runtime? – Eluvatar Oct 25 '13 at 21:57
  • Gotcha, that makes a lot of sense (I'm relatively new to the Android world, coming from iOS). Do you want to post some version of this an the answer so I can accept it? – Alfie Hanssen Oct 26 '13 at 14:30

1 Answers1

10

two binaries would be the most robust method but checking both the Build.MANUFACTURER and the installerName should get you pretty close (though assuming yo want to check for the Amazon AppStore if the user has installed an old version of the installer on their non-Kindle device and not updated the installerName might report null)

boolean isAmazonDevice = Build.MANUFACTURER.equalsIgnoreCase("amazon");

final Application application = getApplication();
String installerName = application.getPackageManager().getInstallerPackageName(application.getPackageName());
boolean fromAmazonStore = installerName != null && installerName.equalsIgnoreCase("com.amazon.venezia");

and then checking the value for:

isAmazonDevice || fromAmazonStore

should get you what you need for a significant amount of the time.

One scenario where this can confuse matters is if you are sideloading your apk for testing - in that case it wouldn't have the correct InstallerPackageName. You can fake that by sideloading the apk using:

adb install -i com.amazon.venezia APK_NAME
Offbeatmammal
  • 7,970
  • 2
  • 33
  • 52