Android系统去掉长按webview界面弹框中的分享功能

提示: 最近有个客户自己做了WebView 加载HTML的网页,长按WebView 网页后显示了菜单选项,其中一个就是分享功能。让把它去掉,后面又让把所有的分析菜单去掉


前言

一、需求

Android 系统去解决长按显示内容,去掉分享功能,不论那个界面,是所有界面都需要满足。

需求:

  • 如果仅仅去掉系统自带的,那么系统来处理
  • 如果客户自定义,部分App 自定义的菜单项,不是调用系统的,那么还是需要应用去解决的。
  • 之前做过Editext,其实还需要去 TextView,最难点的就是WebView 中的HTML了 去分享功能了。

如下:WebView 中涉及到分享功能菜单的界面,

在这里插入图片描述

在这里插入图片描述

二、参考文档

自己之前的笔记
RK-3576-Android15屏蔽EditText的长按分享菜单的功能 涉及到另外一个组件TextView 的屏蔽 功能,和Editext 修改方案一模一样。

其它参考资料比较有建设性,但是要付费: 参考下,然后自己分析下代码实现呗,但是千万不要相信别人的建议,实际效果都需要自己不断查阅资料、定位源码、分析源码、反复实践调试 才行。

Android 10.0 framework去掉长按webview界面弹框中的 打开 字符串
Android 14.0 framework去掉长按webview界面弹框中的打开字符串

三、修改文件

frameworks/base/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbar.java

四、效果演示

在这里插入图片描述
在这里插入图片描述

五、实现方案

实现方案

frameworks/base/core/java/com/android/internal/widget/floatingtoolbar/FloatingToolbar.java 中的getVisibleAndEnabledMenuItems 方法中,过滤掉分享菜单即可。

实际代码改成如下:

   /**
     * Returns the visible and enabled menu items in the specified menu.
     * This method is recursive.
     */
    private static List<MenuItem> getVisibleAndEnabledMenuItems(Menu menu) {
        Log.d(TAG,"==========getVisibleAndEnabledMenuItems==========");
        List<MenuItem> menuItems = new ArrayList<>();
        for (int i = 0; (menu != null) && (i < menu.size()); i++) {
            MenuItem menuItem = menu.getItem(i);
            if (menuItem.isVisible() && menuItem.isEnabled()) {
                Menu subMenu = menuItem.getSubMenu();
                if (subMenu != null) {
                    Log.d(TAG,"=====menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu))=======");
                    menuItems.addAll(getVisibleAndEnabledMenuItems(subMenu));
                } else {
                    Log.d(TAG,"==========getVisibleAndEnabledMenuItems=== menuItems.add(menuItem)======="+menuItem.getTitle()+"  "+menuItem.getTooltipText());
					
					if(menuItem.getTitle().equals(mTWindow.getContext().getResources().getString(com.android.internal.R.string.share))){
						 Log.d(TAG,"==========now is share not add menuItem====");
						continue;
					}
                    menuItems.add(menuItem);
                }
            }
        }
        return menuItems;
    }

在这里插入图片描述

实现思路推荐

  • dumsys 堆栈打印,查找难找的组件信息 dumpsys window
  • 查找share 相关的ID、字符串信息
  • 通过 \frameworks\base\core\res\res 中的values ,查找关键字,反向grep 查找
  • 网上多看看资料吧 FloatingToolbar
    在这里插入图片描述

六、代码跟踪

1、找到浮动组件-frameworks/base/core/java/com/android/internal/widget/floatingtoolbar

相关说明:

  • RK-3576-Android15屏蔽EditText的长按分享菜单的功能 笔记中 有了解过,系统的基本组件都在 frameworks/base/core/java/com/android/internal/widget 目录下 所以我们最开始的思路 就应该在这个包名下面找对应的基本组件,但是我们遇到第一个问题,没法像之前那样 通过 关键字段、关键方法 搜索到对应相关信息。
  • 大家看实际效果,是不是很像poppupwindows,实际打印堆栈信息,真的好多Windows 相关的信息,floatingtoolbar 就是一个浮动组件,实现了这个菜单功能。

在这里插入图片描述

2、floatingtoolbar 包下类架构分析

当我分析到这里的时候,我就感觉找到位置了,分析代码,然后更改即可实现需求
在这里插入图片描述

FloatingToolbarPopup 定义接口

/**
 * A popup window used by the {@link FloatingToolbar} to render menu items.
 *
 */
