问题:需要对SIM卡进行管理,支持APP切换SIM卡。此功能需要访问串口文件,并且对串口文件进行读写。APP操作串口文件/dev/ttyUSB1时,串口文件打开失败。
2023-11-23 10:59:44.092 14264-14264 MULTI_CARD_SerialHandle com.wellnkiot.multinic E ===========open errorjava.lang.SecurityExceptionat android.serialport.SerialPort.<init>(SerialPort.java:108)at android.serialport.SerialPort$Builder.build(SerialPort.java:299)at com.wellnkiot.multinic.mode.SerialHandle.open(SerialHandle.java:79)at com.wellnkiot.multinic.mode.SerialHandle.open(SerialHandle.java:50)at com.wellnkiot.multinic.mode.SerialManage.open(SerialManage.java:70)at com.wellnkiot.multinic.mode.command.impl.ChangeCardPinServiceImpl.<init>(ChangeCardPinServiceImpl.java:53)at com.wellnkiot.multinic.mode.command.SimCommandMode.getChangeCardService(SimCommandMode.java:91)at com.wellnkiot.multinic.mode.command.SimCommandMode.changeAutoStatus(SimCommandMode.java:60)
打开串口的时候,报错“java.lang.SecurityException”,这个是安全访问错误。
一、什么是串口?
二、串口文件的访问
三、串口文件授权访问
怎么实现APP对串口文件的访问呢?
基本的实现思路:
1)APP授权system用户。APP采用系统签名,作为系统应用, 对应的用户system,方便用户访问读写串口文件
2)串口文件授权system用户访问
3.1 应用调整为系统应用
3.1.1 什么是应用应用?
系统应用需要集成到ROM中。
3.1.2 APP签名采用系统签名
APP打包的时候,签名文件采用系统签名文件。
对应的APP application模块,build.gradle中,定义签名文件
signingConfigs {release {keyAlias 'xxx'keyPassword 'xxx'storeFile file('../systemJupiter.jks')storePassword 'xxx'}debug {keyAlias 'xxx'keyPassword 'xxx'storeFile file('../systemJupiter.jks')storePassword 'xxx'}}buildTypes {debug {// 版本名称增加后缀versionNameSuffix = ".debug"minifyEnabled falsedebuggable trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.debug}release {minifyEnabled truedebuggable false//true 开启可以知道进程包名,debug默认为trueproguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'signingConfig signingConfigs.release}}
编译时采用系统签名。
这样,生成的APP,对应的用户是system,用户组也是system
3.1.3 APP清单文件指定UID为system
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"package="com.sandstar.jupiter.client"android:sharedUserId="android.uid.system">
android:sharedUserId="android.uid.system"
将此APP的用户ID定义为系统system
3.1.4 内置应用允许升级更新
清单文件AndroidManifest.xml中,application节点,不要设置为常驻程序
android:persistent="true",否则无法安装过呢更新包。
因为系统应用+常驻程序,是不允许安装更新包的。
3.2 串口文件授权system访问
APP已经授权system用户以后,就可以访问system级别的文件。
3.2.1 确认系统串口文件普通权限
1|lahaina:/ $ ls -al /dev/tty*
crw-rw-rw- 1 root root 5, 0 1970-01-03 08:44 /dev/tty
crw------- 1 root root 235, 0 1970-01-03 08:44 /dev/ttyEUD0
crw-rw---- 1 bluetooth net_bt 234, 0 2023-11-23 11:17 /dev/ttyHS0
crw-rw---- 1 system system 234, 1 1970-01-03 08:44 /dev/ttyHS1
crw-rw---- 1 system system 234, 2 2023-11-23 11:21 /dev/ttyHS2
crw------- 1 root root 4, 64 1970-01-03 08:44 /dev/ttyS0
crw------- 1 root root 4, 65 1970-01-03 08:44 /dev/ttyS1
crw------- 1 root root 4, 66 1970-01-03 08:44 /dev/ttyS2
crw------- 1 root root 4, 67 1970-01-03 08:44 /dev/ttyS3
crw-rw---- 1 radio radio 188, 0 2023-11-22 14:55 /dev/ttyUSB0
crw-rw---- 1 radio radio 188, 1 2023-11-22 14:55 /dev/ttyUSB1
crw-rw---- 1 radio radio 188, 2 2023-11-23 11:22 /dev/ttyUSB2
crw-rw---- 1 radio radio 188, 3 2023-11-22 14:55 /dev/ttyUSB3
lahaina:/ $
很清理,我们能看到/dev/ttyHS1和/dev/ttyHS2都是归属 system:system用户组,因此我们的
系统应用可以访问。而 /dev/ttyUSB1,归属的用户是radio:radio,两者并非同一个用户组,
因此无法通过system访问 /dev/ttyUSB1 串口文件。
3.2.2 串口文件归属切换system用户
怎么将 /dev/ttyUSB1 文件用户组调整为 system:system 呢?