Storage Manager v1.0.5 产品功能与商业化分析
Storage Manager v1.0.5 产品功能与商业化分析返回竞品库
报告口径本页直接渲染本地报告真源;静态能力、动态观察、推断和线上未验证项不得互相替代。

Storage Manager v1.0.5 产品功能与商业化分析#

文档日期:2026-10-14
样本:com.sweepeeer.manager.ssstorage,APK 1.0.5 (7)。
S1=静态事实,D1=本轮真机事实,I=推断,U=未验证。

一、结论先行#

  1. 产品形态是“存储焦虑入口 + 工具矩阵”。 首屏先给出 RAM/存储诊断和 Clean Now,再进入包含清理、文件、应用、电池和压缩的首页;价值叙事围绕“发现问题—立即清理—继续探索工具”。(D1/S1)
  2. 核心能力并非都同等可信。 文件分类、用户确认删除、系统卸载和电池信息有 Android 能力支撑;RAM 百分比和“优化”更偏状态呈现,未发现能强制停止其他 App 的可靠证据。(S1/I/U)
  3. 广告存在明确的安装来源分流,而且会改变广告请求,不只是区分埋点。 代码把来源码 7 明确定义为 SOURCE_ORGANIC(自然量);插屏和原生广告均采用 referrer != 7 || data.isShow(),导致 isShow=false 只拦自然/默认组,非 7 识别来源仍会继续请求。(S1)
  4. “非 7”不能直接等同“付费推广用户”。 该组包含 Facebook、TikTok、Google、Kwai、Bigo,也包含 official/website/direct;反过来,未知 referrer、查询异常和超时都会落入 7。准确叫法应为“自然/默认组 7”与“非 7 已识别来源组”。(S1)
  5. 商业化是多节点全屏广告 + 结果页原生广告。 release 内置 24 个场景、19 个 isShow=true、5 个关闭;其中 first、junk_in、junk_no、home_native、guide 这 5 个关闭位对非 7 组并非真正关闭。(S1)
  6. 定向 simple-mode 反编译已恢复场景归一化。 junk→junk_in、manager_in→app_in、open_in→open_in_int、open_ou→open_ou_int 均能命中配置;此前疑似错配中,仅 uninstall_in 未见映射、仍会落到 Unknown。(S1)
  7. 本轮真机没有看到广告,但该设备不能代表全部来源组。 已走过首启、通知授权、诊断、拒绝 All Files Access、首页、Home 和最近任务划卡;未观察到广告或广告日志命中,也未构造非 7 referrer 做 A/B 对照。(D1/U)

二、产品入口与用户流程#

2.1 首启流程#

SplashFirstEmptyActivity → 通知权限 → 设备诊断/清理计划 → Clean Now → All Files Access 解释弹窗 → 垃圾清理或首页。

真机观察:

  • 首启先请求通知权限,而不是先解释清理价值。(D1)
  • 诊断页展示 74% / 2.7GB/3.5GB、存储 88.1GB/100GB、RAM 2GB/3GB 等值;这些数字可能混合系统读取、格式化和展示层估算,未做系统设置页逐项校准。(D1/U)
  • 标题出现 CheckingGenerating cleanup plan.,是明显的字符串拼接/状态文案缺陷。(D1)
  • 用户拒绝 All Files Access 后仍进入首页,核心清理受限,但其他工具仍可访问。(D1)

2.2 首页工具矩阵#

功能 页面/入口 能力说明 状态
Junk Clean(垃圾清理) AppJunkCleanerActivity → CleanActivity 分类展示 App Cache、APK、Residual Files 等候选,用户选择后进入清理 页面与扫描代码 S1;真实删除未做 D1
Large Files(大文件) ScanninActivity / LargeFilesActivity 扫描大照片、视频和其他大文件 S1;首页入口 D1
App Manager(应用管理/RAM) ScanninActivity → AppManageActivity 枚举应用、使用情况与后台概念;依赖 Usage Access S1/D1;强停能力 U
Battery Info(电池信息) ScanBatterActivity → BatteryInfoActivity 电量、健康、温度、电压、亮度等信息与扫描展示 S1/D1
文件分类 Image/Video/Audio/Docs/Zips/APK 进入 FileMagagerActivity,按类型浏览文件 S1/D1
Photo Compression(照片压缩) ScanninActivity → PhotoCompressionActivity / CompressionActivity 选择图片并压缩,显示压缩过程 S1/D1;质量/节省量 U
App Uninstall(应用卸载) ScanninActivity → AppUninstallActivity 枚举应用并转系统卸载确认,不是静默卸载 S1/D1
Settings(设置) SettingsActivity 通知开关、Feedback、Rate、Privacy Policy、User Agreement S1

