当前位置: 首页 > article >正文

android 通过action启动Activity拦截,Activity应用组件添加intent-filter priority(优先级)不生效

1. 项目背景
android 通过action启动Activity拦截,Activity应用组件添加intent-filter priority(优先级)不生效。

【前置条件】1.电源模式D1

【操作步骤】1.打开搜狐App的八方电台点击进行麦克风授权

【预期结果】1.正常跳转到车机定制的系统设置

【实际结果】1.跳转到Android原生设置页面

【发生概率】5/5

2. 分析过程

搜狐用的是安卓标准跳转方法
系统的应用程序设置页 ACTION_APPLICATION_DETAILS_SETTINGS = “android.settings.APPLICATION_DETAILS_SETTINGS”;

很明显是车机定制的设置App没有接收这个action,只有原生的设置接收这个action,所以导致跳转错误。

通过命令:adb shell dumpsys package > package.log
可以很清晰的看到,确实接收这个action的只有一个activity。
在这里插入图片描述

在 Activity 的 intent-filter 中,android:priority 主要影响 隐式 Intent 的匹配优先级。
当多个 Activity 声明了相同的 intent-filter 时,优先级 (priority) 较高的 Activity 更有可能被系统选中。

  • android:priority 仅影响隐式 Intent(Implicit Intent),不影响显式 Intent(Explicit Intent)。
  • android:priority 取值范围为 -1000 到 1000。
  • 默认值为 0,即如果未设置 android:priority,默认是 0。

在这里插入图片描述
根据资料,我们进行如下方式修改:
在这里插入图片描述

修改完之后,通过adb install的方式,替换apk之后,发现并不能实现activity跳转拦截,dump如下:
在这里插入图片描述
通过上面的dump可以看出来,adb install替换app的方式,PMS里面的控件已经发生了变化,但是为什么功能却不生效呢?通过跟踪priority的代码可知,intent-filter的priority会通过IntentFilter.setPriority进行修改,详情

    /**
     * Modify priority of this filter.  This only affects receiver filters.
     * The priority of activity filters are set in XML and cannot be changed
     * programmatically. The default priority is 0. Positive values will be
     * before the default, lower values will be after it. Applications should
     * use a value that is larger than {@link #SYSTEM_LOW_PRIORITY} and
     * smaller than {@link #SYSTEM_HIGH_PRIORITY} .
     *
     * @param priority The new priority value.
     *
     * @see #getPriority
     * @see #SYSTEM_LOW_PRIORITY
     * @see #SYSTEM_HIGH_PRIORITY
     */
    public final void setPriority(int priority) {
        Log.w(TAG, "setPriority, this =" + this + ", priority = " + priority);
        for (String action : mActions) {
            Log.w(TAG, "-----setPriority, this =" + this + ", priority = " + priority + ", action = " + action);
            if (action != null && action.contains("APPLICATION_DETAILS_SETTINGS")) {
                Log.w(TAG, "setPriority, this =" + this + ", callstack = ", new Throwable("xxx"));
            }
        }
        mPriority = priority;
    }
01-01 12:32:56.797  1702  1755 W IntentFilter: -----setPriority, this =android.content.IntentFilter@94037f2, priority = 0, action = android.settings.APPLICATION_DETAILS_SETTINGS
01-01 12:32:56.797  1702  1755 W IntentFilter: setPriority, this =android.content.IntentFilter@94037f2, callstack = 
01-01 12:32:56.797  1702  1755 W IntentFilter: java.lang.Throwable: xxx
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at android.content.IntentFilter.setPriority(IntentFilter.java:534)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.resolution.ComponentResolver.adjustPriority(ComponentResolver.java:630)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.resolution.ComponentResolver.addAllComponents(ComponentResolver.java:209)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallPackageHelper.commitPackageSettings(InstallPackageHelper.java:506)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallPackageHelper.commitReconciledScanResultLocked(InstallPackageHelper.java:402)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallPackageHelper.commitPackagesLocked(InstallPackageHelper.java:2020)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallPackageHelper.installPackagesLI(InstallPackageHelper.java:1037)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallPackageHelper.installPackagesTracedLI(InstallPackageHelper.java:921)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallPackageHelper.processInstallRequests(InstallPackageHelper.java:861)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallParams.lambda$processInstallRequestsAsync$0$com-android-server-pm-InstallParams(InstallParams.java:442)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.pm.InstallParams$$ExternalSyntheticLambda0.run(Unknown Source:6)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at android.os.Handler.handleCallback(Handler.java:942)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at android.os.Handler.dispatchMessage(Handler.java:99)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at android.os.Looper.loopOnce(Looper.java:201)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at android.os.Looper.loop(Looper.java:288)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at android.os.HandlerThread.run(HandlerThread.java:67)
01-01 12:32:56.797  1702  1755 W IntentFilter: 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

