安卓机型适配之痛

gznike 2015-10-14 04:52:24

Android平台的诞生为手机智能化的普及立下汗马功劳,但其最大的缺点也越来越凸显,那就是碎片化严重:设备繁多、品牌众多、版本各异,芯片、摄像头、分辨率不统一等等,这些都逐渐成为Android系统发展的障碍,碎片化严重不仅造成Android系统混乱,也导致Android应用隐形开发成本的增多。本文详细介绍了Android琳琅满目的适配问题。
一、个性化十足的Launcher
快捷方式虽然看起来只是一个很小的功能点,但是它涉及到的机型适配问题很多。
快捷方式创建代码:

1. 无法创建快捷方式
越来越多的手机厂商取消了快捷方式的概念,导致我们无法通过代码创建一个自己实际需要的快捷方式,数据显示,这样的手机约占13%。
 
2. 重复创建快捷方式
通常情况下,我们是不希望自己的快捷方式被重复创建。使用addShortCut.putExtra("duplicate", false);方法就能达到目的,但是市面上至少有8%的手机,即使设置了duplicate为false,还是可以重复创建快捷方式。
代表手机品牌为:华为、中兴、HTC。
Android Launcher源码:

2.1 重复创建快捷方式的解决方案V1.X
我们最早使用的解决快捷方式重复创建的方法是:在创建快捷方式前先执行删除操作。这种方式其实很聪明,因为即使是在快捷方式不存在的情况下执行删除操作也不会有任何异常。这样看来问题解决得太轻松了,但是遗憾的是删除快捷方式同样存在适配问题,数据显示大约21%的手机无法正常删除快捷方式。
另外一种方法是:自行保存快捷方式的创建记录,通过一个字段来记录快捷方式是否已经创建过了,以此来决定是否创建新的快捷方式。这种做法也是因为出现快捷方式无法删除情况后对解决方案进行了一个小的升级,虽然可以解决问题,但是如果程序被清除了数据,那么一切都乱了,还是无法彻底的规避重复的问题。
2.2 重复创建快捷方式的解决方案V2.X
遇到难解的问题还是看看源码吧,Android的Launcher源码在创建快捷方式的时候不仅会判断duplicate的值,还会在数据库中查询一下将要被创建的快捷方式是否已经存在,我们也照做就OK了。

此外,我们也注意到,查询数据库的时候访问地址URI是一个很重要的因素,问题是数据库的URI比较多,Android标准的URI就有3个:
2.2版本以前的URI是:content://com.android.launcher.settings/favorites?notify=true
2.2~4.3版本的URI是:content://com.android.launcher2.settings/favorites?notify=true
4.4版本以上的目前都是:
content://com.android.launcher3.settings/favorites?notify=true
不仅仅Android自己的Launcher数据库地址众多,厂商自己定义的地址就更加丰富多彩,如OPPO R827T的访问URI为:content://com.oppo.launcher.settings /favorites?notify=true;HTC Z715e的访问地址为: content://com.htc.launcher.settings/favorites?notify=true。事实上 远远不止这些,还有不计其数的第三方Launcher应用,很多开发者也会修改数据库访问地址,目前仅我们掌握的不同访问地址就有多达40种左右。
通过权限查询URI:
通过数据库的读写权限来查询对应的URI相信大家也不陌生,感觉上像是找到了终极的解决方案,且看下去……

1.问题一:如果使用完整的权限进行查询——权限众多,我们目前掌握的超过50种。
2.问题二:如果使用不完整的权限进行查询(READ_SETTINGS)对应关系复杂,大约有 32% 的手机会对应两个以上的URI。
例如:
GT-I8262D:
authority:com.sec.android.app.launcher.settings ReadPermission:com.android.launcher.permission.READ_SETTINGS 
authority:com.sec.android.app.launcher.settings.id ReadPermission:com.android.launcher.permission.READ_SETTINGS
Lenovo A278t:
authority:com.aspire.mm.Settings
ReadPermission:com.aspire.mm.permission.READ_SETTINGS 
authority:com.huaqin.launcherEx.settings ReadPermission:com.huaqin.launcherEx.permission.READ_SETTINGS 
authority:com.huaqin.thememgr.Settings ReadPermission:com.huaqin.thememgr.permission.READ_SETTINGS

...全文
441 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_34877084 2016-05-19
  • 打赏
  • 举报
回复
蒲锦_up 2016-05-19
  • 打赏
  • 举报
回复
深度定制,如三星 小米 华为之类的,测试的时候 一堆坑。。。。
文明游戏 2016-05-19
  • 打赏
  • 举报
回复
https://forum.csdn.net/PointForum/ui/scripts/csdn/Plugin/001/face/2.gif
JOANNEZHANG1 2016-05-19
  • 打赏
  • 举报
回复
楼主很厉害的样子,研究的比较透彻呢!
LyySummer 2016-05-19
  • 打赏
  • 举报
回复
warmor 2016-05-14
  • 打赏
  • 举报
回复
看起来很强大的样子,顶一下!
月盡天明 2015-10-14
  • 打赏
  • 举报
回复
写的很好啊~~~
gznike 2015-10-14
  • 打赏
  • 举报
