EntryAbility.ets 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395
  1. /**
  2. * 应用主Ability入口文件
  3. * 功能:
  4. * 1. 管理应用生命周期
  5. * 2. 处理窗口创建和尺寸变化
  6. * 3. 响应外部调用请求
  7. * 4. 全局状态管理
  8. */
  9. import UIAbility from '@ohos.app.ability.UIAbility';
  10. import hilog from '@ohos.hilog';
  11. import window from '@ohos.window';
  12. import { AbilityConstant, Want } from '@kit.AbilityKit';
  13. import { BusinessError, emitter } from '@kit.BasicServicesKit';
  14. import { AppUtil, ArrayUtil, GlobalContext, LogUtil, StrUtil } from '@pura/harmony-utils';
  15. import { DemoConstants } from './DemoConstants';
  16. import { EventConstants } from '../common/constants/EventConstants';
  17. import { Utility } from '../common/util/Utility';
  18. import { WXApi, WXEventHandler } from '../common/util/WXApiWrap';
  19. import { systemShare } from '@kit.ShareKit';
  20. import Logger from '../common/util/Logger';
  21. import statusBarManager from '@hms.pcService.statusBarManager';
  22. import StatusBarViewExtensionAbility from '@hms.pcService.StatusBarViewExtensionAbility';
  23. import { SpiderMan } from '@simplepeng/spider-man';
  24. import { smartMobilityCommon } from '@kit.CarKit';
  25. import { url } from '@kit.ArkTS';
  26. import { display } from '@kit.ArkUI';
  27. /**
  28. * 主Ability类,继承自UIAbility
  29. * 负责:
  30. * - 应用初始化
  31. * - 窗口管理
  32. * - 事件分发
  33. */
  34. export default class EntryAbility extends UIAbility {
  35. // UI上下文对象,用于获取窗口信息
  36. private uiContext?: UIContext;
  37. // private awareness: smartMobilityCommon.SmartMobilityAwareness = smartMobilityCommon.getSmartMobilityAwareness();
  38. private awareness: smartMobilityCommon.SmartMobilityAwareness|undefined = canIUse("SystemCapability.CarService.DistributedEngine")?smartMobilityCommon.getSmartMobilityAwareness():undefined;
  39. /**
  40. * 窗口尺寸变化回调函数
  41. * @param windowSize 新的窗口尺寸对象
  42. * 功能:
  43. * 1. 获取最新的窗口断点尺寸
  44. * 2. 更新AppStorage中的尺寸状态
  45. * 3. 记录尺寸变化日志
  46. */
  47. private onWindowSizeChange: (windowSize: window.Size) => void = async (windowSize: window.Size) => {
  48. // 获取宽度断点并更新全局状态
  49. let widthBp: WidthBreakpoint = this.uiContext!.getWindowWidthBreakpoint();
  50. AppStorage.setOrCreate('currentWidthBreakpoint', widthBp);
  51. // 获取高度断点并更新全局状态
  52. let heightBp: HeightBreakpoint = this.uiContext!.getWindowHeightBreakpoint();
  53. AppStorage.setOrCreate('currentHeightBreakpoint', heightBp);
  54. // 记录尺寸变化日志
  55. // LogUtil.info('pura onWindowSizeChange currentHeightBreakpoint= '+heightBp);
  56. // LogUtil.info( 'pura onWindowSizeChange currentWidthBreakpoint= '+widthBp);
  57. AppStorage.setOrCreate('windowWidth', windowSize.width);
  58. AppStorage.setOrCreate('windowHeight', windowSize.height);
  59. if(windowSize.width > windowSize.height){
  60. AppStorage.setOrCreate('isLandscape', true);
  61. }else{
  62. AppStorage.setOrCreate('isLandscape', false);
  63. }
  64. // LogUtil.info('hicar onWindowSizeChange width= '+windowSize.width);
  65. // LogUtil.info( 'hicar onWindowSizeChange height= '+windowSize.height);
  66. };
  67. onAvoidAreaChange = (data: window.AvoidAreaOptions) => {
  68. if (data.type === window.AvoidAreaType.TYPE_SYSTEM) {
  69. let topRectHeight = px2vp(data.area.topRect.height);
  70. AppStorage.setOrCreate('topRectHeight', topRectHeight);
  71. } else if (data.type === window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR) {
  72. let bottomRectHeight = px2vp(data.area.bottomRect.height);
  73. AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
  74. }
  75. }
  76. onDisplayIdChange=(displayId: number)=> {
  77. let curDisplay = display.getDisplayByIdSync(displayId);
  78. console.info('twocold curDisplay 2 = '+curDisplay.name);
  79. if(curDisplay.name =='HiCar'||curDisplay.name =='SuperLauncher'){
  80. AppStorage.setOrCreate('curDisplayIsHiCar', true);
  81. }else{
  82. AppStorage.setOrCreate('curDisplayIsHiCar', false);
  83. }
  84. }
  85. async onCreate(want:Want, launchParam:AbilityConstant.LaunchParam) {
  86. AppStorage.setOrCreate('context', this.context);
  87. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');
  88. // 初始化WebDAV管理器
  89. this.initWebDAV();
  90. setTimeout(async ()=>{
  91. this.loadDoWant(want)
  92. await this.handleParam(want)
  93. },2000)
  94. this.handleWeChatCallIfNeed(want)
  95. this.getHiCarStatus()
  96. }
  97. /**
  98. * 初始化WebDAV管理器
  99. * 功能:
  100. * 1. 设置Context
  101. * 2. 初始化数据库和Preferences
  102. * 3. 创建WebDAV数据库表
  103. * 4. 加载WebDAV账户信息
  104. */
  105. private async initWebDAV() {
  106. try {
  107. Logger.info('heanup EntryAbility', '开始初始化WebDAV管理器');
  108. // 1. 初始化DataBaseUtil
  109. const DataBaseUtil = (await import('../common/util/DataBaseUtil')).DataBaseUtil;
  110. DataBaseUtil.getInstance().setContext(this.context);
  111. // 2. 初始化PreferencesUtil
  112. // const PreferencesUtil = (await import('../common/util/PreferencesUtil')).default;
  113. // PreferencesUtil.getInstance().setContext(this.context);
  114. // 3. 初始化RemoteDriveManager
  115. const RemoteDriveManagerModule = await import('../common/util/RemoteDriveManager');
  116. const webdavManager = RemoteDriveManagerModule.RemoteDriveManager.getInstance();
  117. webdavManager.setContext(this.context);
  118. // 4. 创建WebDAV数据库表
  119. await webdavManager.createWebDavTableInDB();
  120. // 5. 从数据库加载账户
  121. await webdavManager.queryWebDavAccountsFromDB();
  122. // 6. 加载历史数据(如果有迁移需求)
  123. await webdavManager.loadInfo();
  124. Logger.info('heanup EntryAbility', 'WebDAV管理器初始化成功');
  125. } catch (error) {
  126. Logger.error('heanup EntryAbility', `WebDAV管理器初始化失败: ${error}`);
  127. }
  128. }
  129. async onNewWant(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {
  130. hilog.info(0x0000, 'testTag', `onNewWant, want=${JSON.stringify(want)}`);
  131. super.onNewWant(want, launchParam);
  132. this.loadDoWant(want)
  133. await this.handleParam(want)
  134. this.handleWeChatCallIfNeed(want)
  135. }
  136. private handleWeChatCallIfNeed(want: Want) {
  137. WXApi.handleWant(want, WXEventHandler)
  138. }
  139. //处理其他app点击其他应用打开播放器播放视频或者音频
  140. loadDoWant(want: Want){
  141. // console.info('onecold KnockController 碰一碰 want ='+JSON.stringify(want));
  142. let uri = want.uri;
  143. if (uri == null || uri == undefined|| StrUtil.isEmpty(uri)) {
  144. console.info('uri is invalid');
  145. return;
  146. }
  147. hilog.info(0x0000, 'testTag', `onCreate or onNewWant, uri=${uri}`);
  148. this.doSendEmit(uri)
  149. }
  150. //广播通知打开播放器播放视频或者音频
  151. doSendEmit(uri:string){
  152. setTimeout(async ()=>{
  153. let eventData: emitter.EventData = {
  154. data: {
  155. message: uri
  156. }
  157. };
  158. if(Utility.isMeidaByExtension(uri)){
  159. emitter.emit({ eventId: EventConstants.EVENT_AUDIO_OPEN }, eventData); // 发送音频打开广播事件
  160. }else{
  161. emitter.emit({ eventId: EventConstants.EVENT_VIDEO_OPEN }, eventData); // 发送视频打开广播事件
  162. }
  163. },300)
  164. }
  165. // 华为分享拉起接收 处理分享数据
  166. // 1. 改造 handleParam 为异步函数,让其返回 Promise
  167. async handleParam(want: Want) {
  168. try {
  169. // 通过 await 等待异步操作完成
  170. const data = await systemShare.getSharedData(want);
  171. const records = data.getRecords();
  172. let uri = want.uri;
  173. for (const record of records) {
  174. if (record.uri) {
  175. uri = record.uri;
  176. this.doSendEmit(uri)
  177. break;
  178. }
  179. }
  180. } catch (error) {
  181. const businessError = error as BusinessError;
  182. console.error(`Failed: Code ${businessError.code}, ${businessError.message}`);
  183. }
  184. }
  185. onDestroy() {
  186. try {
  187. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onDestroy');
  188. if(this.awareness){
  189. let types: smartMobilityCommon.SmartMobilityType[] = [smartMobilityCommon.SmartMobilityType.CAR_HOP];
  190. // 出行连接状态回调函数
  191. const callBack = (info: smartMobilityCommon.SmartMobilityInfo) => {
  192. hilog.info(0x0000, 'Received smart mobility info: ', JSON.stringify(info));
  193. };
  194. // 解注册智慧出行连接状态的监听 示例2
  195. this.awareness.off('smartMobilityStatus', types, callBack);
  196. }
  197. }catch (error) {
  198. console.error(`Failed to getHiCarStatus: ${error.code}, message: ${error.message}`);
  199. }
  200. }
  201. onWindowStageCreate(windowStage: window.WindowStage) {
  202. // Main window is created, set main page for this ability
  203. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
  204. SpiderMan.init();
  205. AppUtil.init(this.context);
  206. //1.获取应用主窗口。
  207. let windowClass: window.Window | null = null;
  208. windowStage.getMainWindow((err: BusinessError, data) => {
  209. windowClass = data;
  210. // LogUtil.info( 'getMainWindow = ');
  211. globalThis.windowClass = data // 赋值给全局变量windowClass
  212. let curDisplay = display.getDisplayByIdSync(windowClass.getWindowProperties().displayId);
  213. console.info('twocold curDisplay = '+curDisplay.name);
  214. if(curDisplay.name =='HiCar'||curDisplay.name =='SuperLauncher'){
  215. AppStorage.setOrCreate('curDisplayIsHiCar', true);
  216. }else{
  217. AppStorage.setOrCreate('curDisplayIsHiCar', false);
  218. }
  219. windowClass.setWindowLayoutFullScreen(true).then(() => {
  220. console.info('Succeeded in setting the window layout to full-screen mode.');
  221. }).catch((e: BusinessError) => {
  222. console.error('Failed to set the window layout to full-screen mode. Cause:' + JSON.stringify(e));
  223. })
  224. // let avoidArea = windowClass.getWindowAvoidArea(window.AvoidAreaType.TYPE_SYSTEM)
  225. // let topRectHeight = px2vp(avoidArea.topRect.height);
  226. // AppStorage.setOrCreate('topRectHeight', topRectHeight);
  227. let type = window.AvoidAreaType.TYPE_NAVIGATION_INDICATOR; // 以导航条避让为例
  228. let avoidArea = windowClass.getWindowAvoidArea(type);
  229. let bottomRectHeight = px2vp(avoidArea.bottomRect.height); // 获取到导航条区域的高度
  230. AppStorage.setOrCreate('bottomRectHeight', bottomRectHeight);
  231. type = window.AvoidAreaType.TYPE_SYSTEM; // 以状态栏避让为例
  232. avoidArea = windowClass.getWindowAvoidArea(type);
  233. let topRectHeight = px2vp(avoidArea.topRect.height) // 获取状态栏区域高度
  234. AppStorage.setOrCreate('topRectHeight', topRectHeight);
  235. LogUtil.info('onecold topRectHeight = '+topRectHeight);
  236. windowClass.on('avoidAreaChange', this.onAvoidAreaChange)
  237. windowClass.on('displayIdChange', this.onDisplayIdChange)
  238. })
  239. AppStorage.setOrCreate('windowStage',windowStage);
  240. GlobalContext.getContext().setObject('windowClass',windowClass)
  241. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageCreate');
  242. windowStage.loadContent('pages/SplashIndex', (err, data) => {
  243. if (err.code) {
  244. hilog.error(0x0000, 'testTag', 'Failed to load the content. Cause: %{public}s', JSON.stringify(err) ?? '');
  245. return;
  246. }
  247. //一多断点开发
  248. windowStage.getMainWindow().then((data: window.Window) => {
  249. this.uiContext = data.getUIContext();
  250. let widthBp: WidthBreakpoint = this.uiContext.getWindowWidthBreakpoint();
  251. let heightBp: HeightBreakpoint = this.uiContext.getWindowHeightBreakpoint();
  252. AppStorage.setOrCreate('currentWidthBreakpoint', widthBp);
  253. AppStorage.setOrCreate('currentHeightBreakpoint', heightBp);
  254. LogUtil.info( 'getMainWindow currentHeightBreakpoint= '+heightBp);
  255. LogUtil.info( 'getMainWindow currentWidthBreakpoint= '+widthBp);
  256. data.on('windowSizeChange', this.onWindowSizeChange);
  257. AppStorage.setOrCreate('windowWidth', data.getWindowProperties().windowRect.width);
  258. AppStorage.setOrCreate('windowHeight', data.getWindowProperties().windowRect.height);
  259. if(data.getWindowProperties().windowRect.width > data.getWindowProperties().windowRect.height){
  260. AppStorage.setOrCreate('isLandscape', true);
  261. }else{
  262. AppStorage.setOrCreate('isLandscape', false);
  263. }
  264. // LogUtil.info('hicar getMainWindow width= '+data.getWindowProperties().windowRect.width);
  265. // LogUtil.info( 'hicar getMainWindow height= '+data.getWindowProperties().windowRect.height);
  266. }).catch((err: BusinessError) => {
  267. console.error(`Failed to obtain the main window. Cause code: ${err.code}, message: ${err.message}`);
  268. });
  269. hilog.info(0x0000, 'testTag', 'Succeeded in loading the content. Data: %{public}s', JSON.stringify(data) ?? '');
  270. });
  271. DemoConstants.windowStage = windowStage
  272. }
  273. onWindowStageDestroy() {
  274. // Main window is destroyed, release UI related resources
  275. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onWindowStageDestroy');
  276. }
  277. onForeground() {
  278. // Ability has brought to foreground
  279. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onForeground');
  280. }
  281. onBackground() {
  282. // Ability has back to background
  283. hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onBackground');
  284. }
  285. getHiCarStatus(){
  286. try {
  287. if (!this.awareness){
  288. this.awareness=canIUse("SystemCapability.CarService.DistributedEngine")?smartMobilityCommon.getSmartMobilityAwareness():undefined;
  289. }
  290. console.log('enter getHiCarStatus,awareness:'+JSON.stringify(this.awareness));
  291. if(this.awareness){
  292. console.log('enter awareness');
  293. // 业务类型
  294. let types: smartMobilityCommon.SmartMobilityType[] = [smartMobilityCommon.SmartMobilityType.HICAR];
  295. // 获取出行业务连接状态
  296. let info = this.awareness.getSmartMobilityStatus(types[0]);
  297. hilog.info(0x0000, 'getHiCarStatus info: ', JSON.stringify(info));
  298. if(info&&info.status==1){
  299. AppStorage.setOrCreate('isHiCarStatus', true);
  300. }else{
  301. AppStorage.setOrCreate('isHiCarStatus', false);
  302. }
  303. // 出行连接状态回调函数
  304. const callBack = (info: smartMobilityCommon.SmartMobilityInfo) => {
  305. hilog.info(0x0000, 'getHiCarStatus Received smart mobility info: ', JSON.stringify(info));
  306. if(info&&info.status==1){
  307. AppStorage.setOrCreate('isHiCarStatus', true);
  308. }else{
  309. AppStorage.setOrCreate('isHiCarStatus', false);
  310. const eventData: emitter.EventData = {};
  311. emitter.emit({ eventId: EventConstants.EVENT_PLAY_PAUSE }, eventData); // 发送广播通知更新doSwipBack
  312. }
  313. this.sendChangeEvent()
  314. };
  315. // 注册智慧出行连接状态的监听
  316. this.awareness.on('smartMobilityStatus', types, callBack);
  317. }else{
  318. AppStorage.setOrCreate('isHiCarStatus', false);
  319. }
  320. }catch (error) {
  321. console.error(`Failed to getHiCarStatus: ${error.code}, message: ${error.message}`);
  322. }
  323. }
  324. //发送广播通知更新UI
  325. sendChangeEvent() {
  326. const eventData: emitter.EventData = {};
  327. emitter.emit({ eventId: EventConstants.EVENT_SETTING_UPDATE }, eventData); // 发送广播通知更新doSwipBack
  328. }
  329. }