页面组件清单见 jadx/resources/AndroidManifest.xml:115-210;真机首页见 evidence/main-more-tools.png。

2.3 垃圾分类#

一方扫描逻辑和绑定页面可确认至少包含:

  • App Cache(应用缓存);
  • APK Files(安装包);
  • Residual Files(卸载残留);
  • 广告/临时文件候选;
  • 浏览器、应用商店、社交、媒体、游戏与系统缓存/临时目录规则。

这些是“候选扫描规则”,不等于每一项都安全可删;本轮未授予 MANAGE_EXTERNAL_STORAGE,因此没有验证真实扫描量、误报率和删除效果。(S1/U)

2.4 文件管理#

FileMagagerActivity 及相关 Fragment/工具类包含文件搜索、选择、分享、复制/移动、重命名和删除调用迹象;部分页面大方法反编译失败,当前只能确认能力结构,不能保证每种文件类型和 Android 版本都可达。(S1/U)

2.5 设置与合规可见问题#

  • Privacy Policy URL 为 http://storagephonesweeper.com/privacy.html,使用明文 HTTP。(S1,SettingsActivity.java:34-36)
  • User Agreement 的 URL 是空字符串,点击后可能进入空白 WebView。(S1,SettingsActivity.java:38-41)
  • 权限中心将通知和所有文件访问都标为 Necessary Permissons,但通知主要用于常驻服务与建议/召回,不是文件浏览必需能力;权限解释可能造成合规和用户信任风险。(D1/I)

三、安装来源识别:自然量与非 7 来源如何划分#

3.1 来源码全表#

来源:utils/m1.java:13-19,69-95。

code 代码常量 Referrer 命中词 下游分组
1 SOURCE_FACEBOOK facebook、apps.instagram.com 非 7 已识别来源组
2 SOURCE_TIKTOK tt_cid、tiktok、tiktokglobal、E_C_P_C 非 7 已识别来源组
3 SOURCE_GOOGLE gclid 非 7 已识别来源组
4 SOURCE_KWAI kwai、kuaishou、_kwai_、_ks_ 非 7 已识别来源组
5 SOURCE_OFFICIAL official、website、direct、_official_、_site_ 非 7 已识别来源组
6 SOURCE_BINGO bigo 非 7 已识别来源组
7 SOURCE_ORGANIC organic、未知、空值、异常、超时 自然/默认组 7

因此,竞品代码真正执行的是二元判断 referrer == 7 / referrer != 7,而不是可靠的“自然用户/付费推广用户”判断。非 7 里混入了官网和 direct(直达)来源;7 里又混入查询失败与无法识别来源。(S1)

3.2 读取、重试与持久化链路#

定向使用 JADX simple mode(简单反编译模式)恢复 m1.qazws...() 后,链路可整理为:

var source = 7
repeat(3) { attempt ->
    val timeout = if (attempt == 0) 8.seconds else 5.seconds
    source = queryGooglePlayInstallReferrer(timeout)
    if (source != 7) return source
    if (attempt < 2) sleep(1.seconds)
}
return 7
  • 最多尝试 3 次:首次 8 秒,后两次各 5 秒,重试间隔 1 秒。(S1,定向 simple-mode 恢复)
  • 由于 7 同时代表真实 organic 和失败默认值,即使第一次已经正确拿到 organic,也仍可能继续重试。(S1)
  • 原始 referrer 写入 INSTALL_REFERRER;从 utm_content 开始的尾串另存 utmContent。(S1,m1.java:31-60)
  • SplashActivity 只在本地 REFERRER==0 时查询;成功与失败回调都会把返回码写入本地。之后只要该值非 0,启动时就不再查询。(S1,SplashActivity.java:435-469)

