原理:
原理不多说,看下安卓源码就知道了。
首先得到AssetManager,然后用AssetManager的openXmlResourceParser方法获取XmlResourceParser,通过XmlResourceParser开始解析APK内的AndroidManifest.xml文件
解决方案:
直接上代码吧,很简单。package com.example.linetest;import java.lang.reflect.Method;import java.util.HashMap;import java.util.Map;import org.xmlpull.v1.XmlPullParser;import android.annotation.SuppressLint;import android.content.IntentFilter;import android.content.res.AssetManager;import android.content.res.XmlResourceParser;import android.os.PatternMatcher;import android.text.TextUtils;public class IntentFilterParser { String apkPath; public IntentFilterParser(String apkPath) { this.apkPath = apkPath; } public Map<String, IntentFilter> getIntentFilter() { Map<String, IntentFilter> intentFilters = new HashMap<String, IntentFilter>(); AssetManager assetManager = null; XmlResourceParser parser = null; try { assetManager = AssetManager.class.newInstance(); Method method = AssetManager.class.getDeclaredMethod("addAssetPath", String.class); method.invoke(assetManager, apkPath); parser = assetManager.openXmlResourceParser(ANDROID_MANIFEST_FILENAME); parseManifest(parser, intentFilters); parser.close(); assetManager.close(); parser = null; assetManager = null; } catch (Exception e) { } finally { if (parser != null) { parser.close(); parser = null; } if (assetManager != null) { assetManager.close(); assetManager = null; } } return intentFilters; } private void parseManifest(XmlResourceParser parser, Map<String, IntentFilter> intentFilters) throws Exception { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName == null) { continue; } if (tagName.equals("activity") || tagName.equals("receiver") || tagName.equals("service")) { String activityName = parser.getAttributeValue(ANDROID_RESOURCES, "name"); if (activityName != null) { parseActivity(activityName, intentFilters, parser); } } } } private void parseActivity(String activityName, Map<String, IntentFilter> intentFilters, XmlResourceParser parser) throws Exception { int outerDepth = parser.getDepth(); int type; while ((type = parser.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String tagName = parser.getName(); if (tagName == null) { continue; } if (tagName.equals("intent-filter")) { IntentFilter mFilter = new IntentFilter(); intentFilters.put(activityName, mFilter); parseIntentFilter(mFilter, parser); } } } /** * 解析Intent-Filter字段 * * @param mFilter * @param attrs * @throws Exception */ @SuppressLint("NewApi") private void parseIntentFilter(IntentFilter mFilter, XmlResourceParser attrs) throws Exception { int outerDepth = attrs.getDepth(); int type; while ((type = attrs.next()) != XmlPullParser.END_DOCUMENT && (type != XmlPullParser.END_TAG || attrs.getDepth() > outerDepth)) { if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) { continue; } String nodeName = attrs.getName(); if (nodeName == null) { continue; } if (nodeName.equals("action")) { String value = attrs.getAttributeValue(ANDROID_RESOURCES, "name"); if (!TextUtils.isEmpty(value)) { mFilter.addAction(value); } } else if (nodeName.equals("category")) { String value = attrs.getAttributeValue(ANDROID_RESOURCES, "name"); if (!TextUtils.isEmpty(value)) { mFilter.addCategory(value); } } else if (nodeName.equals("data")) { /** * Specify a URI authority host that is handled, as per * IntentFilter.addDataAuthority() . [string] */ String host = attrs.getAttributeValue(ANDROID_RESOURCES, "host"); /** * Specify a URI authority port that is handled, as per * IntentFilter.addDataAuthority() . [string] */ String port = attrs.getAttributeValue(ANDROID_RESOURCES, "port"); if (!TextUtils.isEmpty(host) && !TextUtils.isEmpty(port)) { mFilter.addDataAuthority(host, port); } /** * Specify a URI scheme that is handled, as per * IntentFilter.addDataScheme() . [string] */ String scheme = attrs.getAttributeValue(ANDROID_RESOURCES, "scheme"); if (!TextUtils.isEmpty(scheme)) { mFilter.addDataScheme(scheme); } /** * Specify a URI path that must exactly match, as per * IntentFilter.addDataPath() with PATTERN_LITERAL. [string] */ String path = attrs.getAttributeValue(ANDROID_RESOURCES, "path"); if (!TextUtils.isEmpty(path)) { mFilter.addDataPath(path, PatternMatcher.PATTERN_LITERAL); } /** * Specify a URI path that must be a prefix to match, as per * IntentFilter.addDataPath() with PATTERN_PREFIX. [string] */ String pathPrefix = attrs.getAttributeValue(ANDROID_RESOURCES, "pathPrefix"); if (!TextUtils.isEmpty(pathPrefix)) { mFilter.addDataPath(pathPrefix, PatternMatcher.PATTERN_PREFIX); } /** * Specify a URI path that matches a simple pattern, as per * IntentFilter.addDataPath() with PATTERN_SIMPLE_GLOB. [string] */ String pathPattern = attrs.getAttributeValue(ANDROID_RESOURCES, "pathPattern"); if (!TextUtils.isEmpty(pathPattern)) { mFilter.addDataPath(pathPattern, PatternMatcher.PATTERN_SIMPLE_GLOB); } /** * Specify a MIME type that is handled, as per * IntentFilter.addDataType() . [string] */ String mimeType = attrs.getAttributeValue(ANDROID_RESOURCES, "mimeType"); if (!TextUtils.isEmpty(mimeType)) { mFilter.addDataType(mimeType); } if (android.os.Build.VERSION.SDK_INT >= 19) { /** * Specify a URI scheme specific part that must exactly * match, as per IntentFilter.addDataSchemeSpecificPart() * with PATTERN_LITERAL. [string] */ String ssp = attrs.getAttributeValue(ANDROID_RESOURCES, "ssp"); mFilter.addDataSchemeSpecificPart(ssp, PatternMatcher.PATTERN_LITERAL); /** * Specify a URI scheme specific part that must be a prefix * to match, as per IntentFilter.addDataSchemeSpecificPart() * with PATTERN_PREFIX. [string] */ String sspPrefix = attrs.getAttributeValue(ANDROID_RESOURCES, "sspPrefix"); mFilter.addDataSchemeSpecificPart(sspPrefix, PatternMatcher.PATTERN_PREFIX); /** * Specify a URI scheme specific part that matches a simple * pattern, as per IntentFilter.addDataSchemeSpecificPart() * with PATTERN_SIMPLE_GLOB. [string] */ String sspPattern = attrs.getAttributeValue(ANDROID_RESOURCES, "sspPattern"); mFilter.addDataSchemeSpecificPart(sspPattern, PatternMatcher.PATTERN_SIMPLE_GLOB); } } } } private static final String ANDROID_RESOURCES = "http://schemas.android.com/apk/res/android"; private static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";}