How to Know an Application Is Installed from Google Play or Side-Load

How to know an application is installed from google play or side-load?

The PackageManager class supplies the getInstallerPackageName method that will tell you the package name of whatever installed the package you specify. Side-loaded apps will not contain a value.

EDIT: Note @mttmllns' answer below regarding the Amazon app store.

Detect if an app is installed from Play store

This method will check if your app has been installed from the Play Store.

boolean verifyInstallerId(Context context) {
// A list with valid installers package name
List<String> validInstallers = new ArrayList<>(Arrays.asList("com.android.vending", "com.google.android.feedback"));

// The package name of the app that has installed your app
final String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());

// true if your app has been downloaded from Play Store
return installer != null && validInstallers.contains(installer);
}

Some days ago I released an Android library, PiracyChecker, that protects your app using some techniques, such as Google Play Licensing (LVL), APK signature protection and installer ID (this one).

Check if an application is installed from Google Play

This should work for that purpose, taken from HockeyAppSDK for Android Github library:

protected static boolean installedFromMarket(WeakReference<? extends Context> weakContext) {
boolean result = false;

Context context = weakContext.get();
if (context != null) {
try {
String installer = context.getPackageManager().getInstallerPackageName(context.getPackageName());
// if installer string is not null it might be installed by market
if (!TextUtils.isEmpty(installer)) {
result = true;

// on Android Nougat and up when installing an app through the package installer (which HockeyApp uses itself), the installer will be
// "com.google.android.packageinstaller" or "com.android.packageinstaller" which is also not to be considered as a market installation
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N && (TextUtils.equals(installer, INSTALLER_PACKAGE_INSTALLER_NOUGAT) || TextUtils.equals(installer, INSTALLER_PACKAGE_INSTALLER_NOUGAT2))) {
result = false;
}

// on some devices (Xiaomi) the installer identifier will be "adb", which is not to be considered as a market installation
if (TextUtils.equals(installer, INSTALLER_ADB)) {
result = false;
}
}

} catch (Throwable ignored) {
}
}

return result;
}

However, I'd suggest to build two different apps for that purpose. If you're including forbidden code in Google Play, although it won't be executed helped by this method, it will be part of your bytecode and it's very likely to be banned by Google. It's much more cleaner to strip that out of your code by creating another flavour.

Check if Android app is installed by playstore

You can use this

Signature[] sighashes = context.getPackageManager().getPackageInfo(context.getPackageName(), PackageManager.GET_SIGNATURES).signatures;

The signatures can be compared with your debug keys or release keys(that you used when uploading to Play Store) to check whether its from apk or play store.

However if someone has access to your release key signed apk then I dont know if its possible to distinguish.

Check if application is installed - Android

Try this:

private boolean isPackageInstalled(String packageName, PackageManager packageManager) {
try {
packageManager.getPackageInfo(packageName, 0);
return true;
} catch (PackageManager.NameNotFoundException e) {
return false;
}
}

It attempts to fetch information about the package whose name you passed in. Failing that, if a NameNotFoundException was thrown, it means that no package with that name is installed, so we return false.

Note that we pass in a PackageManager instead of a Context, so that the method is slightly more flexibly usable and doesn't violate the law of Demeter. You can use the method without access to a Context instance, as long as you have a PackageManager instance.

Use it like this:

public void someMethod() {
// ...

PackageManager pm = context.getPackageManager();
boolean isInstalled = isPackageInstalled("com.somepackage.name", pm);

// ...
}

Note: From Android 11 (API 30), you might need to declare <queries> in your manifest, depending on what package you're looking for. Check out the docs for more info.

Android: check somewhere an app is installed via store or manually?

There is getInstallerPackageName() method in PackageManager. For side-loaded APKs it will return no name.

What happened to Google's sideload check documentation?

This library, although convenient, was only a temporary solution until a better solution could be found. This library effectively makes a disk read on every startup of the app, which affects startup latency. Note that this affects all users regardless of whether they have all splits or not, but is only useful for users who sideloaded the app so they'd get a warning message instead of a crash.

The Android platform is now rejecting the installation of apps that don't have all the required splits, rendering the sideloading API unnecessary. This solution should work on all Android versions.

Android, sideloading applications and keep them up to date via Google Play

As per January 2015, this appears to be impossible. Here is the response I got from Google Play Developer support:

Side-loaded apps do not update via the Play Store. If you would like the app to update, you will need to uninstall the app on your phone and reinstall the app via the Play Store.

I wonder if anyone found a way around this?



Related Topics



Leave a reply



Submit