程序员MM的自白:磨人小妖精之安卓碎片化

文/腾讯优测 章婉霞

除了crash问题,Android平台的碎片化越来越受到移动开发的关注,且不谈支持Android系统的移动设备早已过万款,屏幕、品牌以及传感器等方面的碎片化问题也困扰着开发者。

初级Android的开发人员经常关心的问题就是开发的应用能不能在需求的设备上正常运行。为什么我没有说所有设备呢?长期盘踞各Android设备市场份额或市场关注度榜单前十位,被大家熟知的品牌,它们ROM的个性化都足以让人眼花缭乱了,更何况在如今“乱世”里那些七零八落的机型了。想要做更全面的自动化机型测试,破解兼容问题,腾讯优测是很好的选择。

最近笔者在做Launcher上图标的清理,接到这个需求的时候,内心是感到轻松的,感觉查询需要删除的图标然后删除不就OK了。但事实证明,我还真是很年轻呢。

Launcher个性化

我们都知道,Android源码中有Google做的原生Launcher。在2.1及之前的版本中,使用com.android.launcher;2.2至4.3版本使用的是com.android.launcher2;4.4版本开始则使用com.android.launcher3。

为了探究一下不同机型的Launcher应用,我分别查看了五部手机,结果如下:

除了锤子使用了原生的Launcher外,其他四个机型都经过了个性化再开发。在实际操作中也可以发现,对图标上的操作响应也不尽相同。

对于点击Home键后有“应用”图标的Launcher,长按应用并拖动可在桌面上创建快捷方式。而没有“应用”图标的Launcher,长按加拖动则只能实现应用图标的移动。

应用要创建和删除自己的快捷方式图标只需发送如下两个Intent即可:

com.android.launcher.action.INSTALL_SHORTCUT

com.android.launcher.action.UNINSTALL_SHORTCUT

同时需要在AndroidManifest.xml中添加如下两个权限:

android:name="com.android.launcher.permission.INSTALL_SHORTCUT

android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT

而第三方应用要对Launcher上其他应用的快捷方式图标进行删除,最简单粗暴的方式是直接从数据库里删除,当然我们并不推荐,即便发送删除的Intent也需要获知该图标在Launcher保存信息的数据库launcher.db中的一条具有独特性的信息。

接下来我们看看launcher.db数据库是不是像网络上说的那般,favorites表中保存着图标信息。

数据库个性化

从导出launcher.db来看,上述表中的五部手机大部分都在favorites表中保存图标信息,三星I9082则在favorites中只保存主桌面图标,其他应用图标保存在favorites_normal表中。而各机型launcher.db中存放的数据及形式也有所区别,详细情况见如下两图:

权限个性化

一旦要对Launcher数据库有访问,至少需要有对数据库的读权限,而要进行操作,权限要求会更高(写数据库的权限安全等级一般都是signatureOrSystem)。据不完全统计,要适配市场上大部分的设备,如下所列出的一大长串权限是免不了的,而且肯定还有不少漏网之鱼。

android:name="com.android.launcher.permission.READ_SETTINGS"

android:name="com.android.launcher.permission.WRITE_SETTINGS"

android:name="com.android.launcher2.permission.READ_SETTINGS"

android:name="com.android.launcher2.permission.WRITE_SETTINGS"

android:name="com.android.launcher3.permission.READ_SETTINGS"

android:name="com.android.launcher3.permission.WRITE_SETTINGS"

android:name="cn.nubia.launcher.permission.READ_SETTINGS"

android:name="cn.nubia.launcher.permission.WRITE_SETTINGS"

android:name="org.adw.launcher.permission.READ_SETTINGS"

android:name="org.adw.launcher.permission.WRITE_SETTINGS"

android:name="com.htc.launcher.permission.READ_SETTINGS"

android:name="com.htc.launcher.permission.WRITE_SETTINGS"

android:name="com.qihoo360.launcher.permission.READ_SETTINGS"

android:name="com.qihoo360.launcher.permission.WRITE_SETTINGS"

android:name="com.lge.launcher.permission.READ_SETTINGS"

android:name="com.lge.launcher.permission.WRITE_SETTINGS"

android:name="net.qihoo.launcher.permission.READ_SETTINGS"