这意味着一次查询错误可能被持久化为 7,此后广告、通知和产品流程都会长期按自然/默认组执行,除非清数据、重装或代码另行覆盖。(S1/I)

3.3 解析缺陷#

代码先把 referrer 转成小写,再以大小写敏感方式检查大写字符串 E_C_P_C:

val source = raw.lowercase()
if (source.contains("E_C_P_C", ignoreCase = false)) return 2

单独依赖 E_C_P_C 的 TikTok 来源理论上无法命中;若同一串还包含 tt_cid/tiktok/tiktokglobal 则仍能归为 code 2。(S1/I)

四、广告分流核心代码#

4.1 插屏广告:非 7 组绕过 isShow=false#

标准 JADX 对 ad/g.java 的大方法反编译失败;本轮以 simple mode 定向恢复后,AdMob 与 TopOn 两条加载分支均为同一门禁。去除混淆后的等价代码如下:

val referrer = prefs.getInt(REFERRER, 7)
val data = adConfig[normalizedScene]?.data?.getOrNull(index) ?: return fail()

if (referrer == 7 && !data.isShow) {
    log("Ad not shown for organic users")
    return fail()
}

loadFromAdMobOrTopOn(data)

逻辑等价式是:

允许请求 = referrer != 7 OR data.isShow == true

因此 isShow=false 不是全局关闭,而是“只关闭自然/默认组 7”。只要场景配置仍存在,非 7 已识别来源组就会跳过该开关,继续进入缓存、点击上限、Provider 和广告请求判断。(S1)

4.2 Native 原生广告:相同门禁#

ad/j.java:128-157 的 Java 输出完整保留了同一判断:

if (getInt(REFERRER) != 7 || data.isShow()) {
    loadNative(scene, data);
    return;
}
log("not shown for organic users");
fail();

所以该分流同时作用于功能插屏和 Native 原生广告,不是单一广告位的特例。(S1)

4.3 五个默认关闭位的真实人群效果#

release scene 位置 isShow 自然/默认组 7 非 7 已识别来源组
first 首次启动插屏 false 跳过 可继续请求
junk_in App 内 Junk 入口插屏 false 跳过 可继续请求
junk_no 通知点击进入 Junk 插屏 false 跳过 可继续请求
home_native 首页 Native false 跳过 可继续请求
guide 首次引导节点插屏 false 跳过 可继续请求

“可继续请求”不等于必然展示:还会受场景是否存在、点击上限、缓存/展示锁、网络、广告填充、Consent(同意管理)与远端配置影响。(S1/U)

五、广告位置、场景归一化与展示链路#

5.1 两个独立维度不要混淆#

  • referrer==7/!=7:安装来源人群分组。
  • scene 后缀 _in/_no:进入方式分组;_in 是 App 内入口,_no 是 Notification Open(通知点击入口),不是“自然/非自然”。Firebase 常量也把 _no 定义为 EVENT_NOTIFICATION_OPEN。(S1)

此前把 junk_in 写成“自然入口”、把 junk_no 写成“非自然入口”不准确,本版已更正。

5.2 release 内置广告配置全表#

来源:jadx/resources/res/raw/ss_ad_config.json。

Scene 形式 平台 默认 产品位置/含义
first Interstitial(插屏) AdMob 关 首次启动/首引导前;仅 7 组被关
open_in App Open(开屏) AdMob 开 7 组普通后续启动
open_in_int Interstitial AdMob 开 非 7 组普通后续启动
open_ou App Open AdMob 开 App Open 的通知回流事件语义
open_ou_int Interstitial AdMob 开 非 7 组通知回流启动
junk_in Interstitial AdMob 关 App 内 Junk 入口;仅 7 组被关
app_in Interstitial AdMob 开 App 内应用管理入口
battery_in Interstitial AdMob 开 App 内电池工具入口
large_in Interstitial AdMob 开 App 内大文件入口
compress_in Interstitial AdMob 开 App 内照片压缩入口
junk_no Interstitial AdMob 关 通知点击 Junk;仅 7 组被关
app_no Interstitial AdMob 开 通知点击应用管理
battery_no Interstitial AdMob 开 通知点击电池工具
large_no Interstitial AdMob 开 通知点击大文件
compress_no Interstitial TopOn 开 通知点击照片压缩
junk_result_in Native(原生) AdMob 开 App 内 Junk 结果页
large_result_in Native AdMob 开 App 内大文件结果页
junk_result_no Native AdMob 开 通知点击 Junk 结果页
exit Native AdMob 开 退出确认弹窗
battery_result_in Native AdMob 开 App 内电池结果页
battery_result_no Native AdMob 开 通知点击电池结果页
home_native Native AdMob 关 首页原生广告;仅 7 组被关
guide Interstitial AdMob 关 首次引导完成节点;仅 7 组被关
file_manage Interstitial AdMob 开 文件管理入口

