only parse <uses-sdk> once when looking for min/max SDK version
When building APK instances from installed apps, the minSdkVersion and maxSdkVersion needs to be parsed directly from the APK's Android Manifest, since PackageManager does not provide a method to get it how we need it. Previously, the whole AndroidManifest.xml file was parsed entirely twice, once for minSdkVersion then for maxSdkVersion.
This commit is contained in:
parent
02d98826a9
commit
f08f8cb53d
@ -20,8 +20,6 @@ package org.fdroid.fdroid;
|
|||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
import android.content.res.AssetManager;
|
|
||||||
import android.content.res.XmlResourceParser;
|
|
||||||
import android.graphics.Bitmap;
|
import android.graphics.Bitmap;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.support.annotation.NonNull;
|
import android.support.annotation.NonNull;
|
||||||
@ -39,12 +37,9 @@ import com.nostra13.universalimageloader.utils.StorageUtils;
|
|||||||
|
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.fdroid.fdroid.compat.FileCompat;
|
import org.fdroid.fdroid.compat.FileCompat;
|
||||||
import org.fdroid.fdroid.data.Apk;
|
|
||||||
import org.fdroid.fdroid.data.Repo;
|
import org.fdroid.fdroid.data.Repo;
|
||||||
import org.fdroid.fdroid.data.SanitizedFile;
|
import org.fdroid.fdroid.data.SanitizedFile;
|
||||||
import org.xml.sax.XMLReader;
|
import org.xml.sax.XMLReader;
|
||||||
import org.xmlpull.v1.XmlPullParser;
|
|
||||||
import org.xmlpull.v1.XmlPullParserException;
|
|
||||||
|
|
||||||
import java.io.BufferedInputStream;
|
import java.io.BufferedInputStream;
|
||||||
import java.io.Closeable;
|
import java.io.Closeable;
|
||||||
@ -225,38 +220,6 @@ public final class Utils {
|
|||||||
return ANDROID_VERSION_NAMES[sdkLevel];
|
return ANDROID_VERSION_NAMES[sdkLevel];
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PackageManager doesn't give us the min and max sdk versions, so we have
|
|
||||||
* to parse it */
|
|
||||||
private static int getSdkVersion(Context context, String packageName,
|
|
||||||
String attrName, final int defaultValue) {
|
|
||||||
try {
|
|
||||||
AssetManager am = context.createPackageContext(packageName, 0).getAssets();
|
|
||||||
XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml");
|
|
||||||
int eventType = xml.getEventType();
|
|
||||||
while (eventType != XmlPullParser.END_DOCUMENT) {
|
|
||||||
if (eventType == XmlPullParser.START_TAG && "uses-sdk".equals(xml.getName())) {
|
|
||||||
for (int j = 0; j < xml.getAttributeCount(); j++) {
|
|
||||||
if (xml.getAttributeName(j).equals(attrName)) {
|
|
||||||
return Integer.parseInt(xml.getAttributeValue(j));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
eventType = xml.nextToken();
|
|
||||||
}
|
|
||||||
} catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
|
|
||||||
Log.e(TAG, "Could not get min/max sdk version", e);
|
|
||||||
}
|
|
||||||
return defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMinSdkVersion(Context context, String packageName) {
|
|
||||||
return getSdkVersion(context, packageName, "minSdkVersion", Apk.SDK_VERSION_MIN_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static int getMaxSdkVersion(Context context, String packageName) {
|
|
||||||
return getSdkVersion(context, packageName, "maxSdkVersion", Apk.SDK_VERSION_MAX_VALUE);
|
|
||||||
}
|
|
||||||
|
|
||||||
// return a fingerprint formatted for display
|
// return a fingerprint formatted for display
|
||||||
public static String formatFingerprint(Context context, String fingerprint) {
|
public static String formatFingerprint(Context context, String fingerprint) {
|
||||||
if (TextUtils.isEmpty(fingerprint)
|
if (TextUtils.isEmpty(fingerprint)
|
||||||
|
@ -7,6 +7,8 @@ import android.content.pm.ApplicationInfo;
|
|||||||
import android.content.pm.FeatureInfo;
|
import android.content.pm.FeatureInfo;
|
||||||
import android.content.pm.PackageInfo;
|
import android.content.pm.PackageInfo;
|
||||||
import android.content.pm.PackageManager;
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.res.AssetManager;
|
||||||
|
import android.content.res.XmlResourceParser;
|
||||||
import android.database.Cursor;
|
import android.database.Cursor;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@ -15,6 +17,8 @@ import android.util.Log;
|
|||||||
import org.fdroid.fdroid.AppFilter;
|
import org.fdroid.fdroid.AppFilter;
|
||||||
import org.fdroid.fdroid.FDroidApp;
|
import org.fdroid.fdroid.FDroidApp;
|
||||||
import org.fdroid.fdroid.Utils;
|
import org.fdroid.fdroid.Utils;
|
||||||
|
import org.xmlpull.v1.XmlPullParser;
|
||||||
|
import org.xmlpull.v1.XmlPullParserException;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
@ -293,8 +297,9 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
apk.versionName = packageInfo.versionName;
|
apk.versionName = packageInfo.versionName;
|
||||||
apk.versionCode = packageInfo.versionCode;
|
apk.versionCode = packageInfo.versionCode;
|
||||||
apk.added = this.added;
|
apk.added = this.added;
|
||||||
apk.minSdkVersion = Utils.getMinSdkVersion(context, packageName);
|
int[] minMaxSdkVersions = getMinMaxSdkVersions(context, packageName);
|
||||||
apk.maxSdkVersion = Utils.getMaxSdkVersion(context, packageName);
|
apk.minSdkVersion = minMaxSdkVersions[0];
|
||||||
|
apk.maxSdkVersion = minMaxSdkVersions[1];
|
||||||
apk.packageName = this.packageName;
|
apk.packageName = this.packageName;
|
||||||
apk.permissions = Utils.CommaSeparatedList.make(packageInfo.requestedPermissions);
|
apk.permissions = Utils.CommaSeparatedList.make(packageInfo.requestedPermissions);
|
||||||
apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk";
|
apk.apkName = apk.packageName + "_" + apk.versionCode + ".apk";
|
||||||
@ -476,4 +481,34 @@ public class App extends ValueObject implements Comparable<App> {
|
|||||||
public String getSuggestedVersionName() {
|
public String getSuggestedVersionName() {
|
||||||
return suggestedVersionName;
|
return suggestedVersionName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@link PackageManager} doesn't give us {@code minSdkVersion} and {@code maxSdkVersion},
|
||||||
|
* so we have to parse it straight from {@code <uses-sdk>} in {@code AndroidManifest.xml}.
|
||||||
|
*/
|
||||||
|
private static int[] getMinMaxSdkVersions(Context context, String packageName) {
|
||||||
|
int minSdkVersion = Apk.SDK_VERSION_MIN_VALUE;
|
||||||
|
int maxSdkVersion = Apk.SDK_VERSION_MAX_VALUE;
|
||||||
|
try {
|
||||||
|
AssetManager am = context.createPackageContext(packageName, 0).getAssets();
|
||||||
|
XmlResourceParser xml = am.openXmlResourceParser("AndroidManifest.xml");
|
||||||
|
int eventType = xml.getEventType();
|
||||||
|
while (eventType != XmlPullParser.END_DOCUMENT) {
|
||||||
|
if (eventType == XmlPullParser.START_TAG && "uses-sdk".equals(xml.getName())) {
|
||||||
|
for (int j = 0; j < xml.getAttributeCount(); j++) {
|
||||||
|
if (xml.getAttributeName(j).equals("minSdkVersion")) {
|
||||||
|
minSdkVersion = Integer.parseInt(xml.getAttributeValue(j));
|
||||||
|
} else if (xml.getAttributeName(j).equals("maxSdkVersion")) {
|
||||||
|
maxSdkVersion = Integer.parseInt(xml.getAttributeValue(j));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
eventType = xml.nextToken();
|
||||||
|
}
|
||||||
|
} catch (PackageManager.NameNotFoundException | IOException | XmlPullParserException e) {
|
||||||
|
Log.e(TAG, "Could not get min/max sdk version", e);
|
||||||
|
}
|
||||||
|
return new int[]{minSdkVersion, maxSdkVersion};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user