android:name="net.qihoo.launcher.permission.WRITE_SETTINGS"

android:name="org.adwfreak.launcher.permission.READ_SETTINGS"

android:name="org.adwfreak.launcher.permission.WRITE_SETTINGS"

android:name="org.adw.launcher_donut.permission.READ_SETTINGS"

android:name="org.adw.launcher_donut.permission.WRITE_SETTINGS"

android:name="com.huawei.launcher3.permission.READ_SETTINGS"

android:name="com.huawei.launcher3.permission.WRITE_SETTINGS"

android:name="com.fede.launcher.permission.READ_SETTINGS"

android:name="com.fede.launcher.permission.WRITE_SETTINGS"

android:name="com.sec.android.app.twlauncher.settings.READ_SETTINGS"

android:name="com.sec.android.app.twlauncher.settings.WRITE_SETTINGS"

android:name="com.anddoes.launcher.permission.READ_SETTINGS"

android:name="com.anddoes.launcher.permission.WRITE_SETTINGS"

android:name="com.tencent.qqlauncher.permission.READ_SETTINGS"

android:name="com.tencent.qqlauncher.permission.WRITE_SETTINGS"

android:name="com.huawei.launcher2.permission.READ_SETTINGS"

android:name="com.huawei.launcher2.permission.WRITE_SETTINGS"

android:name="com.android.mylauncher.permission.READ_SETTINGS"

android:name="com.android.mylauncher.permission.WRITE_SETTINGS"

android:name="com.ebproductions.android.launcher.permission.READ_SETTINGS"

android:name="com.ebproductions.android.launcher.permission.WRITE_SETTINGS"

android:name="com.oppo.launcher.permission.READ_SETTINGS"

android:name="com.oppo.launcher.permission.WRITE_SETTINGS"

android:name="com.huawei.android.launcher.permission.READ_SETTINGS"

android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"

android:name="telecom.mdesk.permission.READ_SETTINGS"

android:name="telecom.mdesk.permission.WRITE_SETTINGS"

仅一个Launcher就这么任性,千千万万的Android开发人员,多少次问自己:

爱卓,我怕了吗?

眼泪,我忘了吗?

产品催,机型差

应用怎么开发???

不管是创业公司还是具备一定规模的企业,为了开发和测试自己的应用,采购覆盖Android市场80%甚至更高的机型,是一件既不现实也不容易更不合理的事。想要为开发者压缩时间成本,为公司节省采购和管理成本,不妨尝试一下腾讯优测,会让你得到意想不到的效果哦,这可是程序员MM发自内心地呐喊~

想了解更多干货,欢迎关注腾讯优测微信号:优测网(wxutest)

腾讯优测:

腾讯优测是备受客户信赖的移动云测试平台,为应用、游戏,H5混合应用的研发团队提供产品质量检测与问题解决服务。不仅在线上平台提供「云手机远程操控与调试」、「自动化全面兼容性测试」、「APK源码级缺陷性分析」等多种质量检测工具,更为VIP客户配备专家团队提供定制化综合测试解决方案。真机实验室配备上千款手机,覆盖市面98%主流机型,7*24小时在线运行,覆盖亿级用户。

时间: 2024-10-24 01:24:44

程序员MM的自白:磨人小妖精之安卓碎片化的相关文章

当程序员一天天老去……哪些人晚景凄凉

程序员将代码注入生命去打造互联网的浪潮之巅,当有一天他们老了,会走向那里,会做些什么?真正有可能晚景凄凉的程序员,是对技术和产品没有兴趣的人,是仅仅把编程当做生活工具的人,是那些不能终身学习的人. 很多年以后,在我60岁的那天早晨,天刚蒙蒙亮我就起床了,先去公园晨练,然后回来做早餐(50岁的时候我学会了做饭),送完外孙上学,刚好8点.由于北京从2020年开始单双月限行了,这个月是单月,所以只能挤地铁.人一如既往的多,一小伙子要给我让座,看了看他的小身板,我说不用,你也是干 IT 的吧,今天咱们都

给新手程序员的16个工作必备小妙招,省下时间去LOL吧!

