Samsung Browser 增强模块(LSPosed 模块)。
以 LSPosed 为运行框架,为三星浏览器(Samsung Internet,包名 com.sec.android.app.sbrowser)
补充官方未提供的功能。
A LSPosed module that enhances Samsung Internet Browser (package com.sec.android.app.sbrowser) with features not provided officially.
- Download Bridge — forward downloads to a third-party manager (ADM / IDM+ / 1DM, customizable package), passing Cookie / UA / Referer; optionally block the native download.
- Settings Integration + Logging — inject an SBPlus submenu into browser settings, with a built-in log viewer.
- Via-style Grid Menu — turn the "More" menu into a multi-column grid, drag-to-reorder, add/remove icons.
- Region Switch — switch the browser region to one of 17 countries.
- UA Spoofing — fully replace the User-Agent (Desktop Chrome / Mobile / iPhone / custom).
- Streamlined Settings — master switch + multi-select hiding for unneeded items.
- Block Updates & Red Dots — block browser updates, clear update notifications / popups / red dots.
- Homepage Video Background — play a video on the homepage (loop, muted).
- Userscript Manager — full built-in manager: list / add / save / delete / toggle,
.user.jsinterception, source management, "update all", lightweight GM API, detail page + share import. - Bookmark Management — import / export bookmarks (Chrome / Edge / Firefox HTML format), tree checkbox dialog.
- Random UA — 55 real UA strings with random rotation; supports platform/browser multi-select and custom parameters.
- Media Sniffer & Download Engine — multi-threaded download engine for m3u8/TVOD streams; sniff and download video/audio/image resources with tab-based select-all (video/audio/image independent). Built-in site parsers for Bilibili DASH (auto-pair video+audio into single MP4, 4K/1080P+/HDR), Douyin / Kuaishou / Xiaohongshu / Weibo / AcFun / Toutiao (SSR JSON extraction via script tag), and global platforms YouTube (itag resolution), TikTok, X/Twitter, Instagram/Facebook (performance CDN). Segmented video (m4s/ts) auto-remux to MP4 — instant, no transcoding bloat. Task progress bar, speed display, cancel support, configurable concurrency.
- Homepage Beautification — personalize the homepage search box and other elements.
- Version + Project URL + Auto Update Check — version and project URL shown in module home and browser menu, with auto update checking.
- Rooted device with LSPosed installed (via Magisk).
- Install the module APK, then enable it in LSPosed Manager.
- Set scope to Samsung Internet (
com.sec.android.app.sbrowser) or Beta (com.sec.android.app.sbrowser.beta). - Restart the browser (or device).
call <path-to-android-sdk>/env.bat
gradle assembleDebug --no-daemonOutput: app\build\outputs\apk\debug\app-debug.apk
The module resolves Samsung's obfuscated / version-dependent class and method names at runtime, instead of hardcoding them:
- Dynamic parent resolution — obtains the parent (obfuscated androidx class) of
PreferenceFragmentCustomat launch, so it adapts to whichever obfuscation name the browser version uses. - Multi-candidate method fallback — for obfuscated methods (e.g.
PreferenceManager'screatePreferenceScreen), tries candidate names in order, standard first then obfuscated names. - Isolated error handling — each hook is independently guarded; a failure in one does not break others or the browser itself.
Re-resolution happens on every browser start, so after a browser update the module adapts automatically without a module update.
- 目标框架:LSPosed(接口兼容标准 Xposed API)
- 模块入口:
assets/xposed_init→com.sbplus.browser.MainHook - 兼容:LSPosed 可加载,老 Xposed / EdXposed 理论上也可加载
- 手机已 root,并安装 LSPosed(Magisk 模块方式)
- 安装本模块 APK 后,打开 LSPosed Manager:
- 启用本模块
- 作用域(Scope)勾选「三星浏览器」(
com.sec.android.app.sbrowser)
- 重启三星浏览器(或重启系统)
作用域需要时可在 LSPosed 界面手动勾选。
把三星浏览器的下载请求转交给第三方下载器(ADM / IDM+ / 1DM,包名可自定义)。
- hook
TinDownloadController下载链路(onDownloadStarted等) - 传递 Cookie / User-Agent / Referer 等登录态信息
- 可选阻断原生下载(真正"接管"而非并行)
在三星浏览器设置页注入 SBPlus 子菜单,并提供内置日志查看。
把三星「更多」菜单从单列纵向列表改造成多列网格(Via 风格),支持拖拽排序、 添加/删除图标。
通过 hook CountryUtil.getCountryIsoCode() 等入口,将浏览器地区切换到 17 国之一,
影响所有区域相关行为。
hook SBrowserCommandLine.initialize(),通过 TerraceCommandLine.appendSwitchWithValue
注入 user-agent switch,完整替换 UA(桌面 Chrome / 手机 / iPhone / 自定义)。需重启浏览器生效。
主开关 + 23 项多选屏蔽,两列网格展示,隐藏不需要的设置项。
独立总开关,彻底屏蔽浏览器更新:
- 清除更新通知 / 弹窗 / 红点(关于页、更多按钮、设置徽标)
- 阻断更新检查链路(
UpdateManager.checkUpdate*) - 阻断商店网络(
StubUtil.checkUpdateOnGalaxyStore等) - 禁止跳转商店 / 升档
- 通过官方预留
disable-update-dialogswitch 优雅屏蔽弹窗
让浏览器主页(新标签页/快速访问页)背景播放动态视频。
- 通过 MediaStore 将选中视频存入公共
Movies/SBPlus/目录 - 用
TextureView + MediaPlayer循环静音播放(TextureView 规避 SurfaceView 被不透明背景色盖住的问题) - 子页提供「选择视频 / 清除视频 / 删除视频」三个操作
完整的内置油猴脚本管理器:
- 脚本列表 / 添加 / 保存 / 删除 / 开关(开关在前、名字在后)
- 拦截
.user.js下载引导安装 - 支持源管理(
@updateURL/@downloadURL)、「更新所有脚本」 - 内置精简版 GM API(
GM_setValue/GM_getValue/GM_registerMenuCommand等) - 脚本详情页 + 分享导入
- 导入 / 导出书签(Chrome / Edge / Firefox 通用 HTML 格式)
- 树形勾选对话框(可选导入/导出指定节点)
内置 55 条真实 UA 池,支持随机轮换(桌面 Chrome / 手机 / iPhone / 自定义)。支持平台/浏览器多选和自定义参数动态生成。
多线程下载引擎(m3u8/TVOD 流式),按类型分tab显示(视频/音频/图片独立全选)。
- B站 DASH 自动合并:视频+音频流自动配对合并为单 MP4(4K/1080P+/HDR,大会员全清晰度)
- 国内站点解析器:抖音 / 快手 / 小红书 / 微博 / AcFun / 头条(script 标签 SSR JSON 提取)
- 国外平台支持:YouTube(itag 清晰度标注)、TikTok、X/Twitter、Instagram/Facebook
- 分片视频(m4s/ts)自动纯 remux 转 MP4(秒级完成,不膨胀)
- 任务进度条 / 速度显示 / 取消支持 / 并发数可配置
- 下载后自动转 MP4 开关(默认开)
- 图片格子选中显示蓝色遮罩
主页搜索框等页面元素的个性化设置。
- SBPlus 应用首页与浏览器 SBPlus 菜单里都显示版本号 + 项目地址
- 启动/进入页面时自动检测 GitHub 最新 release,有新版本在版本号后提示「点击更新」,点击后确认下载 apk
call <path-to-android-sdk>\env.bat
gradle assembleDebug --no-daemon产物:app\build\outputs\apk\debug\app-debug.apk
模块对三星浏览器内部被混淆/随版本变化的类名与方法名做了运行时自适应解析,而非硬编码:
- 动态父类解析:通过明文类
PreferenceFragmentCustom动态获取其父类(androidx 混淆类), 无论浏览器版本把混淆名改成H2.A还是其他,都能自动找到。 - 多候选方法回退:对被混淆的方法(如
PreferenceManager的createPreferenceScreen) 按候选名列表依次尝试,标准名优先、混淆名兜底。 - 独立容错:每个 hook 点单独保护,单个失败不影响其他功能,也不影响浏览器自身。
浏览器每次启动时都会重新解析适配,浏览器更新后无需模块更新即可自动适配新版本。
- 主页 Logo / 时钟启动抖动修复:
QuickAccessMainLayout的onFinishInflate(+400ms) 与onAttachedToWindow(+500ms) 原先各调一次refreshHomeLogoSection()/refreshHomeClock(),而这两个方法会清掉配置指纹并 先移除再重建覆盖层——等于自己绕过了幂等短路,冷启动会连续重建三次。 改为调attachHomeLogo/attachHomeClock:配置未变则指纹短路直接返回, 只有设置真的变更才重建。冷启动重建次数 3 → 1。 - 跟随搜索框逻辑改为绝对锚点:原实现每帧把搜索框位移量累加到
translationY,丢帧或基准重置都会漂移且无法自愈; 现在记一次基准位置,之后每帧translationY = 当前位置 - 基准,漏帧也会回正。 - 账户头像与「添加快捷方式」不再被主题色渲染:新增
NEVER_TINT_IDS(account/news_feed_tab_add_button(_icon)/add_view_container/add_item_icon),并向上检查最多 4 层父容器 id——因为「添加」格子内部的 ImageView id 只是通用的icon,仅靠自身 id 无法识别。 模块自己插入的「添加快捷方式」ImageButton 没有资源 id,改用TAG_NO_TINT标记排除。四条着色路径(ensureIconTint/tintHomeIcon/applyToolbarIconTint/forceApplyAllToolbarIcons)同时生效。 - 移除网页字体注入功能:连同
WebFontServer(本地回环 HTTP 字体服务)与FontHelper的 base64 缓存一并删除,浏览器进程不再开监听端口。 技术上可以注入(实测document.fonts.status=loaded,9MB 字体被内核完整拉取), 但无法稳定覆盖网页正文——站点自身 CSS 与内核字体回退会吃掉!important, 多数页面复查为未生效。半生效状态不如不留。模块自身 UI 字体不受影响。 - 清理死代码:
tintAddButtonPlus/getAllFields/dumpVectorNode。
关于 LSPosed 作用域列表:本模块
xposedscope声明的两个包只是推荐, LSPosed 会把它们排在前面并支持「选择推荐应用」,但其它应用仍会列出。 想让列表只显示这两个包(staticScope=true)必须改用 LSPosed 新版模块格式META-INF/xposed/(module.prop+scope.list+java_init.list), 而该格式只对 libxposed 新 API 模块生效——实测加入三件套后 LSPosed 报ClassNotFoundException: com.sbplus.browser.MainHook,因为java_init.list指向的类需实现io.github.libxposed.XposedModule,而本模块基于旧的de.robv.android.xposed.IXposedHookLoadPackage。迁移等于重写全部 hook 注册与 反射辅助调用,代价远超收益,故继续使用旧格式。
- Windows AMD64
- Java 17(Temurin)
- Gradle 8.7
- Android SDK 34+
- 依赖仓库:阿里云镜像(解决国内拉取 AGP 依赖超时问题)
- 测试设备:三星 Galaxy(Android 16 / SDK 36)
SBPlus/
├── app/
│ ├── build.gradle (namespace/applicationId = com.sbplus.browser)
│ └── src/main/
│ ├── AndroidManifest.xml (xposedmodule 声明)
│ ├── assets/xposed_init (模块入口)
│ ├── res/values/ (app_name=SBPlus, xposedscope)
│ └── java/com/sbplus/browser/
│ ├── MainHook.java (核心 hook,功能 1-13)
│ ├── MainActivity.java (模块首页/版本号/更新检测)
│ ├── UpdateChecker.java (GitHub 最新版本查询)
│ ├── MenuReorderHelper.java (网格菜单拖拽排序)
│ ├── MenuAddButtonHelper.java (添加图标)
│ ├── MenuEditHelper.java (编辑图标)
│ ├── HomeLogoHelper.java (主页 Logo 偏好)
│ ├── HomeClockHelper.java (主页时钟偏好)
│ ├── FontHelper.java (模块 UI 自定义字体)
│ ├── ThemeColorHelper.java (主题色槽位)
│ ├── LogWriter.java / LogProvider.java / LogManagerActivity.java (日志系统)
│ └── ...
├── build.gradle
├── settings.gradle (rootProject.name=SBPlus)
└── gradle.properties