public interface FloatingToolbarPopup {

    /**
     * Sets the suggested dp width of this floating toolbar.
     * The actual width will be about this size but there are no guarantees that it will be exactly
     * the suggested width.
     */
    void setSuggestedWidth(int suggestedWidth);

    /**
     * Sets if the floating toolbar width changed.
     */
    void setWidthChanged(boolean widthChanged);

    /**
     * Shows this popup at the specified coordinates.
     * The specified coordinates may be adjusted to make sure the popup is entirely on-screen.
     */
    void show(List<MenuItem> menuItems, MenuItem.OnMenuItemClickListener menuItemClickListener,
            Rect contentRect);

    /**
     * Gets rid of this popup. If the popup isn't currently showing, this will be a no-op.
     */
    void dismiss();

    /**
     * Hides this popup. This is a no-op if this popup is not showing.
     * Use {@link #isHidden()} to distinguish between a hidden and a dismissed popup.
     */
    void hide();

    /**
     * Returns {@code true} if this popup is currently showing. {@code false} otherwise.
     */
    boolean isShowing();

    /**
     * Returns {@code true} if this popup is currently hidden. {@code false} otherwise.
     */
    boolean isHidden();

    /**
     * Makes this toolbar "outside touchable" and sets the onDismissListener.
     *
     * @param outsideTouchable if true, the popup will be made "outside touchable" and
     *      "non focusable". The reverse will happen if false.
     * @param onDismiss
     *
     * @return true if the "outsideTouchable" setting was modified. Otherwise returns false
     *
     * @see PopupWindow#setOutsideTouchable(boolean)
     * @see PopupWindow#setFocusable(boolean)
     * @see PopupWindow.OnDismissListener
     */
    boolean setOutsideTouchable(boolean outsideTouchable,
            @Nullable PopupWindow.OnDismissListener onDismiss);

    /**
     * Returns {@link LocalFloatingToolbarPopup} implementation.
     */
    static FloatingToolbarPopup createInstance(Context context, View parent) {
        return new LocalFloatingToolbarPopup(context, parent);
    }

}

FloatingToolbar 水平包裹的工具类-负责展示menu items

/**
 * A floating toolbar for showing contextual menu items.
 * This view shows as many menu item buttons as can fit in the horizontal toolbar and the
 * the remaining menu items in a vertical overflow view when the overflow button is clicked.
 * The horizontal toolbar morphs into the vertical overflow view.
 */
public final class FloatingToolbar {

LocalFloatingToolbarPopup 负责实际 popup window的工具类-对用户展示

/**
 * A popup window used by the floating toolbar to render menu items in the local app process.
 *
 * This class is responsible for the rendering/animation of the floating toolbar.
 * It holds 2 panels (i.e. main panel and overflow panel) and an overflow button
 * to transition between panels.
 */
public final class LocalFloatingToolbarPopup implements FloatingToolbarPopup {

3 、FloatingToolbar 源码分析

先观察类的一些方法,有个直观感受,然后打印日志,方便查找问题。
在这里插入图片描述

查看 doShow getVisibleAndEnabledMenuItems 方法如下

所以去打印部分信息
在这里插入图片描述

查看日志打印

进一步验证了,就是在这里添加的,那么过滤掉就可以了
在这里插入图片描述

在这里插入图片描述

4 、 查找资源文件-过滤操作

这里有两部分工作

  • 查找资源文件 分享的字符串 表示
  • 字符串在Framework中的获取,来实现匹配 过滤操作
    -
java/android/widget/TextView.java:14238:                        getResources().getString(com.android.internal.R.string.share)));
java/android/widget/Editor.java:3314:                                com.android.internal.R.string.share)
java/android/widget/Editor.java:3372:                            com.android.internal.R.string.share)
java/android/widget/Editor.java:4776:                        com.android.internal.R.string.share)
java/android/widget/ShareActionProvider.java:179:                R.string.shareactionprovider_share_with_application);
java/android/widget/ShareActionProvider.java:181:                R.string.shareactionprovider_share_with);

但是 我们匹配的是字符串,所有要不 字符串id 转字符串表示,然后匹配再过滤。

总结

  • 遇到难找的界面、难找的组件、难定位的UI 直接dumpsys 堆栈找找看
  • 多分析应该在哪里找源码、然后多查阅资料
  • grep 查找、关键字查找、找关键信息
  • 实实在在多看看源码、并实际调试吧
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

野火少年

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值