ss_ad_config_test.json 会把 first/junk/guide/home_native 等测试位打开,且把 compress_no 改为 AdMob;它是 test 资源,不能当作 release 默认策略。

5.3 插屏场景归一化#

simple-mode 恢复的 ad/g.b() 对页面 scene 做了显式别名转换:

页面传入 归一化键 命中 release 配置
first First → lowercase first
junk Junk_In → lowercase junk_in
junk_no Junk_No → lowercase junk_no
manager_in App_In → lowercase app_in
manager_no App_No → lowercase app_no
open_in Open_In_Int → lowercase open_in_int
open_ou Open_Ou_Int → lowercase open_ou_int
battery_in/no Battery_In/No → lowercase battery_in/no
large_in/no Large_In/No → lowercase large_in/no
compress_in/no Compress_In/No → lowercase compress_in/no
guide Guide → lowercase guide
file_manage File_Manage → lowercase file_manage
uninstall_in Unknown → lowercase 无 unknown 配置,仍未命中

因此,junk/junk_in、manager_in/app_in、open_in/open_in_int 并不是失效错配;它们是加载器的内部映射。uninstall_in 才是当前样本中明确未解析的页面场景。(S1)

5.4 启动广告按来源改变形式#

启动条件 7 组路径 非 7 组路径 结果
首次启动 first 插屏;因默认 false 跳过 同为 first,但绕过 false 后可请求 首启广告机会不同
后续普通启动 App Open,读取 open_in 插屏管理器 open_in→open_in_int 广告形式和配置不同
后续通知拉起 App Open 代码固定读 open_in,事件记 Open_Ou 插屏管理器 open_ou→open_ou_int 非 7 使用通知回流专属插屏配置

路由核心代码:

if (isFirst || referrer == 7) {
    checkAndLoadAd(isFirst)       // first 或 App Open
} else {
    loadInterstitialForReferrer() // open_in/open_ou → *_int
}

证据:SplashActivity.java:404-418,567-646,956-973,1088-1093。启动加载计时通常 2 秒,特定条件 8 秒;超时或失败后继续主流程。(S1)

5.5 页面广告位与调用结论#

页面/节点 页面 scene 最终配置/广告 来源差异
首次启动 first first 插屏 false 仅拦 7 组
后续启动 open_in/open_ou 7 组 App Open;非 7 组 *_int 插屏 广告形式不同
Junk Clean junk/junk_no junk_in/junk_no 插屏 两者 false 仅拦 7 组
Battery battery_in/battery_no 插屏 + 结果页 Native 页面完成路径还会按来源分流
Large Files large_in/large_no 插屏 + large_result_in Native 配置均开
Photo Compression compress_in/compress_no 插屏;compress_no 为 TopOn 配置均开
App Manager manager_in/manager_no app_in/app_no 插屏 映射已确认
App Uninstall uninstall_in 映射为 Unknown,无配置 当前样本未见有效请求路径
文件管理 file_manage 插屏 配置开
首次引导 guide 插屏 false 仅拦 7 组
首页 home_native Native false 仅拦 7 组
退出弹窗 exit Native 配置开

5.6 Native 结果页映射#

junk        -> junk_result_in
junk_no     -> junk_result_no
large_in    -> large_result_in
exit        -> exit
battery_in  -> battery_result_in
battery_no  -> battery_result_no
home_native -> home_native

证据:ad/j.java:32-36。Native 缓存有效期同样约 50 分钟,当前直接创建的是 AdMob Native。(S1)

5.7 Battery 流程的来源分流#

