在真机设备上,小艺建议卡片不会实时刷新。可以通过点击卡片中的服务,重新返回到桌面后,进行卡片刷新。
意图框架是HarmonyOS系统级的意图标准体系。将应用和元服务的业务功能智能分发给不同的系统入口,以“音乐播放”为例,HarmonyOS将业务分发给“小艺建议”,提供了桌面大流量曝光,同时为开发者实现业务增长。习惯推荐类别下典型场景主要分为常用接续、常用复访以及常用推新三大类。比如“音乐播放”就属于常用接续场景。具体可参考习惯推荐场景体验。
接入意图框架首先需要确定特性类别和具体意图,详细请参见Intents Kit接入流程。
本文以“音乐播放”意图为例,详细讲解意图接入与开发全过程。
以“音乐播放”为例,从意图注册、意图共享以及意图调用三大块介绍意图运行的开发过程。如果应用支持播放功能并且需要实现推荐播放接续,例如音乐、长视频以及课程的播放接续,可以参考本文。首先需要在设置中开启意图框架调试,如下图所示。确保意图框架调试开启且在界面成功展示设备支持测试应用。

开发步骤

- {
- "insightIntents": [
- {
- "intentName": "PlayMusic",
- "domain": "MusicDomain",
- "intentVersion": "1.0.1",
- "srcEntry": "./ets/entryability/InsightIntentExecutorImpl.ets",
- "uiAbility": {
- "ability": "EntryAbility",
- "executeMode": [
- "background",
- "foreground"
- ]
- }
- },
- {
- "intentName": "PlayMusicList",
- "domain": "MusicDomain",
- "intentVersion": "1.0.1",
- "srcEntry": "./ets/entryability/InsightIntentExecutorImpl.ets",
- "uiAbility": {
- "ability": "EntryAbility",
- "executeMode": [
- "background",
- "foreground"
- ]
- }
- }
- ]
- }
- [
- {
- "intentName": "PlayMusic",
- "intentVersion": "1.0",
- "identifier": "52dac3b0-6520-4974-81e5-25f0879449b5",
- "intentActionInfo": {
- "actionMode": "EXECUTED",
- "executedTimeSlots": {
- "executedStartTime": 1637393112000,
- "executedEndTime": 1637393212000
- },
- "currentPercentage": 50
- },
- "intentEntityInfo": {
- "entityName": "Music",
- "entityId": "C10194368",
- "entityGroupId": "C10194321312",
- "displayName": "红颜如霜",
- "description": "NA",
- "logoURL": "https://www-file.huawei.com/-/media/corporate/images/home/logo/huawei_logo.png",
- "keywords": [
- "华为音乐",
- "化妆"
- ],
- "rankingHint": 99,
- "expirationTime": 1637393212000,
- "metadataModificationTime": 1637393212000,
- "activityType": [
- "1",
- "2",
- "3"
- ],
- "artist": [
- "测试歌手1",
- "测试歌手2"
- ],
- "lyricist": [
- "测试词作者1",
- "测试词作者2"
- ],
- "composer": [
- "测试曲作者1",
- "测试曲作者2"
- ],
- "albumName": "测试专辑",
- "duration": 244000,
- "playCount": 100000,
- "musicalGenre": [
- "流行",
- "话语",
- "抖音",
- "00后"
- ],
- "isPublicData": false
- }
- },
- {
- "intentName": "PlayMusicList",
- "intentVersion": "1.0",
- "identifier": "52dac3b0-6520-4974-81e5-25f0879449b5",
- "intentActionInfo": {
- "actionMode": "EXECUTED",
- "executedTimeSlots": {
- "executedStartTime": 1637393112000,
- "executedEndTime": 1637393212000
- },
- "currentPercentage": 50
- },
- "intentEntityInfo": {
- "entityName": "MusicList",
- "entityId": "C10194368",
- "entityGroupId": "C10194321312",
- "displayName": "测试歌单",
- "description": "这是xxx歌单",
- "logoURL": "https://www-file.huawei.com/-/media/corporate/images/home/logo/huawei_logo.png",
- "keyWords": [
- "抖音",
- "动感"
- ],
- "rankingHint": 99,
- "expirationTime": 1637393212000,
- "metadataModificationTime": 1637393212000,
- "activityType": [
- "1",
- "2",
- "3"
- ],
- "isPublicData": false,
- "briefDescription": "这是xxx歌单,来自xxx,是xxx风格",
- "artist": [
- "测试歌手1",
- "测试歌手2"
- ],
- "numberOfSongs": 20,
- "type": "1",
- "creator": "测试创建者",
- "createDate": "2023-10-08T08:00:00+08:00",
- "musicNameList": [
- "测试歌曲1",
- "测试歌曲2"
- ],
- "playCount": 30,
- "musicalGenre": [
- "流行",
- "华语",
- "抖音",
- "00后"
- ]
- }
- }
- ]