回复
1.问题一:如果使用完整的权限进行查询——权限众多,我们目前掌握的超过50种。
2.问题二:如果使用不完整的权限进行查询(READ_SETTINGS)对应关系复杂,大约有 32% 的手机会对应两个以上的URI。
例如:
GT-I8262D:
authority:com.sec.android.app.launcher.settings ReadPermission:com.android.launcher.permission.READ_SETTINGS 
authority:com.sec.android.app.launcher.settings.id ReadPermission:com.android.launcher.permission.READ_SETTINGS
Lenovo A278t:
authority:com.aspire.mm.Settings
ReadPermission:com.aspire.mm.permission.READ_SETTINGS 
authority:com.huaqin.launcherEx.settings ReadPermission:com.huaqin.launcherEx.permission.READ_SETTINGS 
authority:com.huaqin.thememgr.Settings ReadPermission:com.huaqin.thememgr.permission.READ_SETTINGS
二、多姿多彩的Camera
1. Intent调用手机内相机程序
 
如果我们设置了照片的存储路径,那么很可能会遇到以下三种问题:
问题一:onActivityResult方法中的data返回为空(数据表明,93%的机型的data将会是Null,所以如果我们指定了路径,就不要使用data来获取照片,起码在使用前要做空判断)。
问题二:照片无法存储。
如果自定义存储路径是/mnt/sdcard/lowry/,而手机SD卡下在拍照前没有名为lowry的文件夹,那么部分手机拍照后图片将不会保存,导致我们无法获得照片,大多数手机的相机遇到文件夹不存在的情况都会自己创建出不存在的文件夹,而个别手机却不会创建,其代表机型为:三星I8258、华为H30-T00、红米等。
解决的方法就是在指定存储路径前先判断路径中的文件夹是否都存在,不存在先创建再调用相机。
问题三:照片可以存储,但是名字不对。
file:///mnt/sdcard/123 1.jpg,由于URI的fromFile方法会将路径中的空格用“%20”取代。
其实对于大多数的手机这都不算事,手机在解析存储路径的时候都会将“%20”替换为空格,这样实际上最终的照片名字还是我们当初指定的名字:123 1.jpg,遗憾的是个别手机(如酷派7260)系统自带的相机没有将“%20”读成空格,拍照后的照片的名字是123%201.jpg,我们用路径“file:///mnt/sdcard/123 1.jpg”能找到照片才怪!
 
 

总结:
(1)使用onActivityResult中的intent(data)前要做空判断。 
(2)指定拍照路径时,先检查路径中的文件夹是否都存在,不存在时先创建文件夹再调用相机拍照。 
(3)指定拍照存储路径时,照片的命名中不要包含空格等特殊符号。
2. 通过Camera的open方法调用手机摄像头
2.1 连续自动对焦crash
原因:第一次对焦未结束,应用层又发起第二次对焦,导致对焦失败。

解决方案一:传入AutoFocusCallback;

解决方案二:延时操作;
解决方案三:异常捕获。
2.2 摄像头个数判断错误
现象:当我们使用Camera.getNumberOfCameras()方法检测摄像头数量时返回的结果不准确,如果我们尝试打开一个不存在的摄像头肯定会抛出异常,这也提醒我们在开启Camera摄像头时需要加异常保护。
代表机型:联想278T、酷派8022

2.3 闪光灯的判断
我们常用的判断手机是否支持闪光灯的方法应该有以下两种:
方法一:使用getSupportedFlashModes方法;
 
方法二:通过PackageManager判断。

使用方法一有3.7%的机器结果错误,无法准确地判断出手机是否有闪光灯,主要的品牌包含:酷派、天语、联想、三星等。使用方法二有9.7%的机器结果错误,主要品牌包含:VIVO、金立、酷派、天语、朵唯、三星等。
我们建议在判断手机是否有闪光灯的时候将这两种方法联合使用,出现错误的概率将大大降低。
2.4 常亮状态与其他状态间的切换
前提条件是我们设置闪光灯为常亮(Parameters.FLASH_MODE_TORCH),并且闪光灯成功常亮。此时我们在设置闪光灯模式为Parameters.FLASH_MODE_AUTO后,闪光灯依然常亮,这样的机型约占热门机型的12%。遇到这种情况我们需要先设置闪光灯模式为Parameters.FLASH_MODE_OFF,关闭闪光灯后再设置其他模式。
2.5 释放Camera后闪光灯依旧闪亮
既然开了,我们就要负责关,说实话,以前这个问题根本不在我的考虑范围内,因为我们在使用Camera的时候都会在Activity被销毁或者暂停时释放Camera。这个时候无论闪光灯是什么状态,都会随着Camera的释放而关闭。直到我遇见了OPPO R815T,我的世界观发生了变化,这货如果设置了闪光灯常亮,即使释放了Camera闪光灯依旧稳稳地亮着。
而且由于Camera被释放掉了,你再也没办法关闭闪光灯了,关闭App、卸载App,你还是抠电池关机吧……所以,如果你的程序中有设置闪光灯为常亮状态的操作,建议在释放Camera前先将闪光灯设置为关闭(Parameters.FLASH_MODE_OFF)状态。

80,360

社区成员

发帖
与我相关
我的任务
社区描述
移动平台 Android
androidandroid-studioandroidx 技术论坛(原bbs)
社区管理员
  • Android
  • yechaoa
  • 失落夏天
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