android实现获取其它app的IntentFilter信息

android并没有提供获取四大组件的intentFilter信息功能,例如获取其它应用的activity中的action定义等,因为系统返回的ComponentInfo中删除了IntentFilter字段,如果要获取这些信息只能用其它方法。这里介绍两种方法,一种是调用PackageManager中的getAllIntentFilters方法,返回一个List<IntentFilter>集合,这个是系统api,只能反射调用,不过它返回的是所有intentfilter,里面没有component信息,所以不知道是哪个组件下的,另一种是反射调用系统PackageParser类,手动解析apk获取应用所有信息。第三种方法是直接解析AndroidManifest.xml,这个可以利用第三方插件实现,或者调用系统的AssetManager类实现(关于AssetManager解析xml请参考我写的另一篇文章《android反编译xml资源文件》),下面给出第二种方法代码:

这里不用反射调用信息,我们直接创建一个系统子类,在里面填写需要的信息即可,首先在java目录下创建包android.content.pm,然后创建以下两个类,用于获取最终信息:

public class PackageParser$Package {
    //用到的字段
    public final ArrayList<PackageParser$Component> activities = new ArrayList<>(0);
    public final ArrayList<PackageParser$Component> receivers = new ArrayList<>(0);
    public final ArrayList<PackageParser$Component> providers = new ArrayList<>(0);
    public final ArrayList<PackageParser$Component> services = new ArrayList<>(0);

    //可以在这里添加其它字段,参考系统源码PackageParser.Package类
    //...
}

public class PackageParser$Component {
    public ArrayList<IntentFilter> intents;  //这个就是我们要的数据
    public String className; //这个类名也要有

    public Bundle metaData;
    public Package owner;

    public int order;

    ComponentName componentName;
    String componentShortName;
}

最后上具体实现代码:

public class PackageUtils {

    //根据包名获取Package信息
    public static PackageParser$Package getPackageInfo(Context context, String packageName) {
        ApplicationInfo info = null;
        try {
            info = context.getPackageManager().getApplicationInfo(packageName, 0);
            if (info.sourceDir != null) {
                return getPackageInfo(new File(info.sourceDir));
            }
        } catch (Exception e) {
            Log.e("walx", e.toString());
        }
        return null;
    }

    public static PackageParser$Package getPackageInfo(File apkFile) {
        try {
            Class<?> clazz = Class.forName("android.content.pm.PackageParser");
            Object packageParser = newInstance(clazz, null, null);
            PackageParser$Package pkg = (PackageParser$Package) invokeMethod(packageParser, "parsePackage", new Class[]{File.class, int.class}, new Object[]{apkFile, 0});
            return pkg;
        } catch (Exception e) {
            Log.e("walx", e.toString());
        }
        return null;
    }

    private static Object newInstance(Class clazz, Class[] argsType, Object[] args) {
        Object instance = null;
        try {
            Constructor constructor;
            if (argsType == null) {
                constructor = clazz.getConstructor();
                constructor.setAccessible(true);
                instance = constructor.newInstance();
            } else {
                constructor = clazz.getConstructor(argsType);
                constructor.setAccessible(true);
                instance = constructor.newInstance(args);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return instance;
    }

    private static Object readField(Object object, String name) {
        try {
            Field field = object.getClass().getField(name);
            field.setAccessible(true);
            return field.get(object);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    private static Object invokeMethod(Object object, String name, Class[] argsType, Object[] args) {
        try {
            Method method = object.getClass().getMethod(name, argsType);
            method.setAccessible(true);
            return method.invoke(object, args);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
}
//调用测试

PackageParser$Package pkgInfo = PackageUtils.getPackageInfo(this, "com.android.settings");
if (pkgInfo != null) {
	Log.i(TAG, "activities:" + pkgInfo.activities.size());
	Log.i(TAG, "receivers:" + pkgInfo.receivers.size());
	Log.i(TAG, "providers:" + pkgInfo.providers.size());
	Log.i(TAG, "services:" + pkgInfo.services.size());
	
	//...
}

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值