如何解析第三方Intent

下面是工作过程中同事总结分析的内容

我们经常在程序中碰到第三方的Intent,如来电广播中的Intent,Intent中携带着很多信息,但是很多时候我们不知道Intent中携带了哪些信息,也在不知道Intent数据中的key,无法通过key来获取对应的值,对机型适配和对陌生领域的探索带来了一些麻烦。本文将介绍如何解析第三方Intent。

Intent内部是通过Bundle来实现的,比如我们调用Intent.putExtra(name,value),其实就是往Bundle里面写数据,而Bundle内部是通过一个map和一个Parcel来存储数据,如果存在map中外部可以看到,而如果存在parcel中,外界则无法看到。数据存在Parcel中则需要通过反序列化获取数据,好在,Intent内部提供了接口unparcel(),调用该接口,intent会将数据重新写入map中,所以我们可以通过反射的方式来获取Intent内部的Bundle,再通过反射调用Bundle中unparcel()方法,将数据写入map,最后再反射得到bundle中的map,获取到map就可以获取到key和value对了。以下代码经过测试,可以使用。

/**
	 * 获取并打印外部intent中携带的信息
	 * 
	 * @param 第三方intent
	 * @return 存储Intent中数据的map
	 * @author yangli3
	 */
	@SuppressWarnings("unchecked")
	public static Map<String, Object> getAndPrintIntentExtras(Intent intent) {
		if (null == intent) {
			return null;
		}
		Map<String, Object> map = null;
		try {
			Field fieldExtras = intent.getClass().getDeclaredField("mExtras");
			fieldExtras.setAccessible(true);
			Bundle bundle = (Bundle) fieldExtras.get(intent);

			Method method = bundle.getClass().getDeclaredMethod("unparcel");
			method.setAccessible(true);
			method.invoke(bundle);

			if (null != bundle) {
				Field fieldMap = bundle.getClass().getDeclaredField("mMap");
				fieldMap.setAccessible(true);
				map = (Map<String, Object>) fieldMap.get(bundle);
			}

			if (null != map) {
				Set<String> set = map.keySet();
				for (String key : set) {
					Log.d(TAG, "key = " + key + ", value = " + map.get(key));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return map;
	}

你可能感兴趣的:(如何解析第三方Intent)