`
iaiai
  • 浏览: 2204889 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

[转]Android机型适配之痛

 
阅读更多
Android平台的诞生为手机智能化的普及立下汗马功劳,但其最大的缺点也越来越凸显,那就是碎片化严重:设备繁多、品牌众多、版本各异,芯片、摄像头、分辨率不统一等等,这些都逐渐成为Android系统发展的障碍,碎片化严重不仅造成Android系统混乱,也导致Android应用隐形开发成本的增多。本文中详细介绍了Android琳琅满目的适配问题。

一、个性化十足的Launcher

快捷方式虽然看起来只是一个很小的功能点,但是它涉及到的机型适配问题很多。

快捷方式创建代码:
Intent addShortCut = new Intent("com.android.launcher.action.INSTALL_SHORTCUT");  
addShortCut.putExtra(Intent.EXTRA_SHORTCUT_NAME, title);  
// 不允许重复创建  
addShortCut.putExtra("duplicate", false);  
addShortCut.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon);  
addShortCut.putExtra(Intent.EXTRA_SHORTCUT_INTENT, intent);  
sendBroadcast(addShortCut);


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

二、多姿多彩的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)状态。

2.6 CameraInfo的另类情况

官方文档中有关于调整相机预览角度的例子:

在这个例子中CameraInfo非常重要,最终的角度计算就是根据CameraInfo中orientation值得到的,所以如果这个值不准确的话,那么我们的角度就有可能出现错误。

VIVO V1手机第一次获取CameraInfo的orientation值是90,而当执行了mCamera = Camera.open();之后再获取CameraInfo的orientation值就是0,而且以后获取的都是 0 ,除非重启手机。

无论是这款手机上的哪个应用,只要执行了一次Camera.open()之后,其他所有程序中获取CameraInfo的orientation都是是0。

手机自带的相机却能很好的使用反编译系统相机后果然发现系统相机并没有像官方给出的例子来进行角度的矫正。





解决方案:

  1. 按照此手机系统相机的做;
  2. 对该手机CameraInfo的orientation值写死为90。


三、不止是2的双卡

双卡的问题解决的基本思路:

  • 推断:手机内置的系统APP都可以正常使用这些功能,因此肯定存在厂商自定义API来实现这些功能;
  • 反编译:Framework、系统App、系统数据库;
  • 定位:TelephoneManager扩展、SMSManager扩展、电话服务扩展、短信服务扩展、数据库字段扩展。


四、UI适配

说到UI适配其实很是让人头疼,下面的图片是某个产品为了进行UI适配所做的工作,可以看出相当繁琐。

除了分辨率的适配,有时候布局文件中的某个标签还会引起一些问题,我们先看下面一段布局代码:

正确结果:

错误结果:

这就是因为Android 3.0以下版本在FrameLayout中使用layout_marginTo标签,必须要设置gravity才能生效。

那么如何解决这个问题呢?在设置android:layout_marginTop的组件中再设置一下 android:layout_gravity="top"即可。

五、还有更奇葩的

1. 厂商的抽象方法

如果你需要实现InputConnection接口,那么你一定要注意下面这个很奇葩的异常:


反编译了下此款手机的Framework,发现厂商在InputConnection接口中增加了一个抽象方法performYLPrivateCommand。


2. 距离传感器


2.1 不同手机event.values[0]值简直是千变万化

简单说几个有代表性的:

  1. 一部分手机比较正常,靠近时为0远离时为1(0,1);
  2. 有点小个性的手机数值将变大,比如(0,100),(3,5),(3,100)等等;
  3. 213手机的数值就比较莫名其妙,(1.001,5.003),你是表明精确度高?


2.2 数值与远近关系不统一

既然我们是通过数值来判断当前是否出于近耳状态,那么是不是应该这个数值的大小是有说道的?靠近时的数值小一点,远离时的数值大一些,起码我见过的99%的手机是这样子的。但是就有几款神经病手机(100W)偏偏是靠近时的数值比远离时的数值大,这是个坑,开发者要注意~~!!

2.3 getMaximumRange方法返回值不对

有一句API:SensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY).getMaximumRange(), 文档解释这个应该获取的是传感器数值变化的最大范围,比如如果靠近时的值是0,远离时的值是1。那么getMaximumRange()的值应该是1才不会影响我们的判断,我这里仅仅是从API角度和我们日常的使用习惯来说的,如果不是这样的规律,就会对我们的编程造成麻烦。
  • 大小: 24.1 KB
  • 大小: 217.2 KB
  • 大小: 113 KB
  • 大小: 63.9 KB
  • 大小: 42 KB
  • 大小: 25.3 KB
  • 大小: 8.8 KB
  • 大小: 11.3 KB
  • 大小: 10.2 KB
  • 大小: 35.8 KB
  • 大小: 130.3 KB
  • 大小: 14.8 KB
  • 大小: 19.4 KB
  • 大小: 34.7 KB
  • 大小: 39.8 KB
  • 大小: 24 KB
  • 大小: 37.7 KB
  • 大小: 31.9 KB
  • 大小: 81.5 KB
  • 大小: 147.5 KB
  • 大小: 31.1 KB
  • 大小: 28.8 KB
  • 大小: 50.5 KB
  • 大小: 97.1 KB
  • 大小: 95.5 KB
  • 大小: 63.2 KB
分享到:
评论

相关推荐

    android机型适配讲解

    android机型适配讲解,从概念,设计,适配方案详细讲解android机型适配

    android 适配各种机型布局

    标题“android 适配各种机型布局”和描述中提到的关键点在于“权重”(android:layout_weight),这是Android布局管理器(如LinearLayout)中的一个重要属性,用于解决屏幕适配问题。 权重属性主要应用于...

    android 屏幕适配工具

    提供了android 屏幕适配方案,使用教程 https://blog.csdn.net/qq_17827919/article/details/81027491。

    直接输入px自动适配所有android机型

    标题"直接输入px自动适配所有android机型"所描述的是一种解决策略,它允许开发者在布局文件(layout.xml)中直接使用像素(px)单位来定义UI元素,然后系统会自动处理适配工作,消除设备间的碎片化现象。 这个解决...

    适配android各种机型demo

    在Android开发过程中,适配各种机型是一个至关重要的任务。由于Android设备种类繁多,屏幕尺寸、分辨率、像素密度等因素各异,导致应用在不同设备上的显示效果可能会有很大差异。本Demo旨在提供一种简单易懂的方法来...

    Android 悬浮窗权限各机型各系统适配大全(总结)

    鉴于 Android 系统的碎片化问题,在适配方面也无法做到完全的主流机型适配,需要大家的一起努力。 悬浮窗适配有两种方法:第一种是按照正规的流程,如果系统没有赋予 APP 弹出悬浮窗的权限,就先跳转到权限授权界面...

    Android各机型的屏幕适配

    本篇文章将深入探讨如何使用`dimens`资源来实现Android各机型的完美适配,避免界面元素因尺寸差异而出现拉伸或压缩的现象。 一、屏幕适配的重要性 在Android生态系统中,设备种类繁多,屏幕尺寸从小到大,分辨率从...

    自动生成Android适配不同机型、语言资源文件

    总的来说,适配Android的不同机型和语言资源,是通过创建特定的资源文件夹、编写适配的资源文件和使用自动化工具来完成的。`pxadapter`这样的工具大大简化了这一过程,使得开发者能够更专注于应用功能的实现,而不是...

    能适配各种机型的android二维码扫描

    在Android平台上,开发一款能适配各种机型的二维码扫描应用是一项技术挑战,因为Android设备的硬件配置和屏幕尺寸差异巨大。ZXing(Zebra Crossing)是Google开发的一个开源项目,提供了一套完整的二维码和条形码...

    Android二维码扫描 可适配任何机型

    以下是关于"Android二维码扫描 可适配任何机型"的相关知识点: 1. **Android Camera API**: 扫描二维码的基础是调用Android的相机接口。早期版本的Android使用Camera API1,而较新的版本推荐使用Camera2 API,它...

    Android多屏幕适配及样式-设计开发指导书

    ### Android多屏幕适配及样式设计开发指导书 #### 一、引言 随着移动互联网技术的发展,Android设备种类繁多,不同的品牌、型号、屏幕尺寸以及分辨率等特性导致了多屏幕适配成为Android开发中的一项重要挑战。本文...

    android简单高效自适配

    一个很好使用的android自动适配功能,可以适配绝大多数机型。告别其他复杂的适配方法。详情请到:http://blog.csdn.net/huningjun/article/details/47081519

    android不同机型的适配的解决方案之按比例伸缩篇

    在Android开发中,面对众多不同品牌、不同尺寸的设备,如何进行有效的适配是一个至关重要的问题。本篇文章将深入探讨“按比例伸缩”的方法,为Android应用在各种设备上提供一致的用户体验。通过理解屏幕尺寸、分辨率...

    android开发 手机适配种类选择

    在Android应用开发中,手机适配是一个至关重要的环节,它涉及到应用能否在各种不同设备上顺畅运行和良好显示。本文将详细阐述如何针对不同的系统版本、分辨率和品牌进行适配,确保应用的广泛兼容性。 首先,我们...

    Android各个主要手机机型跳转权限设置界面代码

    本篇文章将详细探讨Android主要手机机型(如华为、小米、vivo、OPPO等)的跳转权限设置界面的代码实现,以及在适配不同设备时需要注意的关键点。 首先,Android权限分为运行时权限(Runtime Permissions)和安装时...

    通过PX适配所有Android机型

    通过工具类生成dimen文件,给一个默认的分辨率即可,生成完成之后复制到res目录下面就可以使用,左右边距使用@dimen/x,上下使用@dimen/y,可以完美适配所有分辨率手机!

    Android应用源码可以适配大多数手机的手电筒

    之前发布过一个手电筒的项目源码有朋友反映不能用,其实网上很多公开的...2.3.7系统实测可以正常使用,同时可以适配绝大多数机型。另外直接点击图片可以更换背景图。默认编译版本4.4.2 编码GBK,需要的朋友可以看一下。

    android手电筒源码(解决部分机型不适配问题)

    自己写了一个手电筒的demo,刚开始只在个别手机上能够打开手电筒,baidu了很多次还是没有解决,最后反编译了一个手电筒的代码看了一下思路,哈哈,终于解决了,现在可以适配绝大多数机型。所以我要分享给大家

    Android 图片显示与屏幕适配的问题

    Android 图片显示与屏幕适配的问题解决方案 Android 图片显示与屏幕适配的问题是每个 Android 开发者头疼的问题,解决这个问题需要了解 Screen 的尺寸、密度、分辨率等多方面的知识。下面将详细介绍 Android 图片...

Global site tag (gtag.js) - Google Analytics