[Android]教你如何擷取未安裝應用的ResolveInfo,androidresolveinfo
原理:查看了下安卓源碼,明白瞭解析過程,只是自己的話就要移植安卓的源碼,有人解析成功了,但是我覺得太麻煩。大概說下安卓的解析過程吧。
public PackageInfo getPackageArchiveInfo(String archiveFilePath, int flags) { PackageParser packageParser = new PackageParser(archiveFilePath); DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); final File sourceFile = new File(archiveFilePath); PackageParser.Package pkg = packageParser.parsePackage( sourceFile, archiveFilePath, metrics, 0); if (pkg == null) { return null; } if ((flags & GET_SIGNATURES) != 0) { packageParser.collectCertificates(pkg, 0); } return PackageParser.generatePackageInfo(pkg, null, flags, 0, 0); }
這裡是源碼,首先通過PackageParser解析,然後通過PackageParser.generatePackageInfo返回PackageInfo,但是PackageInfo裡卻把intent-filter給去掉了,不知道為啥,不過既然知道了這段代碼那麼就好好辦了。那就是通過反射把PackageParser.Package得到,然後再封裝成intentfilter。解決方案:直接上代碼把。因為完全就是通過反射又重寫了一次代碼。
try { // 先得到解析類PackageParser並執行個體化 Class packageParserClass = Class.forName("android.content.pm.PackageParser"); Object packageParser = packageParserClass.getConstructor(String.class).newInstance(dexPath); // 構建參數 DisplayMetrics metrics = new DisplayMetrics(); metrics.setToDefaults(); File sourceFile = new File(dexPath); // 調用PackageParser的parsePackage解析資料 Method method = packageParserClass.getDeclaredMethod("parsePackage", File.class, String.class, DisplayMetrics.class, int.class); method.setAccessible(true); Object Package = method.invoke(packageParser, sourceFile, dexPath, metrics, 0); // 反射得到結果 Field activities = Package.getClass().getDeclaredField("activities"); activities.setAccessible(true); ArrayList filters = (ArrayList) activities.get(Package); for (int i = 0; i < filters.size(); i++) { Object activity = filters.get(i); Field intentsField = activity.getClass().getField("intents"); intentsField.setAccessible(true); ArrayList<IntentFilter> intents = (ArrayList<IntentFilter>) intentsField.get(activity); for (int j = 0; j < intents.size(); j++) { if (intents.iterator().hasNext()) { String actionString = intents.get(0).getAction(0); String categoryString = intents.get(0).getCategory(0); System.out.println(actionString + " " + categoryString); } } } } catch (Exception e) { }dexPath就是你要解析的APK的路徑。intentfilter裡有action和category。這樣就實現了得到一個activity的ResolveInfo,至於為什麼要類型轉來轉去,那就具體看安卓源碼吧。