Dir 是我在 2017年元旦搞的项目,专门治理Android上流氓软件/不规范的软件在存储卡乱存储文件,还你一个整洁的存储空间。这篇文章介绍我开发它的经历和初衷。Dir:https://dir.trumeet.top
本文同步发表于我的博客:https://blog.trumeet.top/2017/07/29/begin-dir/
(顶部图片:atony)
初衷
开发它的初心,还要从一次随意浏览手机开始说起。
某一天,我浏览手机里的文件,发现存储卡里面有许多APP乱创建的内容,它们肆无忌惮地把自己的 缓存
、日志
甚至 广告
和 用户标识
存储在用户的 SD 卡里面。这也就像你的电脑硬盘里本应该是放你的文档、照片的地方,却杂乱无章地堆放了各种垃圾、小广告 还有你的隐私。甚至有些 APP 把临时图片/视频也丢进存储卡,还不忘及时删除或者加上 .nomedia
文件,这就导致我的 Google 相册
总提示我 要不要备份xx缓存目录
.. 我很生气,这是我的个人目录,你们这样子随意丢垃圾肯定是不规范的。
Android 目录规范
Android 文件系统有如下目录区分:
私有目录(内部)
位于
/data/data/<包名>/
下,存放应用的私有内容,其他应用没有授权是无法访问的。它被设计为私有
,也就是说一般不和其他人共享,比较私密的内容
,用户需要访问也需要ROOT
。在这个目录中,我们通常这样安排,如果你去随意打开一个应用的私有目录,它一般也是这样的:
cache
:缓存。里面的文件大小会在应用详情 -> 缓存大小
里面显示,用户可以通过清除缓存
删掉它的内容,所以不能放如设置
等重要内容。databases
: 数据库目录,里面存放数据库。files
: 文件目录,随意安排。shared_prefs
: 设置(SP)目录。以上是常用的目录形式,当然,应用不按照规定也无伤大雅。因为这是放在私有目录中的,其他人(包括用户)都是无法访问的。
私有目录(外部)
位于
SD卡/Android/data/<包名>/
下,由于是外部
,就放在 SD 卡里,用户可以访问。自身程序可以无需存储权限访问,其他应用或用户需要存储卡权限。由于任何人都可以访问,它一般放置一些不太重要、不太保密的内容。里面一般有:
files
: 同上面 filescache
: 同上面 cache
不规范的猥琐做法
也就是说,应用如果要存放缓存、广告、日志 都可以无需存储权限,放进自身目录,既保护了数据安全、方便系统统一管理(如用户 清除缓存),还保持存储卡简洁。最重要的,还能无需存储权限。但是就有一些应用,不知道是开发人员吔屎了、应用间分享数据(可以用 FileProvider)、需要应用间分享用户ID(非常恶心的做法,详见下文),还是怎么着.. 不管怎么说,他们都带来了很多副作用。
插话:应用间分享用户ID
许多流氓软件都为了统计或者追踪用户,把自己获取到的用户硬件ID(隐私信息,如 IMEI、Mac地址) 存放到存储卡,多个应用共享。比如说,有 10 个应用带有XX会读取隐私的SDK,它们只要有一个获取了手机权限,就会把拿到的隐私存到存储卡,这样其他9个只需存储权限就可以获取到用户ID,从而追踪用户、共享情报了。这是非常侵害用户隐私的行为,因为这个ID是终身的,和硬件绑定的,且唯一的。有一次,我在存储卡根目录发现了一个叫 .imei
的文件,打开看里面写着一串东西,应该就是某毒瘤获取到的隐私(IMEI)吧。
不忍受,不认怼
见过一句话:
要么忍受,要么改变。
作为强迫症,我无法忍受自己的手机被肆意丢垃圾。我想起了酷安常见的一种拦截创建目录的方法:使用同名文件替换文件夹
。这是由于 Unix 文件系统所致,替换后再操作会抛出 Not a dictionary
异常,这也就阻止瞎**创建了。Dir 有了雏形——专治随意创建。 Dir 也就是 目录
的简写(搞过 CMD 的童鞋应该知道)。
还有一些原因
还有一些原因,让我上了 Dir 的大船:
- 市面上某些垃圾清理大师
广告太多
,见过酷安某评论,清理完弹出女尸广告。我想找一款简单,无杂质
的清理。 - 还有些比较良心的清理需要 ROOT。
- 大多数清理工具对小众APP、个人作品支持较差。
为此,Dir 基本已定型,可以开始开发了。
让我们开始吧
(原谅这节没写多少东西,因为许多 Bug 修完就忘了 ><)
规则的概念
由于 Dir 不是针对规范路径的清理,也就无法根据通配符、表达式等方式进行匹配垃圾。所以我想到了 规则数据库
的方式,由客户端下载安装最新云端规则,然后根据规则进行清理。每一条规则有一个路径,对应一个APP,一个标题,还有其他属性。
设计 APP
有了目标,我开始开发 Dir。最初就准备做一个 Activity,两个卡片——同步规则
和 扫描
。但最后,放弃了这个想法。
很快地,第一个 Beta 发布了。我在酷安邀请大家来参与公测,测试中,也发现了许多问题。
逐一修复后,觉得差不多了,便发布了正式版。反响很好,用户都表示 【神器】.. 也鼓励我继续开发它。
人多力量大。后来,我还加入了 规则贡献 等功能,通过给我提交垃圾文件规则,可以拿到完整版的兑换码,鼓励大家一起来建设这个项目。
许多用户反馈 界面太丑,我在5月份更新了 UI,全面的 Material 风格,让 Dir 用着更舒服..
许多热心用户来反馈问题,更有帮我 设计、画图、制作官网的热心基佬,他们很大地帮助了 Dir 的进步。
以下是我遇到的一些问题:
第一个问题:同步规则
如何同步?由于我不懂数据库,最初,我是每次同步时删除所有本地规则,然后再下载、保存.. 后来发布一段时间,觉得这样太慢。所以换成了 增量
的方案,先将本地规则路径存入 Set
,然后在下载云端数据后每次保存前使用 contains
判断是否本地已有,如果有就跳过。这样大幅度提高了效率。
在这样发布一段时间后,又遇到了新的问题:
本地重复。由于规则没有一个固定格式,就导致一旦云端的路径修改(ABC
变成了 /ABC
),实际效果相同,但是在contains
的时候就被认为两条,最终多次存储,导致重复。最终,我将每条路径都进行了处理,统一为 /XXX
的形式,保证了本地无重复。
本地现有规则不会更新 如果某规则在云端进行了更新(如标题变更),本地在判断时就会跳过,从而不会更新。为此,我更换了思路,使用SQL的 unique
功能,然后每次不进行本地判断,使用目录作为唯一列,直接存储。这样就会在本地已有这个路径的时候更新这条规则的详情,从而不创建新的项。这样做好处就在于解决了这两个问题,但是速度会变慢。
规则太少
最初只有几十条规则,有些热心用户邮件发来了一些,我需要每次都手动加入后台,数量少还很累。于是,用户贡献规则 的想法便萌生了。起初,我准备允许用户 提交
、修改
、下架
这三个操作,但是觉得工作量太大,最终只保留了 提交
,用户手机上编辑规则后,提交管理员审核,随后再存入数据库。最终规则已过千条,支持许多软件。
后端程序
Telegram 群里大佬说,要尽可能地少把数据放到客户端。所以按照正常做法,规则提交等功能都是调用后台程序完成的。最初为了图省事,直接用的 LeanCloud 云函数(如同 FireBase Function),但简直天价,最低 6RMB/天,价格感人。然后,我借着组VPS的机会自己琢磨了后端,写了 RestFul API (也没有读过什么规范,反正自己够用就行 大雾),这样就能节省很多开支,而且程序完全由自己做主,自由、安全。
详见:https://blog.trumeet.top/2017/06/14/webservlet-jetty-appserver/
结语和感谢
开发中还遇到了许多问题,我都在尝试一一解决,在这个项目中,我也涨了不少姿势。这个项目也受到了大家的好评。开发它7个月了,我没有停下,努力把它做得更好,回报各位的支持。
以下是 Dir 比较重要版本的截图和历史,留作纪念:
1.0 Beta 最初版 (1月12日)
1.5 第一个正式版(1月18日)
界面和最初一样
规则提交工具 发布首个测试版,开始接受贡献规则(4月17日)
v1.31_build38-beta 界面大改,全面 Material 设计 (5月1日)
非常感谢这个项目,让我学到了很多东西,也感谢所有为Dir做出贡献的人,它仍在继续,会做得更好!
硬广时间:文章看完了,带走一只Dir (这个主页也是热心用户 neoFelhz 帮忙设计的 ><)