ScanBatterActivity 不只是换文案,还会切换完成后的产品路径:

  • 7 组:执行 batteryCompletedAnim(),进入真实 BatteryInfoActivity。(S1)
  • 非 7 组:执行 optimizeAnimation(),预加载 Native,完成后进入 ResultActivity 并传 show_interstitial=true;结果页先尝试展示插屏,关闭/失败后再展示缓存 Native。(S1)

这证明来源码是全局产品/商业化 cohort(分组),并非仅用于广告统计。不过 7 组在 BatteryInfo 返回时仍可能尝试缓存插屏,所以当前只能确认“时机、落地页和 Native 机会不同”,不能仅凭静态代码给出每组固定广告次数。(S1/U)

六、远程配置、频控与广告网络#

6.1 Firebase Remote Config#

fetchAndActivate() 后读取:

  • ss_ad_config:整包广告场景配置;空值回退 release raw JSON;
  • ss_click_limit_config:点击上限;
  • ss_notify_config_v2:通知频控;
  • ss_event_cfg:事件开关集合。

证据:ad/abcdefghijklmnopqrstuvwx.java:70-72、a0/n.java:178-275。当前生产 Remote Config payload 未抓取,所以本文矩阵代表 APK release fallback,不代表线上当前最终值。(S1/U)

需要特别注意:只要远端仍保留某一场景的数据,单纯把其 isShow 改为 false 仍不能关闭非 7 组请求。若要全量关闭,应让所有人群都经过统一开关,或从配置中移除该场景/广告数据。(S1/I)

6.2 点击限制#

  • MyApp 字段默认 5,release JSON 也是 click_limit=5。(S1)
  • 本地初始化和 Remote Config 完成回调虽然解析 JSON,随后都把运行值直接设为 8。(S1,ad/abcdefghijklmnopqrstuvwx.java:112-120、a0/n.java:211-223)
  • 每次 AdMob 插屏点击按自然日键 interstitial_clicks_yyyy... 累加。(S1,ad/f.java:30-60)
  • simple-mode 恢复确认:加载前会读取当日计数;count >= runtimeLimit 时记录 Int_Limit 并直接返回,不再发起该次请求。(S1)

因此当前样本的实际运行上限更接近每日 8 次广告点击,而不是配置声称的 5 次;这里限制的是“点击后续加载”,不是每日展示次数。(S1)

6.3 缓存与失败回退#

  • 插屏与 Native 缓存有效期均为 3,000,000ms,约 50 分钟。(S1)
  • 插屏支持 AdMob 和 TopOn;同一场景会按配置 data 顺序尝试,Provider 不支持或加载失败时进入下一项。(S1)
  • 加载超时、展示关闭/失败后均回调页面继续,主功能不是硬阻断。(S1)
  • 全局展示锁会避免多个全屏广告同时展示;TopOn 还有超时复位分支。(S1)

6.4 广告 SDK#

包内包含 Google Mobile Ads、TopOn/ThinkUp、AppLovin MAX、Pangle、Vungle、Chartboost、Unity、Mintegral/MBridge、BIGO、IronSource/LevelPlay 等组件。真机进程也注册了多家初始化 Provider。(S1/D1)

但 release 场景配置直接引用的提供方只有 admob 与 topon;其他 SDK 可能是聚合适配器、依赖传递或备用网络,不能写成全部实时请求。(U)

七、来源分组的埋点与收入回传#

来源分流具备完整可观测性:

数据 回传/埋点内容 证据
安装来源 referrer code、原始 install referrer、utmContent m1.java:31-60
广告收入 收入、广告平台/单元等字段,并带 referrer code、raw referrer、utmContent AnalyticsManager$reportAdRevenueToBackend$1.java:77-106
通用网络事件 isOrganic=1/0 与 referrer code utils/i.java:142-161
启动事件 New_Open from=1/2 SplashActivity.java:404-418
页面/功能事件 Home、Junk、Battery、Guide、Result 多处以 1/2 区分 对应页面埋点调用
通知事件 show/click 追加 _1/_2 notification/ponml...java:329-360

这里的 isOrganic 仍继承其内部二元规则:code 7 记 organic,其他 code 记非 organic;不能据此证明 code 1-6 全部为付费投放。(S1)

