我正在获取 ApplicationInfo 对象列表="noreferrer">packageManager.getInstalledApplications(0) 并尝试根据它们是否是系统应用程序对它们进行分类。
一段时间以来,我一直在使用描述的技术 这里,但是在我的应用程序中看到,有些应用程序不在非系统应用程序列表中(例如例如Facebook,当可用时会要求系统将其自身安装到 SD 卡上)。接下来阅读 ApplicationInfo.FLAG_SYSTEM 的实际文档后,并了解它实际上并不过滤系统应用程序,我现在正在寻找一种新方法。
我的猜测是,系统应用程序和非系统应用程序的 UID 之间存在很大差距,我可以收集这些差距来进行区分,但到目前为止我还没有找到答案。我还研究了其他标志,例如 ApplicationInfo.FLAG_EXTERNAL_STORAGE
,但我支持 API 1.5。
有人对此有真正的解决方案吗(不涉及FLAG_SYSTEM
)?
I am getting a list of ApplicationInfo
Objects with packageManager.getInstalledApplications(0) and attempting to categorize them by whether or not they are a system application.
For a while I have been using the technique described here, however after seeing that in my application, some of the apps were not in the non-system apps list (such as Facebook, which when available asks the system to install itself on the SD card). After next reading the actual documentation for ApplicationInfo.FLAG_SYSTEM, and understanding that it doesn't actually filter system apps, I am now looking for a new approach.
My guess is that there is a large gap between UIDs of System and non-system apps that I can gather to make this distinction, but as of yet I have not found an answer. I also looked into other flags, such as ApplicationInfo.FLAG_EXTERNAL_STORAGE
, however I am supporting API 1.5.
Does anyone have a real solution to this (not involving FLAG_SYSTEM
)?
发布评论
评论(14)
我的印象是系统映像中的所有应用程序都是系统应用程序(通常安装在
/system/app
中)。如果
FLAG_SYSTEM
仅设置为系统应用程序,则这甚至适用于外部存储中的应用程序:另一种方法是使用手机中的
pm
命令行程序。语法:
代码:
那么:
I was under the impression that all apps in the system image are system apps (and normally installed in
/system/app
).If
FLAG_SYSTEM
is only set to system applications, this will work even for apps in external storage:An alternative is to use the
pm
command-line program in your phone.Syntax:
Code:
Then:
您可以检查与系统签署的应用程序的签名。如下所示
您可以在我的博客上获取更多代码 如何检查应用程序是否为系统应用程序(通过签名)
You can check the signature of application which it signed with system. Like below
You can get more code on my blog How to check if application is system app or not (By signed signature)
有 2 种类型的非系统应用程序:
此代码将返回所有上述应用程序的列表:
There are 2 type of Non - system applications :
This code will return a list of all above applications:
好吧,在我看来,这是一个草率的解决方案(如果 /data/app 不是所有设备上的 apps 目录怎么办?),但经过彻底搜索后,这就是我想到的:
Well, it's a sloppy solution in my opinion (what if /data/app isn't the apps directory on all devices?), but after a thorough search, this is what I have come up with:
如果应用程序是非系统应用程序,则它必须具有可以启动它的启动意图。如果启动意图为空,那么它是一个系统应用程序。
系统应用程序示例:“com.android.browser.provider”、“com.google.android.voicesearch”。
对于上述应用程序,当您查询启动意图时,您将得到 NULL。
If an Application is a non-system application it must have a launch Intent by which it can be launched. If the launch intent is null then its a system App.
Example of System Apps: "com.android.browser.provider", "com.google.android.voicesearch".
For the above apps you will get NULL when you query for launch Intent.
这里有一点误解。对于 Android,“系统应用程序”的概念是安装在系统映像上的概念,它没有说明它来自哪个开发人员。因此,如果 OEM 决定将 Facebook 预加载到系统映像上,那么它就是一个系统应用程序,并且将继续如此,无论该应用程序的更新安装在何处。当然,它们不会安装在系统映像上,因为它是只读的。
所以 ApplicationInfo.FLAG_SYSTEM 是正确的,但这似乎不是您要问的问题。我认为您是在问软件包是否使用系统证书进行签名。这不一定是任何事情的良好指标,这可能因设备而异,并且普通 Android 上的一些令人惊讶的组件没有使用系统证书进行签名,即使您可能希望它们如此。
在较新版本的 Android 中,有一个新路径 /system/priv-app/ 尝试成为“真实”系统应用程序的安装位置。刚刚预加载到系统映像上的应用程序最终会位于 /system/app/ 中。请参阅AOSP 特权与系统应用
There is a little bit of misunderstanding here. For Android the notion of a "system app" is one that is install on the system image, it says nothing about what developer it came from. So, if an OEM decides to preload Facebook on to the system image, it is a system app and will continue to be so, regardless of where updates to the app get installed. They won't get installed on the system image, for sure, because it is read-only.
So ApplicationInfo.FLAG_SYSTEM is correct, but that doesn't seem to be the question you are asking. I think you're asking if a package is signed with the system certificate. Which is not necessarily a good indicator of anything, this may vary from device to device and some surprising components on vanilla Android are not signed with the system certificate, even though you might expect them to be.
In newer versions of Android there is a new path, /system/priv-app/ that attempts to be the install location for "real" system apps. Apps that are just pre-loaded on the system image then end up in /system/app/. See AOSP Privileged vs System app
以下是通过包名称查看应用程序是否为系统应用程序的不同可能方法(使用了本文中的一些代码)
Here are different possible ways to see if the app is a system app by its package name (used some of the codes in this post)
这是此处列出的其他响应的简化且更有效的版本。如果直接迭代 ApplicationInfos 会更有效。
This is a simplified and more efficient version of other responses listed here. It is more efficient if you just iterate directly over the ApplicationInfos.
因此,我想在这里放置一个我根据该线程和其他一些线程的知识制作的实用程序类。但在我继续之前,先对一些术语进行解释(如果我理解正确的话),这是从该类中复制的,并在其中使用。
因此,考虑到这一点,这里有 2 个函数:
要检查应用程序是特权系统应用程序还是普通系统应用程序,和/或使用平台/系统密钥签名,我将在下面留下 3 个函数。我相信这与这个问题无关,但我会把它放在以防像我这样的人需要它。
如果你愿意,你可以将最后一个加入到上面的那个中,但我真的不推荐它。仅当系统应用程序尚未更新时,它才会起作用。
So I'd like to put here an utility class I made with the knowledge of this thread and a few others. But before I continue, an explanation of some terms, if I got them all right, copied from that class, which are used on it.
So with that in mind, here are 2 functions:
To check if an app is a privileged system app or is ordinary system app, and/or is signed with the platform/system key, I'll leave 3 functions below. I believe it's off-topic to the question, but I'll put it in case anyone like me needed it.
If you want, you can join this last one to the ones above, but I don't really recommend it. It will only work work as long as the system app hasn't been updated.
如果有 APK 文件并想检查它是系统应用程序还是用户安装的
一个简单的逻辑:-
系统应用文件不可写
If having an APK file and want to check is it System app or User installed
a Simple logic:-
System app Files are not writable
您可以使用
checkSignatures
来确定应用程序是否是系统应用程序。所有系统应用程序均使用相同的密钥进行签名。
https: //developer.android.com/reference/android/content/pm/PackageManager#checkSignatures(java.lang.String,%20java.lang.String)
而用系统密钥签名的就是“android”包。
You can use
checkSignatures
to determine if an app is a system app or not.All system apps are signed with the same key.
https://developer.android.com/reference/android/content/pm/PackageManager#checkSignatures(java.lang.String,%20java.lang.String)
And signed with the system key is the "android" package.
这是我为此目的编写的 AppUtil。
使用示例:
AppsUtil.java
Here is an AppUtil I wrote for that purpose.
Usage example:
AppsUtil.java