[672][app][device]升级build gradle版本到3.5.4用于兼容Android11 manifest <queries>标签;添加硬件管理模块用于管理车载已硬件:新老核销、语音模块等;OCH核销依赖下沉;
This commit is contained in:
1
libraries/mogo-hardware-devices/.gitignore
vendored
Normal file
1
libraries/mogo-hardware-devices/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
/build
|
||||
4
libraries/mogo-hardware-devices/README.md
Normal file
4
libraries/mogo-hardware-devices/README.md
Normal file
@@ -0,0 +1,4 @@
|
||||
#### 说明
|
||||
# 硬件设备管理
|
||||
## 目前包含:核销设备(SK87R和Q350)、TTS语音设备、LED屏幕
|
||||
|
||||
39
libraries/mogo-hardware-devices/build.gradle
Normal file
39
libraries/mogo-hardware-devices/build.gradle
Normal file
@@ -0,0 +1,39 @@
|
||||
plugins {
|
||||
id 'com.android.library'
|
||||
id 'kotlin-android'
|
||||
}
|
||||
|
||||
android {
|
||||
compileSdkVersion rootProject.ext.android.compileSdkVersion
|
||||
|
||||
defaultConfig {
|
||||
minSdkVersion rootProject.ext.android.minSdkVersion
|
||||
targetSdkVersion rootProject.ext.android.targetSdkVersion
|
||||
versionCode rootProject.versionCode as int
|
||||
versionName rootProject.versionName
|
||||
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
|
||||
consumerProguardFiles 'consumer-rules.pro'
|
||||
}
|
||||
|
||||
buildTypes {
|
||||
release {
|
||||
minifyEnabled false
|
||||
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation rootProject.ext.dependencies.androidxappcompat
|
||||
api rootProject.ext.dependencies.serialport
|
||||
}
|
||||
0
libraries/mogo-hardware-devices/consumer-rules.pro
Normal file
0
libraries/mogo-hardware-devices/consumer-rules.pro
Normal file
3
libraries/mogo-hardware-devices/gradle.properties
Normal file
3
libraries/mogo-hardware-devices/gradle.properties
Normal file
@@ -0,0 +1,3 @@
|
||||
GROUP=com.mogo.device
|
||||
POM_ARTIFACT_ID=mogo-device
|
||||
VERSION_CODE=1
|
||||
21
libraries/mogo-hardware-devices/proguard-rules.pro
vendored
Normal file
21
libraries/mogo-hardware-devices/proguard-rules.pro
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
# Add project specific ProGuard rules here.
|
||||
# You can control the set of applied configuration files using the
|
||||
# proguardFiles setting in build.gradle.
|
||||
#
|
||||
# For more details, see
|
||||
# http://developer.android.com/guide/developing/tools/proguard.html
|
||||
|
||||
# If your project uses WebView with JS, uncomment the following
|
||||
# and specify the fully qualified class name to the JavaScript interface
|
||||
# class:
|
||||
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
|
||||
# public *;
|
||||
#}
|
||||
|
||||
# Uncomment this to preserve the line number information for
|
||||
# debugging stack traces.
|
||||
#-keepattributes SourceFile,LineNumberTable
|
||||
|
||||
# If you keep the line number information, uncomment this to
|
||||
# hide the original source file name.
|
||||
#-renamesourcefileattribute SourceFile
|
||||
@@ -0,0 +1 @@
|
||||
<manifest package="com.mogo.support.device"/>
|
||||
@@ -0,0 +1,369 @@
|
||||
package com.mogo.support.device
|
||||
|
||||
import android.content.Context
|
||||
import android.util.Log
|
||||
import com.mogo.support.device.manager.DefaultDevices
|
||||
import com.mogo.support.device.manager.SerialPortManager
|
||||
import com.mogo.support.device.manager.SerialPortManager.SERVICE_STATE
|
||||
import com.mogo.support.device.manager.bean.VerificationData
|
||||
import com.mogo.support.device.manager.listener.OnBindServerListener
|
||||
import com.mogo.support.device.manager.listener.OnDeviceSpeechCx830seListener
|
||||
import com.mogo.support.device.manager.listener.OnDeviceVerificationListener
|
||||
import com.mogo.support.serialport.common.core.Code
|
||||
import com.mogo.support.serialport.common.core.Define
|
||||
import com.mogo.support.serialport.common.core.Device
|
||||
import com.mogo.support.serialport.common.devices.speech.cx830se.data.SwitchingValueData
|
||||
import java.util.concurrent.ConcurrentHashMap
|
||||
|
||||
object DevicesManager {
|
||||
private const val TAG = "DevicesManager"
|
||||
private var serviceBindState = -1//-1:未知
|
||||
private val serialPortManager: SerialPortManager by lazy {
|
||||
SerialPortManager() // 初始化 SerialPortManager
|
||||
}
|
||||
|
||||
private val bindStateChangeListeners: ConcurrentHashMap<String, IBindStateChangeListener> =
|
||||
ConcurrentHashMap()
|
||||
private val verificationAutoListeners: ConcurrentHashMap<String, IVerificationAutoListener> =
|
||||
ConcurrentHashMap()
|
||||
private val speechCx830seListeners: ConcurrentHashMap<String, ISpeechCx830seListener> =
|
||||
ConcurrentHashMap()
|
||||
|
||||
fun init(context: Context, sn: String) {
|
||||
serialPortManager.bindService(context, sn, bindStateChangeListener)
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册服务端APP绑定状态
|
||||
*/
|
||||
fun addBindStateChangeListener(tag: String, listener: IBindStateChangeListener) {
|
||||
if (bindStateChangeListeners.containsKey(tag)) {
|
||||
return
|
||||
}
|
||||
bindStateChangeListeners[tag] = listener
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消注册服务端APP绑定状态
|
||||
*/
|
||||
fun removeBindStateChangeListener(tag: String) {
|
||||
if (bindStateChangeListeners.containsKey(tag)) {
|
||||
bindStateChangeListeners.remove(tag)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册核销设备回调接口 注册时自动连接核销设备
|
||||
*/
|
||||
fun addVerificationListener(tag: String, listener: IVerificationAutoListener) {
|
||||
if (verificationAutoListeners.containsKey(tag)) {
|
||||
return
|
||||
}
|
||||
verificationAutoListeners[tag] = listener
|
||||
if (verificationAutoListeners.isNotEmpty()) {
|
||||
if (serviceBindState == SERVICE_STATE.BIND_SUCCEED) {
|
||||
serialPortManager.open(DefaultDevices.VERIFICATION, verificationListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消注册核销设备回调接口
|
||||
*/
|
||||
fun removeVerificationListener(tag: String) {
|
||||
if (verificationAutoListeners.containsKey(tag)) {
|
||||
verificationAutoListeners.remove(tag)
|
||||
}
|
||||
if (verificationAutoListeners.isEmpty()) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 注册语音设备回调接口 注册时自动连接语音设备
|
||||
*/
|
||||
fun addSpeechCx830seListener(tag: String, listener: ISpeechCx830seListener) {
|
||||
if (speechCx830seListeners.containsKey(tag)) {
|
||||
return
|
||||
}
|
||||
speechCx830seListeners[tag] = listener
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
if (serviceBindState == SERVICE_STATE.BIND_SUCCEED) {
|
||||
serialPortManager.open(DefaultDevices.SPEECH_CX830SE, speechCx830seListener)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 取消注册语音设备回调接口
|
||||
*/
|
||||
fun removeSpeechCx830seListener(tag: String) {
|
||||
if (speechCx830seListeners.containsKey(tag)) {
|
||||
speechCx830seListeners.remove(tag)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val bindStateChangeListener = object : OnBindServerListener() {
|
||||
|
||||
override fun onServiceState(serviceState: Int) {
|
||||
serviceBindState = serviceState
|
||||
if (bindStateChangeListeners.isNotEmpty()) {
|
||||
bindStateChangeListeners.forEach {
|
||||
it.value.onServiceState(serviceState)
|
||||
}
|
||||
}
|
||||
//TODO 链路日志和埋点
|
||||
// OchChainLogManager.writeChainLogScanner(
|
||||
// TAG + "bindStatus",
|
||||
// "绑定服务结果:serviceState:${serviceState}"
|
||||
// )
|
||||
when (serviceState) {
|
||||
SERVICE_STATE.BIND_SUCCEED -> {
|
||||
Log.d(TAG, "服务绑定成功")
|
||||
if (verificationAutoListeners.isNotEmpty()) {
|
||||
serialPortManager.open(DefaultDevices.VERIFICATION, verificationListener)
|
||||
}
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
serialPortManager.open(DefaultDevices.SPEECH_CX830SE, speechCx830seListener)
|
||||
}
|
||||
}
|
||||
|
||||
SERVICE_STATE.BIND_FAILURE_UNINSTALLED -> {
|
||||
Log.d(TAG, "服务绑定失败:未安装串口服务端APP")
|
||||
}
|
||||
|
||||
SERVICE_STATE.BIND_FAILURE_NO_PERMISSION_NOT_FOUND -> {
|
||||
Log.d(
|
||||
TAG,
|
||||
"服务绑定失败:没有绑定权限或找不到服务(如果是此状态,基本上安装后就可以找到,主要就是权限问题)"
|
||||
)
|
||||
}
|
||||
|
||||
SERVICE_STATE.EXCEPTION -> {
|
||||
Log.d(TAG, "服务被异常销毁")
|
||||
}
|
||||
|
||||
else -> {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val verificationListener: OnDeviceVerificationListener =
|
||||
object : OnDeviceVerificationListener() {
|
||||
override fun onDeviceState(
|
||||
path: String?,
|
||||
deviceType: Byte,
|
||||
isOpen: Boolean,
|
||||
message: String?
|
||||
) {
|
||||
if (verificationAutoListeners.isNotEmpty()) {
|
||||
verificationAutoListeners.forEach {
|
||||
it.value.onDeviceState(path, deviceType, isOpen, message)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun onReceive(data: VerificationData) {
|
||||
if (verificationAutoListeners.isNotEmpty()) {
|
||||
verificationAutoListeners.forEach {
|
||||
it.value.onReceive(data)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private val speechCx830seListener: OnDeviceSpeechCx830seListener =
|
||||
object : OnDeviceSpeechCx830seListener() {
|
||||
override fun onSerialPortState(
|
||||
path: String,
|
||||
isOpen: Boolean,
|
||||
throwableMessage: String?
|
||||
) {
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
speechCx830seListeners.forEach {
|
||||
it.value.onOpenState(path, isOpen, throwableMessage)
|
||||
}
|
||||
}
|
||||
|
||||
// if (isOpen) {
|
||||
// openBtnEnable(!serialPortManager.isOpen(selectDevice.path))
|
||||
// updateUi(path, true)
|
||||
// if (serialPortManager.getDeviceType(path) == DeviceType.SPEECH_CX830SE) {
|
||||
// val device = serialPortManager.getOpenedSerialPort(path)
|
||||
// serialPortManager.speechCx830seSendCommand(
|
||||
// device,
|
||||
// SpeechCommand.READ_DEVICE_ADDRESS
|
||||
// )
|
||||
// serialPortManager.speechCx830seSendCommand(
|
||||
// device,
|
||||
// SpeechCommand.READ_SWITCHING_VALUE_STATE
|
||||
// )
|
||||
// }
|
||||
// } else {
|
||||
// showOpenFailed(path)
|
||||
// }
|
||||
}
|
||||
|
||||
override fun onSpeechState(path: String, state: Int) {
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
speechCx830seListeners.forEach {
|
||||
it.value.onSpeechState(path, state)
|
||||
}
|
||||
}
|
||||
val msg = when (state) {
|
||||
Code.SUCCESS -> {
|
||||
"播报内容下发成功"
|
||||
}
|
||||
|
||||
Code.FAILED -> {
|
||||
"播报内容下发失败"
|
||||
}
|
||||
|
||||
|
||||
Code.TIMEOUT -> {
|
||||
"播报内容下发超时"
|
||||
}
|
||||
|
||||
Code.SPEECH_CX830SE_SPEECH_BROADCAST_COMPLETE -> {
|
||||
"播报完成"
|
||||
}
|
||||
|
||||
else -> ""
|
||||
}
|
||||
Log.d(TAG, msg)
|
||||
}
|
||||
|
||||
override fun onSwitchingValue(path: String, state: Int, data: SwitchingValueData?) {
|
||||
super.onSwitchingValue(path, state, data)
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
speechCx830seListeners.forEach {
|
||||
it.value.onSwitchingValue(path, state, data)
|
||||
}
|
||||
}
|
||||
|
||||
val msg = when (state) {
|
||||
Code.SUCCESS -> {
|
||||
"开关量读取成功"
|
||||
}
|
||||
|
||||
Code.TIMEOUT -> {
|
||||
"开关量读取超时"
|
||||
}
|
||||
|
||||
Code.PASSIVITY_RECEIVE -> {
|
||||
"设备主动触发"
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
if (!msg.isNullOrEmpty()) {
|
||||
Log.d(TAG, msg)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDeviceAddress(path: String, state: Int, address: Int) {
|
||||
super.onDeviceAddress(path, state, address)
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
speechCx830seListeners.forEach {
|
||||
it.value.onDeviceAddress(path, state, address)
|
||||
}
|
||||
}
|
||||
|
||||
val msg = when (state) {
|
||||
Code.SUCCESS -> {
|
||||
"设备地址读取成功"
|
||||
}
|
||||
|
||||
Code.TIMEOUT -> {
|
||||
"设备地址读取超时"
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
if (!msg.isNullOrEmpty()) {
|
||||
Log.d(TAG, msg)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun onCommandResponse(
|
||||
path: String,
|
||||
mainCommand: Int,
|
||||
subcommand: Int,
|
||||
state: Int
|
||||
) {
|
||||
super.onCommandResponse(path, mainCommand, subcommand, state)
|
||||
if (speechCx830seListeners.isNotEmpty()) {
|
||||
speechCx830seListeners.forEach {
|
||||
it.value.onCommandResponse(path, mainCommand, subcommand, state)
|
||||
}
|
||||
}
|
||||
// val command = SpeechCommand.getCommandBySign(mainCommand)
|
||||
// var msg = ""
|
||||
// if (state == Code.SUCCESS) {
|
||||
// msg = "执行成功"
|
||||
// } else if (state == Code.TIMEOUT) {
|
||||
// msg = "执行超时"
|
||||
// }
|
||||
Log.i(TAG, "主命令=${mainCommand} 子命令=${subcommand} 命令结果=$state")
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 语音设备(科星互联 CX-830S-E)语音播报
|
||||
* AIDL调用
|
||||
* @param content 播报内容 打断模式下,输入 null或""可以停止语音播报
|
||||
* @return 是否调用成功 调用成功(不代表命令执行成功):[Code.SUCCESS];命令未识别:[Code.COMMAND_ERROR];
|
||||
*/
|
||||
@Define.Code
|
||||
fun speechCx830seBroadcast(content: String?): Int {
|
||||
return serialPortManager.speechCx830seBroadcastSpeech(
|
||||
DefaultDevices.SPEECH_CX830SE,
|
||||
content
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 设备是否打开
|
||||
* @param device {@link DefaultDevices#SPEECH_CX830SE}
|
||||
* {@link DefaultDevices#VERIFICATION}
|
||||
* {@link DefaultDevices#VERIFICATION_SK87R}
|
||||
* {@link DefaultDevices#VERIFICATION_Q350}
|
||||
*/
|
||||
fun isDeviceOpen(device: Device): Boolean {
|
||||
if (DefaultDevices.VERIFICATION.equals(device)) {
|
||||
return serialPortManager.isOpen(DefaultDevices.VERIFICATION_SK87R.path) || serialPortManager.isOpen(
|
||||
DefaultDevices.VERIFICATION_Q350.path
|
||||
)
|
||||
}
|
||||
return serialPortManager.isOpen(device.path)
|
||||
}
|
||||
|
||||
/**
|
||||
* 绑定状态
|
||||
* -1:未知 其他的状态 [SerialPortManager.SERVICE_STATE]
|
||||
*/
|
||||
fun getServiceBindState(): Int {
|
||||
return serviceBindState
|
||||
}
|
||||
|
||||
fun getSDKVersion(): String {
|
||||
return serialPortManager.version
|
||||
}
|
||||
|
||||
fun getSDKAIDLVersion(): String {
|
||||
return serialPortManager.aidlVersion
|
||||
}
|
||||
|
||||
fun getServerVersion(): String? {
|
||||
return serialPortManager.serverVersionName
|
||||
}
|
||||
|
||||
fun getServerAIDLVersion(): String? {
|
||||
return serialPortManager.serverAidlVersion
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package com.mogo.support.device
|
||||
|
||||
//服务绑定状态接口回调
|
||||
interface IBindStateChangeListener {
|
||||
fun onServiceState(state: Int)
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
package com.mogo.support.device;
|
||||
|
||||
import com.mogo.support.serialport.common.core.Define
|
||||
import com.mogo.support.serialport.common.devices.speech.cx830se.data.SwitchingValueData
|
||||
|
||||
/**
|
||||
* 语音设备(科星互联 CX-830S-E)监听
|
||||
*/
|
||||
interface ISpeechCx830seListener {
|
||||
|
||||
/**
|
||||
* 设备打开状态
|
||||
*
|
||||
* @param path 串口地址
|
||||
* @param isOpen 是否打开成功
|
||||
* @param throwableMessage 异常消息
|
||||
*/
|
||||
fun onOpenState(path: String, isOpen: Boolean, throwableMessage: String?) {}
|
||||
|
||||
/**
|
||||
* 语音播报状态
|
||||
*
|
||||
* @param path 串口
|
||||
* @param state 状态 语音命令下发成功:{@link Code#SUCCESS};语音命令下发失败:{@link Code#FAILED};语音命令下发超时:{@link Code#TIMEOUT};语音播报完成:{@link Code#SPEECH_CX830SE_SPEECH_BROADCAST_COMPLETE};
|
||||
*/
|
||||
fun onSpeechState(path: String, @Define.Code state: Int) {}
|
||||
|
||||
/**
|
||||
* 开关量状态
|
||||
* 设备主动触发开关量时 state = Code.PASSIVITY_RECEIVE
|
||||
*
|
||||
* @param path 串口
|
||||
* @param state 状态 查询成功:{@link Code#SUCCESS};查询命令下发失败:{@link Code#FAILED};查询超时:{@link Code#TIMEOUT};设备主动触发开关量:{@link Code#PASSIVITY_RECEIVE};
|
||||
* @param data 开关量数据
|
||||
*/
|
||||
fun onSwitchingValue(path: String, @Define.Code state: Int, data: SwitchingValueData?) {}
|
||||
|
||||
/**
|
||||
* 设备地址
|
||||
*
|
||||
* @param path 串口
|
||||
* @param state 查询状态 成功:{@link Code#SUCCESS};查询命令下发失败:{@link Code#FAILED};超时:{@link Code#TIMEOUT};
|
||||
* @param address 设备地址 -1:解析失败
|
||||
*/
|
||||
fun onDeviceAddress(path: String, @Define.Code state: Int, address: Int) {}
|
||||
|
||||
/**
|
||||
* 命令下发响应
|
||||
*
|
||||
* @param path 串口
|
||||
* @param mainCommand 命令
|
||||
* @param subcommand mainCommand 中如果存在子流程则表示正在执行的子命令 目前只有存在子流程的命令有:{@link SpeechCommand#INITIALIZE};
|
||||
* @param state 状态 成功:{@link Code#SUCCESS};失败:{@link Code#FAILED};超时:{@link Code#TIMEOUT};
|
||||
* 当 mainCommand == {@link SpeechCommand#INITIALIZE} && subcommand == {@link SpeechCommand#UNKNOWN} 时
|
||||
* state表示整体流程状态
|
||||
* * 初始化开始(整体初始化流程的开始):{@link Code#SPEECH_CX830SE_INITIALIZE_START}
|
||||
* * 初始化完成(整体初始化流程的完成):{@link Code#SPEECH_CX830SE_INITIALIZE_COMPLETE}
|
||||
* <p>
|
||||
* 当 mainCommand == {@link SpeechCommand#INITIALIZE} && subcommand != {@link SpeechCommand#UNKNOWN} 时
|
||||
* state表示子命令执行状态
|
||||
* * 初始化子命令开始执行(初始化流程中的子命令开始下发):{@link Code#SPEECH_CX830SE_INITIALIZE_SUBCOMMAND_START}
|
||||
* * 初始化子命令成功:{@link Code#SUCCESS}
|
||||
* * 初始化子命令失败:{@link Code#FAILED}
|
||||
* * 初始化子命令超时:{@link Code#TIMEOUT}
|
||||
*/
|
||||
fun onCommandResponse(
|
||||
path: String,
|
||||
@Define.CommandSign mainCommand: Int,
|
||||
@Define.CommandSign subcommand: Int,
|
||||
@Define.Code state: Int
|
||||
) {
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
package com.mogo.support.device
|
||||
|
||||
import com.mogo.support.device.manager.bean.VerificationData
|
||||
|
||||
//核销设备数据回调
|
||||
interface IVerificationAutoListener {
|
||||
/**
|
||||
* 设备状态
|
||||
*
|
||||
* @param deviceType 设备类型 [com.mogo.support.serialport.common.core.DeviceType.VERIFICATION_Q350] [com.mogo.support.serialport.common.core.DeviceType.VERIFICATION_SK87R]
|
||||
* @param isOpen 是否打开
|
||||
* @param message 消息
|
||||
*/
|
||||
fun onDeviceState(path: String?, deviceType: Byte, isOpen: Boolean, message: String?) {}
|
||||
fun onReceive(data: VerificationData?)
|
||||
}
|
||||
Reference in New Issue
Block a user