/** * Computes the minimum SDK and target SDK versions for the project * * @param project the project to look up the versions for * @return a pair of (minimum SDK, target SDK) versions, never null */ @NonNull public static Pair<Integer, Integer> computeSdkVersions(IProject project) { int mMinSdkVersion = 1; int mTargetSdkVersion = 1; IAbstractFile manifestFile = AndroidManifest.getManifest(new IFolderWrapper(project)); if (manifestFile != null) { try { Object value = AndroidManifest.getMinSdkVersion(manifestFile); mMinSdkVersion = 1; // Default case if missing if (value instanceof Integer) { mMinSdkVersion = ((Integer) value).intValue(); } else if (value instanceof String) { // handle codename, only if we can resolve it. if (Sdk.getCurrent() != null) { IAndroidTarget target = Sdk.getCurrent().getTargetFromHashString("android-" + value); // $NON-NLS-1$ if (target != null) { // codename future API level is current api + 1 mMinSdkVersion = target.getVersion().getApiLevel() + 1; } } } Integer i = AndroidManifest.getTargetSdkVersion(manifestFile); if (i == null) { mTargetSdkVersion = mMinSdkVersion; } else { mTargetSdkVersion = i.intValue(); } } catch (XPathExpressionException e) { // do nothing we'll use 1 below. } catch (StreamException e) { // do nothing we'll use 1 below. } } return Pair.of(mMinSdkVersion, mTargetSdkVersion); }
/** * Ensure that the package, theme and activity maps are initialized and up to date with respect to * the manifest file */ private void sync() { // Since each of the accessors call sync(), allow a bunch of immediate // accessors to all bypass the file stat() below long now = System.currentTimeMillis(); if (now - mLastChecked < 50 && mManifestFile != null) { return; } mLastChecked = now; if (mManifestFile == null) { IFolderWrapper projectFolder = new IFolderWrapper(mProject); mManifestFile = AndroidManifest.getManifest(projectFolder); if (mManifestFile == null) { return; } } // Check to see if our data is up to date long fileModified = mManifestFile.getModificationStamp(); if (fileModified == mLastModified) { // Already have up to date data return; } mLastModified = fileModified; mActivityThemes = new HashMap<String, String>(); mManifestTheme = null; mTargetSdk = 1; // Default when not specified mMinSdk = 1; // Default when not specified mMinSdkName = ""; // Default when not specified mPackage = ""; // $NON-NLS-1$ mApplicationIcon = null; mApplicationLabel = null; Document document = null; try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); InputSource is = new InputSource(mManifestFile.getContents()); factory.setNamespaceAware(true); factory.setValidating(false); DocumentBuilder builder = factory.newDocumentBuilder(); document = builder.parse(is); Element root = document.getDocumentElement(); mPackage = root.getAttribute(ATTRIBUTE_PACKAGE); NodeList activities = document.getElementsByTagName(NODE_ACTIVITY); for (int i = 0, n = activities.getLength(); i < n; i++) { Element activity = (Element) activities.item(i); String theme = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_THEME); if (theme != null && theme.length() > 0) { String name = activity.getAttributeNS(NS_RESOURCES, ATTRIBUTE_NAME); if (name.startsWith(".") // $NON-NLS-1$ && mPackage != null && mPackage.length() > 0) { name = mPackage + name; } mActivityThemes.put(name, theme); } } NodeList applications = root.getElementsByTagName(AndroidManifest.NODE_APPLICATION); if (applications.getLength() > 0) { assert applications.getLength() == 1; Element application = (Element) applications.item(0); if (application.hasAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON)) { mApplicationIcon = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_ICON); } if (application.hasAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL)) { mApplicationLabel = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_LABEL); } String defaultTheme = application.getAttributeNS(NS_RESOURCES, ATTRIBUTE_THEME); if (defaultTheme != null && !defaultTheme.isEmpty()) { // From manifest theme documentation: // "If that attribute is also not set, the default system theme is used." mManifestTheme = defaultTheme; } } // Look up target SDK NodeList usesSdks = root.getElementsByTagName(NODE_USES_SDK); if (usesSdks.getLength() > 0) { Element usesSdk = (Element) usesSdks.item(0); mMinSdk = getApiVersion(usesSdk, ATTRIBUTE_MIN_SDK_VERSION, 1); mTargetSdk = getApiVersion(usesSdk, ATTRIBUTE_TARGET_SDK_VERSION, mMinSdk); } } catch (SAXException e) { AdtPlugin.log(e, "Malformed manifest"); } catch (Exception e) { AdtPlugin.log(e, "Could not read Manifest data"); } }