本文介绍了应用被克隆到另一个手机上可能引起的问题及解决方案。
《相见欢·无言独上西楼》
无言独上西楼,月如钩。
寂寞梧桐深院锁清秋。
剪不断,理还乱,是离愁。
别是一般滋味在心头。
-五代,李煜
前言
目前各大手机厂商提供了一键换机、手机克隆等快速迁移应用及数据的功能,如果是相同机型,由于是系统级的应用,所以会将/data/data目录下的数据进行迁移,这样会带来一个问题,应用部分功能使用了sp文件进行缓存,例如:imei、androidid等数据,两部手机具有相同的imei会影响推送、日活统计等功能。
小米一键换机
小米一键换机支持应用程序及数据的克隆,应用程序的用户数据有两个部分,一部分位于SD卡,一部分位于系统的data分区。一键换机时会分别对这两部分数据进行打包。如果新手机中的某个应用和之前的旧手机中相同,系统会通过对打包文件中的APK文件作出判断,如果新手机的应用版本高于旧手机的应用版本,旧版本数据依然会原封不动的传送给新手机,并依靠该应用本身的数据升级逻辑进行数据版本的升级。
华为手机克隆
华为手机克隆支持应用程序及数据的克隆,应用程序数据特指应用程序保存在系统路径(data/data)下的应用数据,不含应用在内部存储或外置SD卡上创建并保存的数据,如下载的媒体文件等。
解决方案
我们可以在写入相应imei缓存的同时存储当前系统时间,然后利用PackageInfo中提供的firstInstallTime判断是否为克隆的应用,如果应用安装时间大于缓存的系统时间则表示是通过克隆(一键换机)功能处理的应用:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24public static void saveImei(){
...
saveImeiTime();
}
public static boolean isCloneApp(Context context) {
long time = getImeiTime(); // 在方法中使用sp获取缓存的系统时间
if (time == 0) {
return false;
}
long installTime = getPackageFirstInstallTime(context);
return installTime > time;
}
public static long getPackageFirstInstallTime(Context context) {
String name = context.getPackageName();
long time = 0;
try {
time = context.getPackageManager().getPackageInfo(name, 0).firstInstallTime;
} catch (Exception e) {
e.printStackTrace();
}
return time;
}
在应用启动时判断如果是克隆的应用则重置imei,重新获取权限等处理,这个方案有两个缺陷,一是只能判断新安装的应用,对于覆盖安装的应用只能想办法复用应用原有逻辑中获取之前保存的系统时间;二是如果两个手机的系统时间不一致也可能判断失效,但对于这种非正常情况可以考虑忽略。