通过堆栈信息,可知在install app的时候,会走进adjustPriority进行优先级的调整,并将priority设置成0,所以出现上述的不生效的情况。

 /**
     * Adjusts the priority of the given intent filter according to policy.
     * <p>
     * <ul>
     * <li>The priority for non privileged applications is capped to '0'</li>
     * <li>The priority for protected actions on privileged applications is capped to '0'</li>
     * <li>The priority for unbundled updates to privileged applications is capped to the
     *      priority defined on the system partition</li>
     * </ul>
     * <p>
     * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
     * allowed to obtain any priority on any action.
     */
    private void adjustPriority(@NonNull Computer computer, List<ParsedActivity> systemActivities,
            ParsedActivity activity, ParsedIntentInfo intentInfo, String setupWizardPackage) {
        // nothing to do; priority is fine as-is
        IntentFilter intentFilter = intentInfo.getIntentFilter();
        if (intentFilter.getPriority() <= 0) {
            return;
        }

        String packageName = activity.getPackageName();
        AndroidPackage pkg = computer.getPackage(packageName);

        final boolean privilegedApp = pkg.isPrivileged();
        String className = activity.getClassName();
        if (!privilegedApp) {
            // non-privileged applications can never define a priority >0
            if (DEBUG_FILTERS) {
                Slog.i(TAG, "Non-privileged app; cap priority to 0;"
                        + " package: " + packageName
                        + " activity: " + className
                        + " origPrio: " + intentFilter.getPriority());
            }
            intentFilter.setPriority(0);
            return;
        }

        if (isProtectedAction(intentFilter)) {
            if (mDeferProtectedFilters) {
                // We can't deal with these just yet. No component should ever obtain a
                // >0 priority for a protected actions, with ONE exception -- the setup
                // wizard. The setup wizard, however, cannot be known until we're able to
                // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do
                // until all intent filters have been processed. Chicken, meet egg.
                // Let the filter temporarily have a high priority and rectify the
                // priorities after all system packages have been scanned.
                if (mProtectedFilters == null) {
                    mProtectedFilters = new ArrayList<>();
                }
                mProtectedFilters.add(Pair.create(activity, intentInfo));
                if (DEBUG_FILTERS) {
                    Slog.i(TAG, "Protected action; save for later;"
                            + " package: " + packageName
                            + " activity: " + className
                            + " origPrio: " + intentFilter.getPriority());
                }
            } else {
                if (DEBUG_FILTERS && setupWizardPackage == null) {
                    Slog.i(TAG, "No setup wizard;"
                            + " All protected intents capped to priority 0");
                }
                if (packageName.equals(setupWizardPackage)) {
                    if (DEBUG_FILTERS) {
                        Slog.i(TAG, "Found setup wizard;"
                                + " allow priority " + intentFilter.getPriority() + ";"
                                + " package: " + packageName
                                + " activity: " + className
                                + " priority: " + intentFilter.getPriority());
                    }
                    // setup wizard gets whatever it wants
                    return;
                }
                if (DEBUG_FILTERS) {
                    Slog.i(TAG, "Protected action; cap priority to 0;"
                            + " package: " + packageName
                            + " activity: " + className
                            + " origPrio: " + intentFilter.getPriority());
                }
                intentFilter.setPriority(0);
            }
            return;
        }

        if (systemActivities == null) {
            // the system package is not disabled; we're parsing the system partition

            // privileged apps on the system image get whatever priority they request
            return;
        }

        // privileged app unbundled update ... try to find the same activity

        ParsedActivity foundActivity = findMatchingActivity(systemActivities, activity);
        if (foundActivity == null) {
            // this is a new activity; it cannot obtain >0 priority
            if (DEBUG_FILTERS) {
                Slog.i(TAG, "New activity; cap priority to 0;"
                        + " package: " + packageName
                        + " activity: " + className
                        + " origPrio: " + intentFilter.getPriority());
            }
            intentFilter.setPriority(0);
            return;
        }

        // found activity, now check for filter equivalence

        // a shallow copy is enough; we modify the list, not its contents
        final List<ParsedIntentInfo> intentListCopy =
                new ArrayList<>(foundActivity.getIntents());

        // find matching action subsets
        final Iterator<String> actionsIterator = intentFilter.actionsIterator();
        if (actionsIterator != null) {
            getIntentListSubset(intentListCopy, IntentFilter::actionsIterator, actionsIterator);
            if (intentListCopy.size() == 0) {
                // no more intents to match; we're not equivalent
                if (DEBUG_FILTERS) {
                    Slog.i(TAG, "Mismatched action; cap priority to 0;"
                            + " package: " + packageName
                            + " activity: " + className
                            + " origPrio: " + intentFilter.getPriority());
                }
                intentFilter.setPriority(0);
                return;
            }
        }

        // find matching category subsets
        final Iterator<String> categoriesIterator = intentFilter.categoriesIterator();
        if (categoriesIterator != null) {
            getIntentListSubset(intentListCopy, IntentFilter::categoriesIterator,
                    categoriesIterator);
            if (intentListCopy.size() == 0) {
                // no more intents to match; we're not equivalent
                if (DEBUG_FILTERS) {
                    Slog.i(TAG, "Mismatched category; cap priority to 0;"
                            + " package: " + packageName
                            + " activity: " + className
                            + " origPrio: " + intentFilter.getPriority());
                }
                intentFilter.setPriority(0);
                return;
            }
        }

        // find matching schemes subsets
        final Iterator<String> schemesIterator = intentFilter.schemesIterator();
        if (schemesIterator != null) {
            getIntentListSubset(intentListCopy, IntentFilter::schemesIterator, schemesIterator);
            if (intentListCopy.size() == 0) {
                // no more intents to match; we're not equivalent
                if (DEBUG_FILTERS) {
                    Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
                            + " package: " + packageName
                            + " activity: " + className
                            + " origPrio: " + intentFilter.getPriority());
                }
                intentFilter.setPriority(0);
                return;
            }
        }

        // find matching authorities subsets
        final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator =
                intentFilter.authoritiesIterator();
        if (authoritiesIterator != null) {
            getIntentListSubset(intentListCopy, IntentFilter::authoritiesIterator,
                    authoritiesIterator);
            if (intentListCopy.size() == 0) {
                // no more intents to match; we're not equivalent
                if (DEBUG_FILTERS) {
                    Slog.i(TAG, "Mismatched authority; cap priority to 0;"
                            + " package: " + packageName
                            + " activity: " + className
                            + " origPrio: " + intentFilter.getPriority());
                }
                intentFilter.setPriority(0);
                return;
            }
        }

        // we found matching filter(s); app gets the max priority of all intents
        int cappedPriority = 0;
        for (int i = intentListCopy.size() - 1; i >= 0; --i) {
            cappedPriority = Math.max(cappedPriority,
                    intentListCopy.get(i).getIntentFilter().getPriority());
        }
        if (intentFilter.getPriority() > cappedPriority) {
            if (DEBUG_FILTERS) {
                Slog.i(TAG, "Found matching filter(s);"
                        + " cap priority to " + cappedPriority + ";"
                        + " package: " + packageName
                        + " activity: " + className
                        + " origPrio: " + intentFilter.getPriority());
            }
            intentFilter.setPriority(cappedPriority);
            return;
        }
        // all this for nothing; the requested priority was <= what was on the system
    }