- static async shareIntent(context: Context, input: string): Promise<string> {
- Logger.debug(TAG, 'shareIntent');
- try {
- let insightIntents: insightIntent.InsightIntent[] = JSON.parse(input);
- if (!insightIntents || insightIntents.length === 0) {
- Logger.error(TAG, 'shareIntent: json invalid.');
- return 'shareIntent: json invalid.';
- }
- return await insightIntent.shareIntent(context, insightIntents).then(() => {
- Logger.info(TAG, 'shareIntent success');
- return 'share intent success';
- }, (err: BusinessError) => {
- Logger.error(TAG, `shareIntent error message: ${JSON.stringify(err)}`);
- return `shareIntent error message: ${JSON.stringify(err)}`;
- });
- } catch (err) {
- Logger.error(TAG, 'shareIntent fail', err);
- }
- return Promise.reject('shareIntent fail');
- }
前后台模式 | 启动模式 | 触发生命周期 | |
|---|---|---|---|
foreground | 冷启动 | onCreate->onWindowStageCreate->onExecuteInUIAbilityForegroundMode | |
热启动 | onNewWant->onExecuteInUIAbilityForegroundMode | ||
background | 冷启动 | onCreate->onExecuteInUIAbilityBackgroundMode | |
热启动 | onExecuteInUIAbilityBackgroundMode |
本示例中采取foreground模式,可以在onCreate()或者onNewWant()解析want和launchParam。并将参数result存储在AppStorage中。如果是在真实开发中意图调用传参字段可以在开发前和接口方协商。
- onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
- Logger.info(TAG, 'onCreate');
- if (want.parameters?.['result']) {
- this.result = want.parameters?.['result'] as string;
- }
- }
want解析完毕后,会触发onExecuteInUIAbilityForegroundMode()方法进行真正逻辑处理,根据意图名称去分发处理方法并且返回一个Promise,成功调用code返回0,失败时返回-1。
- /**
- * Override the method to execute the intent in the foreground UIAbility.
- *
- * @param name Intent name.
- * @param param Intent parameters.
- * @param pageLoader Window.
- * @returns Intent call result.
- */
- onExecuteInUIAbilityForegroundMode(name: string, param: Record<string, Object>, pageLoader: window.WindowStage):
- Promise<insightIntent.ExecuteResult> {
- Logger.info(TAG, `onExecuteInUIAbilityForegroundMode name: ${name}, param: ${JSON.stringify(param)}`);
- // Distribute the processing logic based on the intent name.
- switch (name) {
- case InsightIntentExecutorImpl.PLAY_MUSIC:
- return this.playMusic(param, pageLoader);
- case InsightIntentExecutorImpl.PLAY_MUSIC_LIST:
- return this.playMusicList(param, pageLoader);
- default:
- break;
- }
-
- return Promise.resolve({
- code: -1,
- result: {
- message: 'unknown intent'
- }
- } as insightIntent.ExecuteResult)
- }
最后完成playMusic()的功能逻辑,小艺建议基于共享数据生成推荐卡片,点击卡片后将上述shareIntent.json定义的实体ID值传递到应用中。
- /**
- * Implement the music playback function.
- *
- * @param param Intent parameters.
- * @param pageLoader Window.
- */
- private playMusic(param: Record<string, Object>,
- pageLoader: window.WindowStage): Promise<insightIntent.ExecuteResult> {
- return new Promise((resolve, reject) => {
- let para: Record<string, string> = {
- 'result': `intent execute success, entityId: ${param.entityId}`
- };
- let localStorage: LocalStorage = new LocalStorage(para);
- // TODO Implement an intent call.
- pageLoader.loadContent('pages/Index', localStorage)
- .then(() => {
- // TODO The intent is called successfully.
- Logger.info(TAG, "Intent execute success");
- resolve({
- code: 0,
- result: {
- message: 'Intent execute success'
- }
- });
- })
- .catch((err: BusinessError) => {
- // TODO Handle the failure if the intent fails to be called.
- Logger.error(TAG, `Intent execute failed: ${JSON.stringify(err)}`);
- resolve({
- code: -1,
- result: {
- message: 'Intent execute failed'
- }
- })
- });
- })
- }
如果想删除掉意图,可以调用deleteIntent(),在注册文件只有一个意图的情况下卡片入口会消失。运行效果如下图所示。

在真机设备上,小艺建议卡片不会实时刷新。可以通过点击卡片中的服务,重新返回到桌面后,进行卡片刷新。