Android PreInstall Detection

My Android app will be pre-installed. And I want to track preinstalled applications.

To do this, I need to somehow save the key or flag (this means that the application is pre-installed). I will add this key to each request in my internal server and analyze it. I have a problem with this. The problem is related to updating on Google Play.

The standard workflow is as follows:

1) I give the manufacturer a special version of my application that somehow saves the key (for example, in general prefiles).

2) The manufacturer sells the device with the application (special, modified).

3) When the user receives it, there will definitely be the next version of the application (standard, without a special code) on Google Play, so the user may update it without launching (in the worst case).

4) I lost trackability. (the new apk completely removes, never launched the old one, which was special)

To solve this problem, I listened to the ON_BOOT_COMPLETE system broadcast, but it does not work properly on Android 3.1+ .

Do you have any idea how I can do this?

+4
source share
4 answers

.apk, ? .., , . , ; .

+5

, . , FLAG_SYSTEM .

1: -

public static boolean applicationIsSystemApp(Context mContext, String packageName) {

    try {
        ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(packageName, 0);        
        String appLocation = applicationInfo.publicSourceDir; 
        // OR String appLocation = applicationInfo.sourceDir;  
        // Both returns the same
        // if package is pre-installed then output will be /system/app/application_name.apk
        // if package is installed by user then output will be /data/app/application_name.apk

        // Check if package is system app 
        if (appLocation != null && appLocation.startsWith("/system/app/")) {
            return true; 
        }
    } catch (NameNotFoundException e) {
        e.printStackTrace(); // TODO Can handle as your logic
    }
    return false; 
}

2: - FLAG_SYSTEM

public static boolean applicationIsSystemApp(Context mContext, String packageName) {

    try {
        ApplicationInfo applicationInfo = mContext.getPackageManager().getApplicationInfo(packageName, 0);   
        // FLAG_SYSTEM is only set to system applications, 
        // this will work even if application is installed in external storage

        // Check if package is system app 
        if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
            return true; 
        }
    } catch (NameNotFoundException e) {
        e.printStackTrace(); // TODO Can handle as your logic
    }
    return false; 
}

if (applicationIsSystemApp(getApplicationContext(), "com.example.mysystemapp")) {
     // Application is system app
} else {
     // Application has been installed as 3rd Party app
}
+3

ApplicationInfo sourceDir. .

"/system/app", "/data/app"

-

try {
            ApplicationInfo appInfo = this.getPackageManager().getApplicationInfo("com.example.san", 0);
            boolean isSystemApp = false;
            if(appInfo.sourceDir.startsWith("/system/app")){ // You can use "contains" too
                isSystemApp = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

: . , .

+1

- APK, : RECEIVE_BOOT_COMPLETED

, , , PREINSTALLED , , .

You look at this token file in all of your subsequent versions of the APK to determine if the running copy is coming from the device that it previously installed or not.

This solves the mayor’s problems:

1) Then its OK, if the user updates the APK to the latest version, you can still read this token.

2) You do not need to support a separate APK in the Google game for a pre-installed community

3) You do not need to jostle with the OEM to install multiple APKs when you actually only have one application.

0
source

All Articles