通过代码可知,以下几种情况不生效:

  • 内置到/system/app 不生效
  • 手动安装方式新增action的情况不生效

最后通过push的方式替换apk,验证OK,问题解决。

3. 修改方案以及注意事项

测试过的几种上不生效的情况

  • 内置到/system/app 不生效
  • 手动安装方式新增action的情况不生效

http://www.kler.cn/a/588108.html

相关文章:

  • AF3 make_pseudo_beta函数解读
  • 【菜鸟飞】Conda安装部署与vscode的结合使用
  • 技术解析:基于AI+云计算的智能呼叫中心系统如何重构零售行业服务生态?
  • 数据结构与算法-图论-欧拉路径和欧拉回路(有向图和无向图,骑马修栅栏,单词游戏 play on words)详细代码注解
  • 实践 PyTorch 手写数字识别
  • 查看debian的版本信息
  • Linux系统下如何部署svmspro平台
  • vue3系列:vite+vue3怎么配置通过ip和端口打开浏览器
  • 设计模式,持续更新
  • 数据结构------线性表
  • EDAS:投稿经验-word版本-问题解决
  • C语言_数据结构总结9:树的基础知识介绍
  • 51单片机的工作方式
  • 直方图梯度提升:大数据时代的极速决策引擎
  • Windows编译Flash-attention模块
  • 于 Hexo + GitHub Pages 的搭建个人博客网站的详细教程
  • 失败的面试经历(ʘ̥∧ʘ̥)
  • 如何利用物理按键控制LVGL控件的大小与状态
  • 六十天前端强化训练之第二十天React Router 基础详解
  • python-数据类型字符串和列表