当前位置: 代码迷 >> Android >> [Android]教你怎么获取未安装应用的ResolveInfo(非反射,手动解析)
  详细解决方案

[Android]教你怎么获取未安装应用的ResolveInfo(非反射,手动解析)

热度:55   发布时间:2016-04-28 01:37:08.0
[Android]教你如何获取未安装应用的ResolveInfo(非反射,手动解析)

原理:

原理不多说,看下安卓源码就知道了。
首先得到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";}


  相关解决方案