問題:需要對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 呢?