栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Android PackageManager.queryintentactivities 查询不全问题

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Android PackageManager.queryintentactivities 查询不全问题

使用系统相关接口,可以根据 Intent 过滤查询对应的 Context

PackageManager.java

  • queryIntentActivities  查询符合Intent Activity
  • queryBroadcastReceivers  查询符合Intent BroadcastReceiver
  • queryIntentServices  查询符合Intent Service
  • queryIntentContentProviders 查询符合Intent ContentProvider

按照系统接口使用说明,查询桌面应用图标的 actvity 代码demo如下:

        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_DEFAULT);
        intent.addCategory(Intent.CATEGORY_LAUNCHER);

        List list = getPackageManager().queryIntentActivities(intent, 0);

        for (ResolveInfo resolveInfo : list) {
            Log.i(Activity_TAG, "resolveInfo " + resolveInfo);
        }

实际打印中会发现,打印出来的 activity 不全。原因在于系统对查询的结果进行过滤了一部分

    private @NonNull List queryIntentActivitiesInternal(Intent intent,
            String resolvedType, int flags, @PrivateResolveFlags int privateResolveFlags,
            int filterCallingUid, int userId, boolean resolveForStart, boolean allowDynamicSplits) {
        if (!mUserManager.exists(userId)) return Collections.emptyList();
        final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);
        mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,
                false , false ,
                "query intent activities");
        final String pkgName = intent.getPackage();
        ComponentName comp = intent.getComponent();
        if (comp == null) {
            if (intent.getSelector() != null) {
                intent = intent.getSelector();
                comp = intent.getComponent();
            }
        }

        flags = updateFlagsForResolve(flags, userId, filterCallingUid, resolveForStart,
                comp != null || pkgName != null ,
                isImplicitImageCaptureIntentAndNotSetByDpcLocked(intent, userId, resolvedType,
                        flags));
        if (comp != null) {
            // 对指定了 ComponentName 的 Intent 查询
            return result;
        }

        // reader
        boolean sortResult = false;
        boolean addInstant = false;
        List result;
        synchronized (mLock) {
            if (pkgName == null) {
                List matchingFilters =
                        getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);
                // 判断当前查询的应用是否跳过接下来配置文件
                ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,
                        resolvedType, flags, userId);
                if (xpResolveInfo != null) {
                    List xpResult = new ArrayList<>(1);
                    xpResult.add(xpResolveInfo);
                    return applyPostResolutionFilter(
                            filterIfNotSystemUser(xpResult, userId), instantAppPkgName,
                            allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);
                }

                // 判断当前用户是否是系统用户
                result = filterIfNotSystemUser(mComponentResolver.queryActivities(
                        intent, resolvedType, flags, userId), userId);
                addInstant = isInstantAppResolutionAllowed(intent, result, userId,
                        false );
                // Check for cross profile results.
                boolean hasNonNegativePriorityResult = hasNonNegativePriority(result);
                xpResolveInfo = queryCrossProfileIntents(
                        matchingFilters, intent, resolvedType, flags, userId,
                        hasNonNegativePriorityResult);
                if (xpResolveInfo != null && isUserEnabled(xpResolveInfo.targetUserId)) {
                    boolean isVisibleToUser = filterIfNotSystemUser(
                            Collections.singletonList(xpResolveInfo), userId).size() > 0;
                    if (isVisibleToUser) {
                        result.add(xpResolveInfo);
                        sortResult = true;
                    }
                }
                if (intent.hasWebURI()) {
                    // 设置 weburi 的部分
                }
            } else {
                // 设置了pkgName 的intent查询方式
            }
        }
        ... ...
        // 进行过滤操作
        return applyPostResolutionFilter(
                result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
                userId, intent);
    }

queryIntentActivitiesInternal 中初步对调用的应用做了判断,最后调用 applyPostResolutionFilter 对进行进一步判断,在 applyPostResolutionFilter 方法中,一般的APP都是通过 !mAppsFilter.shouldFilterApplication( filterCallingUid, callingSetting, resolvedSetting, userId) 进行判断是否需要过滤删除查询到的 ResolveInfo 

AppsFilter -> shouldFilterApplication

方法中通过对 uid、sharedUserId 数据判断,进行过滤,按照系统默认规则:非 systemUid 应用只能获取到 systemUid 应用、静态库等模块中的 ResolveInfo。开启查询 pkg Feature 或者添加如下权限可以查询获取到全部模块中匹配项。 

android.permission.QUERY_ALL_PACKAGES

这里已经安装应用 uid 等信息都是保存在 /data/system/packages.xml 。系统的 PkgSetting 类就是获取这里内容,debug时候可以手动导出来查看下相关内容。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/343520.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号