Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android PreInstall detection

Tags:

android

My android application will be preinstalled. And I want to keep tracking of preinstalled apps.

For this purpose I need somehow to save a key or a flag (which means that app is preinstalled). I will add this key to each request to my back-end and will analyze it. I have an issue with that. An issue is about update from Google Play.

The standart workflow is the following:

1) I give to a manufacturer a special version of my application, which saves a key somehow (in Shared Prefs for example).

2) Manufacturer sell device with the app (special, modified).

3) When User get it, there definetly be next version of the app (standart, without special code) in the Google Play, so user perhaps update it without any launching (the worst case).

4) I lost my tracking possibility. (new apk fully removing never launched old one which was special)

To solve it I was listening a system broadcast ON_BOOT_COMPLETE, but its not working properly on Android 3.1+.

Have you any ideas how can I do that?

like image 347
TsimoX Avatar asked Nov 06 '13 14:11

TsimoX


2 Answers

Can you install an additional .apk that only has a service? Then that service can have the key, etc. and it can listen for when your app starts and send the tracking info. Then it won't matter if your app gets upgraded; the service will still be the same.

like image 84
ajh158 Avatar answered Sep 24 '22 02:09

ajh158


There are some ways to know if application is system application or not. Like by checking installed directory of application or check FLAG_SYSTEM for the application.

Method 1 : - Check location of application

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; 
}

Method 2 : - Check FLAG_SYSTEM of application

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; 
}

And call this method as

if (applicationIsSystemApp(getApplicationContext(), "com.example.mysystemapp")) {
     // Application is system app
} else {
     // Application has been installed as 3rd Party app
}
like image 24
Pankaj Kumar Avatar answered Sep 24 '22 02:09

Pankaj Kumar