Android:从 Android 代码获取 APKs minSdkVersion
Android: getting an APKs minSdkVersion from Android code
我正在开发一个 Android 应用程序,它能够在用户需要时安装其他应用程序(作为我的应用程序的插件)。
但是,这些附加应用中的每一个都可能需要特定的 Android 版本到 运行。我想在 运行 时间执行检查,看看我尝试安装的 APK 是否真的与设备兼容。
现在,用下面的方法:
public PackageManager getPackageArchiveInfo(String archiveFilePath, int flags)
我可以获取有关 APK 文件的信息。但是,问题是返回的信息似乎只包含 APK 的 targetSdkVersion
而不是 minSdkVersion
,据我了解,它实际上确定了 Android 应用程序的最低版本可以installed/run上。 targetSdkVersion
如果我理解正确的话就是 "optimal" 版本。
所以,长话短说,我如何从 Android 本身确定设备上的 APK cna 运行? (我知道我可以在桌面上使用 AAPT,但 Android 本身不可用)
你可以的。
对于 Android N 及以上,使用 official API。
对于早期版本,可以使用this code,非常高效快速。这是它的一个更好的版本(即使 getAttributeName returns 是一个空字符串也能工作):
public static int getMinSdkVersion(File apkFile) throws ClassNotFoundException, IllegalAccessException, InstantiationException,
NoSuchMethodException, InvocationTargetException, IOException, XmlPullParserException {
final Class assetManagerClass = Class.forName("android.content.res.AssetManager");
final AssetManager assetManager = (AssetManager) assetManagerClass.newInstance();
final Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
final int cookie = (Integer) addAssetPath.invoke(assetManager, apkFile.getAbsolutePath());
final XmlResourceParser parser = assetManager.openXmlResourceParser(cookie, "AndroidManifest.xml");
while (parser.next() != XmlPullParser.END_DOCUMENT)
if (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("uses-sdk"))
for (int i = 0; i < parser.getAttributeCount(); ++i)
if (parser.getAttributeNameResource(i) == android.R.attr.minSdkVersion)//alternative, which works most of the times: "minSdkVersion".equals(parser.getAttributeName(i)))
return parser.getAttributeIntValue(i, -1);
return -1;
}
而且,如果你想要一个全方位的解决方案(遗憾的是这会占用大量堆内存和时间),你可以使用 APK 解析库,例如 APKParser. If you want just the basics of it, consider the APKParser improvement I suggested here.
我正在开发一个 Android 应用程序,它能够在用户需要时安装其他应用程序(作为我的应用程序的插件)。
但是,这些附加应用中的每一个都可能需要特定的 Android 版本到 运行。我想在 运行 时间执行检查,看看我尝试安装的 APK 是否真的与设备兼容。
现在,用下面的方法:
public PackageManager getPackageArchiveInfo(String archiveFilePath, int flags)
我可以获取有关 APK 文件的信息。但是,问题是返回的信息似乎只包含 APK 的 targetSdkVersion
而不是 minSdkVersion
,据我了解,它实际上确定了 Android 应用程序的最低版本可以installed/run上。 targetSdkVersion
如果我理解正确的话就是 "optimal" 版本。
所以,长话短说,我如何从 Android 本身确定设备上的 APK cna 运行? (我知道我可以在桌面上使用 AAPT,但 Android 本身不可用)
你可以的。
对于 Android N 及以上,使用 official API。
对于早期版本,可以使用this code,非常高效快速。这是它的一个更好的版本(即使 getAttributeName returns 是一个空字符串也能工作):
public static int getMinSdkVersion(File apkFile) throws ClassNotFoundException, IllegalAccessException, InstantiationException,
NoSuchMethodException, InvocationTargetException, IOException, XmlPullParserException {
final Class assetManagerClass = Class.forName("android.content.res.AssetManager");
final AssetManager assetManager = (AssetManager) assetManagerClass.newInstance();
final Method addAssetPath = assetManager.getClass().getMethod("addAssetPath", String.class);
final int cookie = (Integer) addAssetPath.invoke(assetManager, apkFile.getAbsolutePath());
final XmlResourceParser parser = assetManager.openXmlResourceParser(cookie, "AndroidManifest.xml");
while (parser.next() != XmlPullParser.END_DOCUMENT)
if (parser.getEventType() == XmlPullParser.START_TAG && parser.getName().equals("uses-sdk"))
for (int i = 0; i < parser.getAttributeCount(); ++i)
if (parser.getAttributeNameResource(i) == android.R.attr.minSdkVersion)//alternative, which works most of the times: "minSdkVersion".equals(parser.getAttributeName(i)))
return parser.getAttributeIntValue(i, -1);
return -1;
}
而且,如果你想要一个全方位的解决方案(遗憾的是这会占用大量堆内存和时间),你可以使用 APK 解析库,例如 APKParser. If you want just the basics of it, consider the APKParser improvement I suggested here.