八、广告之外的来源差异#

模块 7 组 非 7 组 判断
App List 权限解释 首次可能展示解释弹窗 跳过解释弹窗 MainActivity.java:1417-1431(S1)
首次引导存储数值 未见同一随机写入 生成并保存随机 storage size FirstGuideActivity.java:277-295(S1)
Junk 权限拒绝 更倾向退出/返回 可生成 channel 数据、随机大小并继续 AppJunkCleanerActivity.java 多处分支(S1)
普通通知 reminderstatus=false 会阻断 绕过该字段 LongRunningService.java:260-268(S1)
通知文案 多用基础/泛化文案 多用带随机数值的紧迫文案 通知构建代码(S1)

结合广告分流可判断:竞品把非 7 已识别来源组作为更激进的变现/转化人群,同时减少部分权限解释并用模拟或随机数值维持功能叙事。这是静态实现事实;其生产策略是否针对某个具体买量渠道、国家或 campaign(广告系列),仍需远端配置和受控样本验证。(S1/I/U)

九、真机广告观察#

路径 结果
首次启动 未出现插屏;若该设备为 7 组,符合 first=false
引导/诊断 → Clean Now 未出现广告;随后进入权限解释
拒绝 All Files Access → 首页 未出现首页 Native;若为 7 组,符合 home_native=false
首页浏览与 More Tools 未观察到广告
Home / 最近任务划卡 未观察到广告或广告回流页
首启日志关键词检查 未命中可确认的广告请求/展示事件

本轮没有记录并脱敏固化设备的 referrer code,也没有构造非 7 安装来源;所以动态结果不能用于证明“所有用户不展示广告”,也不能动态确认两组展示差异。(D1/U)

十、竞品启示与我方建议#

机制 竞品目的 风险 我方建议
安装来源分层变现 对已识别来源加快回收 误分类;官网/direct 被当高变现组 渠道枚举与“是否付费”分字段,不用 code!=organic 代替付费判断
isShow 仅约束 7 组 快速保护自然量体验 运维误以为已全量关停;合规事故 分成 globalEnabled 与 audiencePolicy 两层,默认全局开关优先
App Open + 功能插屏 + 结果 Native 覆盖会话前中后 打断任务、投诉风险 以任务完成为先,设置会话/日频控和关键流程豁免
Remote Config 整包替换 快速调整地区/来源策略 行为漂移、难审计 配置带版本、签名、灰度、回滚与变更日志
来源码持久化 启动后快速路由 一次失败长期误分组 保存 resolved/unknown/error 状态、时间戳和可控重试策略
场景别名映射 页面调用与广告配置解耦 uninstall_in 这类静默失效 枚举化、构建期完整性校验、未知 scene 上报
随机数值紧迫文案 提升点击和功能完成率 真实性、商店政策和用户信任风险 只展示可复核真实数据,无法检测时使用非数值文案

十一、未验证项与最小验证矩阵#

11.1 未验证项#

  1. Firebase Remote Config 当前生产 payload、按国家/渠道/版本的条件下发规则。(U)
  2. 两个来源组的实际广告请求、填充、展示顺序、关闭按钮和收入差异。(U)
  3. uninstall_in 是否由远端新增 unknown 配置兜底,或在运行时始终无广告。(U)
  4. 真实清理、删除、照片压缩质量、App Manager 权限后的完整页面与 Battery 返回路径。(U)
  5. Mediation 瀑布流中各三方网络的真实请求和填充。(U)

11.2 建议动态验证#

保持国家、设备、版本、网络和 Remote Config 一致,仅改变安装来源:

样本 referrer 目标 重点路径
A organic → code 7 首启、首页、Guide、Junk、二次启动、Battery
B gclid=... → code 3 与 A 完全相同
C website/direct → code 5 验证“非付费但进入非 7 组”
D 查询超时/异常 → code 7 验证失败是否被持久化及后续是否重查

每一步同时记录 REFERRER 本地值、scene、归一化 config key、isShow、广告请求/填充/展示事件、页面最终落点和通知 show/click 的 _1/_2。只有完成该矩阵,才能把当前 S1 静态结论提升为生产策略实证。

竞品拆包报告库 · 逆向结论按证据等级阅读