diff --git a/entry/src/main/cpp/bin/libJudgeSdk.so b/entry/src/main/cpp/bin/libJudgeSdk.so index 0849edf9..b10494a3 100644 Binary files a/entry/src/main/cpp/bin/libJudgeSdk.so and b/entry/src/main/cpp/bin/libJudgeSdk.so differ diff --git a/entry/src/main/ets/ ServiceExtAbility/ServiceExtAbility.ets b/entry/src/main/ets/ ServiceExtAbility/ServiceExtAbility.ets new file mode 100644 index 00000000..bc31bb70 --- /dev/null +++ b/entry/src/main/ets/ ServiceExtAbility/ServiceExtAbility.ets @@ -0,0 +1,35 @@ +import ServiceExtension from '@ohos.app.ability.ServiceExtensionAbility' + +import hilog from '@ohos.hilog'; +import { getTCP } from '../common/utils/GlobalTcp'; +import ServiceExtImpl from '../IdlServiceExt/idl_service_ext_impl'; + +const TAG: string = '[ServiceExtAbility]'; +const DOMAIN_NUMBER: number = 0xFF00; + +export default class ServiceExtAbility extends ServiceExtension { + serviceExtImpl: ServiceExtImpl = new ServiceExtImpl('ExtImpl', this.context); + + async onCreate(want): Promise { + getTCP() + hilog.info(DOMAIN_NUMBER, TAG, `js-test ServiceExtensionAbility-- onCreate, want: ${want.abilityName}`); + }; + + onRequest(want, startId: number): void { + hilog.info(DOMAIN_NUMBER, TAG, `js-test ServiceExtensionAbility--onRequest, want: ${want.abilityName}`); + }; + + onConnect(want) { + hilog.info(DOMAIN_NUMBER, TAG, `js-test ServiceExtensionAbility--onConnect, want: ${want.abilityName}`); + // 返回ServiceExtImpl对象,客户端获取后便可以与ServiceExtensionAbility进行通信 + return this.serviceExtImpl; + }; + + onDisconnect(want): void { + hilog.info(DOMAIN_NUMBER, TAG, `js-test ServiceExtensionAbility--onDisconnect, want: ${want.abilityName}`); + }; + + onDestroy(): void { + hilog.info(DOMAIN_NUMBER, TAG, 'js-test ServiceExtensionAbility--onDestroy'); + }; +}; diff --git a/entry/src/main/ets/ ServiceExtAbility/ServiceInteractive.ets b/entry/src/main/ets/ ServiceExtAbility/ServiceInteractive.ets new file mode 100644 index 00000000..35facd85 --- /dev/null +++ b/entry/src/main/ets/ ServiceExtAbility/ServiceInteractive.ets @@ -0,0 +1,18 @@ +import common from '@ohos.app.ability.common'; +import hilog from '@ohos.hilog'; +import Want from '@ohos.app.ability.Want'; + +const DOMAIN_NUMBER: number = 0xFF00; + +const TAG: string = '[tcp转发服务]'; +let context: common.UIAbilityContext = getContext(this) as common.UIAbilityContext; // UIAbilityContext +let want: Want = { + deviceId: '', + bundleName: 'com.oh.dts', + abilityName: 'ServiceExtAbility' +}; +context.startServiceExtensionAbility(want).then(() => { + hilog.info(DOMAIN_NUMBER, TAG, `启动成功`); +}).catch((err) => { + hilog.error(DOMAIN_NUMBER, TAG, `启动失败`); +}); diff --git a/entry/src/main/ets/IdlServiceExt/i_idl_service_ext.ts b/entry/src/main/ets/IdlServiceExt/i_idl_service_ext.ts new file mode 100644 index 00000000..33b4ab13 --- /dev/null +++ b/entry/src/main/ets/IdlServiceExt/i_idl_service_ext.ts @@ -0,0 +1,7 @@ +export default interface IIdlServiceExt { + processData(data: string, callback: processDataCallback): void; + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void; +} +export type processDataCallback = (errCode: number, returnValue: string) => void; +export type insertDataToMapCallback = (errCode: number) => void; + diff --git a/entry/src/main/ets/IdlServiceExt/idl_service_ext_impl.ts b/entry/src/main/ets/IdlServiceExt/idl_service_ext_impl.ts new file mode 100644 index 00000000..c7be4032 --- /dev/null +++ b/entry/src/main/ets/IdlServiceExt/idl_service_ext_impl.ts @@ -0,0 +1,23 @@ +import IdlServiceExtStub from './idl_service_ext_stub'; +import hilog from '@ohos.hilog'; +import type { insertDataToMapCallback } from './i_idl_service_ext'; +import type { processDataCallback } from './i_idl_service_ext'; +import { getTCP } from '../common/utils/GlobalTcp'; + +const ERR_OK = 0; +const TAG: string = "[IdlServiceExtImpl]"; +const DOMAIN_NUMBER: number = 0xFF00; + +// 开发者需要在这个类型里对接口进行实现 +export default class ServiceExtImpl extends IdlServiceExtStub { + processData(data: string, callback: processDataCallback): void { + // 开发者自行实现业务逻辑 + hilog.info(DOMAIN_NUMBER, TAG, `收到主进程信息`); + } + + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void { + // 开发者自行实现业务逻辑 + hilog.info(DOMAIN_NUMBER, TAG, `js-test ServiceExtensionAbility--insertDataToMap, key: ${key} val: ${val}`); + callback(ERR_OK); + } +} diff --git a/entry/src/main/ets/IdlServiceExt/idl_service_ext_proxy.ts b/entry/src/main/ets/IdlServiceExt/idl_service_ext_proxy.ts new file mode 100644 index 00000000..61c34ab6 --- /dev/null +++ b/entry/src/main/ets/IdlServiceExt/idl_service_ext_proxy.ts @@ -0,0 +1,57 @@ + + +import {processDataCallback} from "./i_idl_service_ext"; +import {insertDataToMapCallback} from "./i_idl_service_ext"; +import IIdlServiceExt from "./i_idl_service_ext"; +import rpc from "@ohos.rpc"; + +export default class IdlServiceExtProxy implements IIdlServiceExt { + constructor(proxy) { + this.proxy = proxy; + } + + processData(data: string, callback: processDataCallback): void + { + let _option = new rpc.MessageOption(); + let _data = new rpc.MessageParcel(); + let _reply = new rpc.MessageParcel(); + // _data.writeString(data); + _data.writeString(data) + this.proxy.sendRequest(IdlServiceExtProxy.COMMAND_PROCESS_DATA, _data, _reply, _option).then(function(result) { + if (result.errCode === 0) { + let _errCode = result.reply.readInt(); + if (_errCode != 0) { + let _returnValue = undefined; + callback(_errCode, _returnValue); + return; + } + let _returnValue = result.reply.readString(); + callback(_errCode, _returnValue); + } else { + console.log("sendRequest failed, errCode: " + result.errCode); + } + }) + } + + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void + { + let _option = new rpc.MessageOption(); + let _data = new rpc.MessageParcel(); + let _reply = new rpc.MessageParcel(); + _data.writeString(key); + _data.writeInt(val); + this.proxy.sendRequest(IdlServiceExtProxy.COMMAND_INSERT_DATA_TO_MAP, _data, _reply, _option).then(function(result) { + if (result.errCode === 0) { + let _errCode = result.reply.readInt(); + callback(_errCode); + } else { + console.log("sendRequest failed, errCode: " + result.errCode); + } + }) + } + + static readonly COMMAND_PROCESS_DATA = 1; + static readonly COMMAND_INSERT_DATA_TO_MAP = 2; + private proxy +} + diff --git a/entry/src/main/ets/IdlServiceExt/idl_service_ext_stub.ts b/entry/src/main/ets/IdlServiceExt/idl_service_ext_stub.ts new file mode 100644 index 00000000..94e8d324 --- /dev/null +++ b/entry/src/main/ets/IdlServiceExt/idl_service_ext_stub.ts @@ -0,0 +1,55 @@ +import { processDataCallback } from "./i_idl_service_ext"; +import { insertDataToMapCallback } from "./i_idl_service_ext"; +import IIdlServiceExt from "./i_idl_service_ext"; +import rpc from "@ohos.rpc"; +import common from '@ohos.app.ability.common'; + +export default class IdlServiceExtStub extends rpc.RemoteObject implements IIdlServiceExt { + protected context: common.ServiceExtensionContext + + constructor(des: string, context: common.ServiceExtensionContext) { + super(des); + this.context = context; + } + + onRemoteMessageRequest(code: number, data: rpc.MessageSequence, reply: rpc.MessageSequence, option): Promise { + console.log("lixiao onRemoteRequest called, code = " + code); + return new Promise((resolve, reject) => { + switch (code) { + case IdlServiceExtStub.COMMAND_PROCESS_DATA: { + let _data = data.readString() + this.processData(_data, (errCode, returnValue) => { + console.log("lixiao callback", returnValue); + reply.writeInt(errCode); + reply.writeString(returnValue); + resolve(true) + }); + break + } + case IdlServiceExtStub.COMMAND_INSERT_DATA_TO_MAP: { + let _key = data.readString(); + let _val = data.readInt(); + this.insertDataToMap(_key, _val, (errCode) => { + reply.writeInt(errCode); + resolve(true) + }); + break + } + default: { + console.log("invalid request code" + code); + reject(true) + } + } + }) + } + + processData(data: string, callback: processDataCallback): void { + } + + insertDataToMap(key: string, val: number, callback: insertDataToMapCallback): void { + } + + static readonly COMMAND_PROCESS_DATA = 1; + static readonly COMMAND_INSERT_DATA_TO_MAP = 2; +} + diff --git a/entry/src/main/ets/common/utils/GlobalTcp.ts b/entry/src/main/ets/common/utils/GlobalTcp.ts index 7faf56cd..902a7b77 100644 --- a/entry/src/main/ets/common/utils/GlobalTcp.ts +++ b/entry/src/main/ets/common/utils/GlobalTcp.ts @@ -26,29 +26,31 @@ export async function getTCP(flag = false) { await globalThis.TcpClient.sendMsg(globalThis.carInfo.carNo) //1002 clearInterval(globalThis.intervalSendMsg) + globalThis.intervalSendMsg = setInterval(() => { if (!globalThis.getCloseTcp) { globalThis.TcpClient.sendMsg(globalThis.carInfo.carNo) //1002 globalThis.tcpStep += 1 - if (globalThis.tcpStep > 30) { + if (globalThis.tcpStep > 4) { globalThis.tcpStep = 0 - getTCP() + getTCP(true) console.log('tcp重连开始') } } - }, 1000 / 3) + }, 1000 * 2) globalThis.TcpClient.onError((val) => { setTimeout(() => { - getTCP() + getTCP(true) }, 1000) }) await globalThis.TcpClient.onMessage((val) => { - setTimeout(() => { - if (val && globalThis.udpClient?.sendMsg) { - globalThis.udpClient?.sendMsg(val) - globalThis.udpClientGps2?.sendMsg(val) - } - }, 1000) + console.log("tcp test 收到差分改正数 length: ", val.byteLength) + if (val) { + globalThis.udpClient?.sendMsg(val, () => { + console.log("tcp test 后置机写入改正数成功") + }) + globalThis.udpClientGps2?.sendMsg(val) + } }) } return diff --git a/entry/src/main/ets/common/utils/TcpClient.ts b/entry/src/main/ets/common/utils/TcpClient.ts index 0a641692..3025666a 100644 --- a/entry/src/main/ets/common/utils/TcpClient.ts +++ b/entry/src/main/ets/common/utils/TcpClient.ts @@ -105,13 +105,13 @@ export default class TcpClient { console.log(`${TAG} TCP send error ${JSON.stringify(err)}`) this.tcpSendNum++ if (!globalThis.getCloseTcp && this.tcpSendNum > 10) { + globalThis.getCloseTcp = true setTimeout(async () => { getTCP(true) }, 3000) this.tcpSendNum = 0 return } - globalThis.getCloseTcp = true reject(false) }); }) diff --git a/entry/src/main/ets/common/utils/UdpClientByCenter.ts b/entry/src/main/ets/common/utils/UdpClientByCenter.ts index ed46a8fc..d8efe18f 100644 --- a/entry/src/main/ets/common/utils/UdpClientByCenter.ts +++ b/entry/src/main/ets/common/utils/UdpClientByCenter.ts @@ -281,10 +281,6 @@ export default class UdpClientByCenter { const newArr = JSON.parse(JSON.stringify(strachArr)) if (strachArr[83] != '4') { console.log('差分状态异常', strachArr[83], strachArr[92]) - this.writeLog({ - time: dateFormat(new Date()), - PLC: `${TAG}差分状态异常,${strachArr[83]},${strachArr[92]}`, - }) } else { globalThis.dialogOpen = false this.chafenFlag = 0 @@ -298,10 +294,6 @@ export default class UdpClientByCenter { this.testIfUdpConnetced(callback) } - async writeLog(param) { - // const fileUtil = new FileUtil(globalThis.context) - // fileUtil.editFile(`${this.folderPath}/plcLog.txt`, JSON.stringify(param)+`\n`) - } async initPath() { // const fileUtil = new FileUtil(globalThis.context) @@ -334,10 +326,6 @@ export default class UdpClientByCenter { lightLineUdp?.send(this.plcUdpError ? arrRedBuffer : (isJudge ? arrGreenBugger : arrBlueBuffer)); if (this.plcUdpError) { num++ - this.writeLog({ - time: dateFormat(new Date()), - PLC: 'plc udp信号丢失', - }) if (num == 3) { getUDP(globalThis.context, true) globalThis.title = 'plc udp信号丢失' diff --git a/entry/src/main/ets/entryability/EntryAbility.ets b/entry/src/main/ets/entryability/EntryAbility.ets index 1bd3dc83..b00d8107 100644 --- a/entry/src/main/ets/entryability/EntryAbility.ets +++ b/entry/src/main/ets/entryability/EntryAbility.ets @@ -8,6 +8,7 @@ import DB from '../common/database/DbSql'; import { initTable } from '../common/service/initable'; import { examPeerOccupy } from "../pages/judgeSDK/api" import { judgeConfig } from '../pages/judgeSDK/utils/judgeConfig'; +import Want from '@ohos.app.ability.Want'; export default class EntryAbility extends UIAbility { async onCreate(want, launchParam) { @@ -24,15 +25,20 @@ export default class EntryAbility extends UIAbility { hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate'); } - onDestroy() { + async onDestroy() { const arrClose = [0x55, 0xaa, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00] const arrCloseBuffer = Array2Byte(arrClose).buffer globalThis?.lightLineUdp?.send(arrCloseBuffer); + let want: Want = { + deviceId: '', + bundleName: 'com.oh.dts', + abilityName: 'ServiceExtAbility' + }; + await this.context.stopServiceExtensionAbility(want) hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy'); } async onWindowStageCreate(windowStage: window.WindowStage) { - // this.context // Main window is created, set main page for this ability hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate'); @@ -40,7 +46,6 @@ export default class EntryAbility extends UIAbility { // console.log("examPeerOccupy", examPeerOccupy()) // }, 5000) - globalThis.carInfo = {} globalThis.examinerInfo = {} globalThis.deviceNo = ''; diff --git a/entry/src/main/ets/pages/Index.ets b/entry/src/main/ets/pages/Index.ets index 6ecaa1c2..6899e731 100644 --- a/entry/src/main/ets/pages/Index.ets +++ b/entry/src/main/ets/pages/Index.ets @@ -19,6 +19,8 @@ import { delPic } from '../common/service/videoService'; import imageBtn from './compontents/imageBtn'; import VoiceAnnounce from './judgeSDK/utils/voiceAnnouncements'; import { examJudgeVersion } from './judgeSDK/api'; +import IdlServiceExtProxy from '../IdlServiceExt/idl_service_ext_proxy'; +import Want from '@ohos.app.ability.Want'; @Entry @Component @@ -39,6 +41,7 @@ struct Index { @State initParamFlag: boolean = false @State fd: number = -1; @State num: number = 0; + private serviceExtProxy: IdlServiceExtProxy private fileHelper = null; private errorDialog: CustomDialogController = new CustomDialogController({ builder: errorMsgDialog({ @@ -76,6 +79,8 @@ struct Index { globalThis.lsh = '1111111111111' globalThis.errorDialog = this.errorDialog globalThis.udpEvent = new UdpEvent(); + await this.startServiceAbility() + getSyncData('MA_SYSSET').then(async (data: any[]) => { data.forEach(async sys => { //判断是否能点开始考试 @@ -89,6 +94,51 @@ struct Index { } + async startServiceAbility() { + let want: Want = { + deviceId: '', + bundleName: 'com.oh.dts', + abilityName: 'ServiceExtAbility' + }; + + await this.context.startServiceExtensionAbility(want).then(() => { + // 成功启动后台服务 + console.log('js-test index.ets Succeeded in starting ServiceExtensionAbility.'); + let self = this; + let options: common.ConnectOptions = { + onConnect(elementName, remote): void { + console.log('js-test index.ets onConnect callback'); + if (remote === null) { + console.log(`js-test index.ets onConnect remote is null`); + return; + } + self.serviceExtProxy = new IdlServiceExtProxy(remote); + globalThis.serviceExtProxy = self.serviceExtProxy + console.log(`js-test index.ets processData, this.serviceExtProxy == `, self.serviceExtProxy); + }, + onDisconnect(elementName): void { + console.log('js-test index.ets onDisconnect callback'); + }, + onFailed(code): void { + console.log('js-test index.ets onFailed callback', JSON.stringify(code)); + } + } + + // 建立连接后返回的Id需要保存下来,在解绑服务时需要作为参数传入 + // let connectionId = context.connectServiceExtensionAbility(want, options); + try { + this.context.connectServiceExtensionAbility(want, options); + } catch (e) { + console.log('js-test index.ets connectServiceExtensionAbility err == ', JSON.stringify(e)); + } + // 成功连接后台服务 + console.log('js-test index.ets connectServiceExtensionAbility success'); + + }).catch((err) => { + console.log(`js-test index.ets Failed to start ServiceExtensionAbility. Code is ${err.code}, message is ${err.message}`); + }); + } + async networkExam(isSingle: boolean = false) { if (this.loading) { return @@ -183,9 +233,7 @@ struct Index { globalThis.singlePlay = false } this.isSingle = globalThis.singlePlay - // this.loading = false this.num = 0 - // const TcpClient: TcpClient =new TcpClient(result[0].tcplocalIp, result[0].tcplocalIpPort,result[0].tcpOppositeIp,result[0].tcpOppositePort) globalThis.lsh = '1111111111111' } @@ -201,11 +249,10 @@ struct Index { } userAuth() { - return new Promise((reslove, reject) => { + return new Promise((resolve, reject) => { const permissions: Array = ["ohos.permission.SET_TIME", "ohos.permission.READ_IMAGEVIDEO", "ohos.permission.DISTRIBUTED_DATASYNC", 'ohos.permission.CONNECTIVITY_INTERNAL', 'ohos.permission.CAMERA', 'ohos.permission.READ_MEDIA', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.FILE_ACCESS_MANAGER']; let context = this.context; let atManager = abilityAccessCtrl.createAtManager(); - // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 atManager.requestPermissionsFromUser(context, permissions).then((data) => { this.initParams() @@ -213,11 +260,9 @@ struct Index { let length: number = grantStatus.length; for (let i = 0; i < length; i++) { if (grantStatus[i] === 0) { - // 用户授权,可以继续访问目标操作 - reslove(true) + resolve(true) } else { reject() - // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限 return; } } @@ -245,7 +290,6 @@ struct Index { await getDeviceInfo(this.context) await getCarInfo() await getUDP2(this.context, false) - getTCP() this.deviceId = globalThis.carInfo.carNo await setCurrentTime(); if (!globalThis.distanceClass) { diff --git a/entry/src/main/ets/pages/compontents/SignDisplayCom.ets b/entry/src/main/ets/pages/compontents/SignDisplayCom.ets index 3d430815..b4673020 100644 --- a/entry/src/main/ets/pages/compontents/SignDisplayCom.ets +++ b/entry/src/main/ets/pages/compontents/SignDisplayCom.ets @@ -198,7 +198,7 @@ export default struct SignDisplayCom { Text('收星数:' + this.signArr[84]).fontColor('#FFB433').fontSize(14 * this.ratio).height(18 * this.ratio) Text('海拔高:' + this.signArr[85]).fontColor('#FFB433').fontSize(14 * this.ratio).height(18 * this.ratio) Text('高度差:' + this.signArr[86]).fontColor('#FFB433').fontSize(14 * this.ratio).height(18 * this.ratio) - Text('龄期:' + this.signArr[87]).fontColor('#FFB433').fontSize(14 * this.ratio).height(18 * this.ratio) + Text('龄期:' + this.signArr[87]).fontColor(Color.Red).fontSize(14 * this.ratio).height(18 * this.ratio) Text('维度因子:' + this.signArr[88]) .fontColor('#FFB433') .fontSize(14 * this.ratio) @@ -262,7 +262,7 @@ export default struct SignDisplayCom { Row() { Flex({ direction: FlexDirection.Column }) { Row() { - if(this.isA2) { + if (this.isA2) { ForEach(["GPS", "GPS2"], (item, i) => { Row() { Text(item).fontColor(this.gpsActive == i ? '#2D3C5A' : '#fff') @@ -299,9 +299,9 @@ export default struct SignDisplayCom { ForEach(this.GPSColum, (item) => { Column() { Text(`${item.key}:${item.value}`) - .fontSize(12 * this.ratio) + .fontSize((item.key === '龄期' ? 20 : 12) * this.ratio) .lineHeight(20 * this.ratio) - .fontColor('#fff') + .fontColor(item.key === '龄期' ? "#6b96f2" : '#fff') }.height(20 * this.ratio).justifyContent(FlexAlign.Start).width('100%') }) } diff --git a/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts b/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts index b93b6040..b9f84b14 100644 --- a/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts +++ b/entry/src/main/ets/pages/judgeSDK/utils/judgeConfig.ts @@ -1,7 +1,7 @@ //考试回放开关 export const judgeConfig = { // 外壳版本号 - version: "2025.05.14.01", + version: "2025.05.15.01", // 是否A1A3共用一车 isUseSameCar: false, //本地目录开关 diff --git a/entry/src/main/module.json5 b/entry/src/main/module.json5 index 067273af..fbae337d 100644 --- a/entry/src/main/module.json5 +++ b/entry/src/main/module.json5 @@ -1,5 +1,3 @@ - - { "module": { "name": "entry", @@ -13,7 +11,16 @@ "deliveryWithInstall": true, "installationFree": false, "pages": "$profile:main_pages", - + "extensionAbilities": [ + { + "name": "ServiceExtAbility", + "icon": "$media:icon", + "description": "service", + "type": "service", + "exported": true, + "srcEntry": "./ets/ServiceExtAbility/ServiceExtAbility.ets" + } + ], "abilities": [ { "name": "EntryAbility", @@ -36,9 +43,13 @@ ] } ], - "requestPermissions":[ - {"name": "ohos.permission.CONNECTIVITY_INTERNAL"}, - {"name": "ohos.permission.SET_TIME"}, + "requestPermissions": [ + { + "name": "ohos.permission.CONNECTIVITY_INTERNAL" + }, + { + "name": "ohos.permission.SET_TIME" + }, { "name": "ohos.permission.INTERNET" }, @@ -135,7 +146,6 @@ { "name": "ohos.permission.STORAGE_MANAGER" }, - { "name": "ohos.permission.GET_BUNDLE_INFO_PRIVILEGED", "reason": "$string:module_desc",