写在前面: 这个文章核心并不是程序优化的具体技巧,而是拿到一个问题如何思考和利用工具的通用方法.比如即使我们不知道 profiler 这个东西,通过搜索"代码 每一行 时间"也可以很快知道有这样的工具叫做 profiler,并且学会怎么使用.即使不知道 rand 这个函数怎么加速,通过搜索引擎也可以找到别人写好的现成代码.另一方面是发现瓶颈之后也不要着急自己修复,如果不是特别一目了然的话,先看看别人是怎么做的.站在巨人的肩膀上,事半功倍. 1.多看看「官方文档」 我们很多的问题和技术细

「程序员生活志」互联网人的崩溃,是从年终总结开始的

世上本没有年终总结 后来有了KPI 就有人开始千方百计地为涨工资找点说辞 毕业之后,你迎着朝阳乘风破浪,义无反顾地踏入了这个时代最蓬勃发展的互联网行业. 你的第一份工作在一家不到二十个员工的创业公司里,公司总是无缘无故拖欠工资.你们的老板特别喜欢画大饼,总说什么投资会有的股票期权会有的梦想也会有的,到头来只不过是加班是经常有的. 这一天,买完肉包子后,你突然发现公司大楼前,挂上了红灯笼.才猛地惊觉,竟又过了一年. 你是一个产品经理 这一年里 你一共提了331个需求 其中330个有逻辑问题 画了7

有哪些老鸟程序员知道而新手不知道的小技巧?来源:知乎

著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处.作者:大狐狸链接:https://www.zhihu.com/question/36426051/answer/76031743来源:知乎 本来只是分享几条看法,没想到会有这么多人喜欢.我再补充一些,希望能对进阶中的程序朋友有帮助.手机敲得,比较凌乱.作为个人意见仅供参考. 1.重构是程序员的主力技能. 2.工作日志能提升脑容量. 3.先用profiler调查,才有脸谈优化. 4.注释贵精不贵多.杜绝大姨妈般的“例注”.漫山遍野

程序员都会的 35 个 jQuery 小技巧

收集的35个 jQuery 小技巧/代码片段,可以帮你快速开发. 1. 禁止右键点击 1 $(document).ready(function(){ 2 $(document).bind("contextmenu",function(e){ 3 return false; 4 }); 5 }); 2. 隐藏搜索文本框文字 1 Hide when clicked in the search field, the value.(example can be found below in t

黑马程序员_面向对象解决的一个小问题,觉得还好,就存一下

/** *10. 一位老农带着猫.狗.鱼过河,河边有一条船,每次老农只能带一只动物过河. *当老农不和猫狗鱼在一起时,狗会咬猫,猫会吃鱼,当老农和猫狗鱼在一起时,则不会发生这种问题. *编程解决猫狗鱼过河问题. * *分析: * 问题中的对象:猫.狗.鱼.老农.岸1(这岸).岸2(对岸) * * * 限制条件是:老农每次只能带一只动物过河 * 老农不在时,狗咬猫 * 老农不在时,猫吃鱼 * 目标是:将猫.狗.鱼从这岸运到对岸. * 当农夫到达一个岸后,即为一个中间状态,则这个中间状态需要满足,岸

每个程序员都会的 35 个 jQuery 小技巧

1 收集的35个 jQuery 小技巧/代码片段,可以帮你快速开发. 2 1. 禁止右键点击 3 $(document).ready(function(){ 4 $(document).bind("contextmenu",function(e){ 5 return false; 6 }); 7 }); 8 2. 隐藏搜索文本框文字 9 Hide when clicked in the search field, the value.(example can be found belo

浅挖《程序员的自我修养》的小问题

一.size中统计的text的大小与objdump中统计的一些大小不一致问题: size(size.text ) == size( objdump.text + objdump.rodata + objdump.eh_frame) 二..rodata段大小的计算方法 .rodata段存放的是常量.用C代码写一段程序,其中有些东西是被编译器放到.rodata段的. 例如: char* fmt = "12345678"; int main() { uart_send_string(fmt)

每个程序员都会的35个jQuery小技巧!

1. 禁止右键点击$(document).ready(function(){ $(document).bind("contextmenu",function(e){ return false; });}); 2. 隐藏搜索文本框文字Hide when clicked in the search field, the value.(example can be found below in the comment fields)$(document).ready(function() {