一、前言
近段时间我们打算针对公司已有的设备做一套设备管理系统,采集设备的数据、给设备发送指令。
过程中发现代码执行reboot命令的时候长时间未响应,但是我去adb中执行reboot又是可以的,而且以往从来也没有出现过这个情况,经过我反复排查发现是这批设备没有进行root的原因,导致我的app没有root权限,无法执行这些命令
可是厂家给的app装上竟然可以执行这些命令
原本为了工作的顺利进行,并不打算揪住这一个小的点浪费时间了,不过我是个喜欢刨根问底的人,于是便有了今天这篇博客,这是我这两天查阅各种资料和各种调试测试出来的结果,希望对大家有所帮助
二、获得权限
做一件事情之前我们先搞清楚他的概念,这样理解起来才会顺畅
我们的应用想要获取系统级权限有两种方法:
(1)设备root
(2*)在AndroidManifest中添加
android:sharedUserId="android.uid.system"
简单解释下sharedUserId这个属性,通过设置同一个User id的使得多个应用可以运行在同一个进程中。而将sharedUserId设置成android.uid.system则可以将该应用和系统应用运行在同一进程中,于是乎便有了系统权限
三、加入sharedUserId出现的问题
Manifest文件中加入sharedUserId后,我们会发现一个问题
不管是调试安装还是打包安装,都会报一个INSTALL_FAILED_SHARED_USER_INCOMPATIBLE的安装错误
这边就需要阐述一下这个问题出现的原因,我们从设计思想上来反推
如果任意一个app加上跟你一样的sharedUserId都可以与你的app运行在同一进程和你的app共享数据,那么我们的app数据安全谁来保障,肯定不行是吧,所以当你加上这个的时候,安装包是不能安装的
那么怎么样才能安装上呢?
四、解决安装失败(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE的问题)
使用sharedUserId我们需要记住一个概念
使用同一个sharedUserId的应用,需要使用同一个签名文件
(一)下载相关文件
于是乎,想要安装在android设备上,就需要找到android原生应用相同的签名
在google的git上我们可以拿到我们想要的东西
https://android.googlesource.com/platform/build/+/donut-release/target/product/security/
需要的就是这两个签名文件
这里需要特别说明一下
如果使用的设备厂家没有对这个改动过,则使用google给的这两个就行了
我碰到过有的设备因为厂家做过处理,所以该文件需要向厂家索取,否则无法还是会导致安装不上的问题
除此之外,还需要keytool工具
https://github.com/getfatday/keytool-importkeypair
(二)生成.jks签名文件
1、在项目更目录下创建文件夹signApk,并将签名工具和签名文件都放到该文件夹下
2、在该文件夹下创建signature.sh脚本文件,方便直接生成签名
编写signature文件
./keytool-importkeypair -k giftedcat.jks -p 123456 -pk8 platform.pk8 -cert platform.x509.pem -alias key0
giftedcat.jks 是生成签名文件的名称
123456 是签名的密码
key0 是签名的别名
如果是在windows下的话 双击便可以得到签名文件了
3.在Android Studio中使用
这一步的话,其实也不需要我过多叙述,相信大家已经是烂熟于心了
到这一步,我们的app获取系统级权限就算是大功告成了
已经可以跑起来了,跑不起来的惯例先clean一下
五、结语
在最后需要提醒一下各位,如果之前没有加这个,这次需要加上去的话,是需要将老的应用卸载掉的,毕竟签名都变了,所以对线上已有的应用需要更新的话,加上这个势必会造成影响,这个需要注意