Today, I faced the challenge to check from within the Android SDK, if the app I was running was installed via Google Play or not.

In the Android SDK, there is a way to get the package name of the app that installed a specific package.

Getting the package name is quite easy provided you have the Context instance:

String packageName = ctx.getPackageName();

The getPackageName method returns the name of the application's package.

Once we have the package name, getting the package name of the app that was used to install the application depends on which version of Android you are running. The original method was getInstallerPackageName:

PackageManager pm = ctx.getPackageManager();
String installerPackageName = pm.getInstallerPackageName(packageName);

However, this method was deprecated in Android API level 30. As of Android API level 30, you're supposed to use InstallSourceInfo.getInstallingPackageName instead:

PackageManager pm = ctx.getPackageManager();
InstallSourceInfo info = pm.getInstallSourceInfo(packageName);

String installerPackageName = "";
if (info != null) {
    installerPackageName = info.getInstallingPackageName();
}

Now that we have the package name of the installer app, how do we check if it's Google Play? You need to check if that package name equals com.android.vending:

"com.android.vending".equals(installerPackageName);

Don't make the mistake of doing it like this:

installerPackageName.equals("com.android.vending");

This might fail as installerPackageName might be null. If that's the case, the second approach will fail while the first one will work just fine.

So, combining everything together gives us (with some extra options):

YDGooglePlayUtils.java

package be.yellowduck.apps.utils;

import android.content.Context;
import android.content.pm.InstallSourceInfo;
import android.content.pm.PackageManager;
import android.os.Build;
import android.text.TextUtils;

public class YDGooglePlayUtils {

    public static String GOOGLE_PLAY = "com.android.vending";
    public static String AMAZON = "com.amazon.venezia";

    public static boolean isInstalledViaGooglePlay(Context ctx) {
        return isInstalledVia(ctx, GOOGLE_PLAY);
    }

    public static boolean isInstalledViaAmazon(Context ctx) {
        return isInstalledVia(ctx, AMAZON);
    }

    public static boolean isSideloaded(Context ctx) {
        String installer = getInstallerPackageName(ctx);
        return TextUtils.isEmpty(installer);
    }

    public static boolean isInstalledVia(Context ctx, String required) {
        String installer = getInstallerPackageName(ctx);
        return required.equals(installer);
    }

    private static String getInstallerPackageName(Context ctx) {
        try {
            String packageName = ctx.getPackageName();
            PackageManager pm = ctx.getPackageManager();
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
                InstallSourceInfo info = pm.getInstallSourceInfo(packageName);
                if (info != null) {
                    return info.getInstallingPackageName();
                }
            }
            return pm.getInstallerPackageName(packageName);
        } catch (PackageManager.NameNotFoundException e) {
        }
        return "";
    }

}

Related Posts

  • Taking an Android screenshot via terminal
  • Upgrading your Gradle project to version 7
  • Creating a fat jar from gradle
  • Auto-accepting terms of service with Gradle build scans
  • Creating a runnable jar using Gradle