5

我的 android 应用程序将被预装。我想继续跟踪预装的应用程序。

为此,我需要以某种方式保存密钥或标志(这意味着该应用程序已预装)。我会将此密钥添加到后端的每个请求中并对其进行分析。我有一个问题。一个问题是关于来自 Google Play 的更新

标准工作流程如下:

1)我给制造商一个特别的版本的我的应用程序,它以某种方式保存了一个密钥(例如在共享首选项中)。

2)制造商销售带有应用程序的设备(特殊,修改)。

3)当用户得到它时,Google Play 中肯定会有应用程序的下一个版本(标准,没有特殊代码),所以用户可能会在没有任何启动的情况下更新它(最坏的情况)。

4) 我失去了追踪的可能性。(完全删除的新 apk 从未启动过特殊的旧 apk)

为了解决它,我正在收听系统广播 ON_BOOT_COMPLETE,但它在 Android 3.1+ 上无法正常工作

你有什么想法我该怎么做?

4

4 回答 4

5

你能安装一个额外的.apk,它只有一个服务吗?然后该服务可以拥有密钥等,它可以侦听您的应用程序何时启动并发送跟踪信息。然后,您的应用程序是否升级都没关系;服务还是一样的。

于 2013-11-17T02:40:46.943 回答
3

有一些方法可以知道应用程序是否是系统应用程序。就像通过检查应用程序的安装目录或检查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
}
于 2013-11-21T07:03:04.667 回答
1

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

注意:我没有测试它..希望它有效

于 2013-11-18T22:03:37.863 回答
1

一种行之有效的解决方案是预安装具有以下权限的 APK:RECEIVE_BOOT_COMPLETED

然后在第一次启动时 - 您快速表示您已预先安装到您使用的任何持久存储中,最好添加一个令牌文件。

您在所有更高版本的 APK 中查找此令牌文件,以确定运行副本是否源自预安装它的设备。

这解决了市长问题:

1)然后如果用户将您的APK更新到最新版本就可以了,您仍然可以读取此令牌。

2)您不必为预装社区在google play上维护单独的APK

3)当您实际上只有一个应用程序时,您不必与 OEM 一起安装多个 APK。

于 2013-12-08T19:05:25.800 回答