如何做網(wǎng)站frontpageseo方案
接入HarmonyOS NEXT Push 推送功能,相比于 Android 真的是簡單太多。不再需要適配接入各個廠家的推送 SDK,真是舒服。
1.開通推送服務與配置Client ID
1.1 創(chuàng)建應用獲取Client ID
按照官方文檔來就可以了:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/push-config-setting-V5
1.2 配置Client ID
在項目模塊級別下的src/main/module.json5(例如entry/src/main/module.json5)中,新增metadata并配置client_id,如下所示:
"module": {"name": "entry","type": "xxx","description": "xxxx","mainElement": "xxxx","deviceTypes": [],"pages": "xxxx","abilities": [],// 配置如下信息"metadata": [ {"name": "client_id",// 配置為步驟1中獲取的Client ID"value": "xxxxxx" }]
}
2.獲取 push token 并上傳
import { pushService } from '@kit.PushKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { UIAbility, AbilityConstant, Want } from '@kit.AbilityKit';export default class EntryAbility extends UIAbility {async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {// 獲取Push Tokentry {const pushToken: string = await pushService.getToken();hilog.info(0x0000, 'testTag', 'Succeeded in getting push token: %{public}s', pushToken);} catch (err) {let e: BusinessError = err as BusinessError;hilog.error(0x0000, 'testTag', 'Failed to get push token: %{public}d %{public}s', e.code, e.message);}// 上報Push Token 到服務器uploadPushToken()}
}
3. AAID
上傳 push token 時,可以使用 AAID 當作 識別設備的唯一標識,即類是 Android 中的 deviceId 使用。i按照官方文檔說明:
AAID(Anonymous Application Identifier):應用匿名標識符,標識運行在移動智能終端設備上的應用實例,只有該應用實例才能訪問該標識符,它只存在于應用的安裝期,總長度32位。與無法重置的設備級硬件ID相比,AAID具有更好的隱私權(quán)屬性。
AAID具有以下特性:
匿名化、無隱私風險:AAID和已有的任何標識符都不關(guān)聯(lián),并且每個應用只能訪問自己的AAID。
同一個設備上,同一個開發(fā)者的多個應用,AAID取值不同。
同一個設備上,不同開發(fā)者的應用,AAID取值不同。
不同設備上,同一個開發(fā)者的應用,AAID取值不同。
不同設備上,不同開發(fā)者的應用,AAID取值不同。
場景介紹
AAID會在包括但不限于下述場景中發(fā)生變化:
應用卸載重裝。
應用調(diào)用刪除AAID接口。
用戶恢復出廠設置。
用戶清除應用數(shù)據(jù)。
獲取 AAID :
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { AAID } from '@kit.PushKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { hilog } from '@kit.PerformanceAnalysisKit';export default class EntryAbility extends UIAbility {// 入?yún)ant與launchParam并未使用,為初始化項目時自帶參數(shù)async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {// 獲取AAIDtry {const aaid: string = await AAID.getAAID();hilog.info(0x0000, 'testTag', 'Succeeded in getting AAID.');} catch (err) {let e: BusinessError = err as BusinessError;hilog.error(0x0000, 'testTag', 'Failed to get AAID: %{public}d %{public}s', e.code, e.message);}}
}
4. 喚醒應用
后端在推送消息的時候,數(shù)據(jù)結(jié)構(gòu):
// Request URL
POST https://push-api.cloud.huawei.com/v3/[projectId]/messages:send// Request Header
Content-Type: application/json
Authorization: Bearer eyJr*****OiIx---****.eyJh*****iJodHR--***.QRod*****4Gp---****
push-type: 0// Request Body
{"payload": {"notification": {"category": "MARKETING","title": "普通通知標題","body": "普通通知內(nèi)容","clickAction": {"actionType": 0,"data": {"testKey": "testValue"}}}},"target": {"token": ["IQAAAA**********4Tw"]},"pushOptions": {"testMessage": true}
}
我們主要關(guān)注 clickAction 這個結(jié)構(gòu):
actionType:點擊消息的動作,在后端push-type: 0 即表示 Aler消息時:
0:打開應用首頁
1:打開應用自定義頁面
當然還有其他類型,如下:
但是一般我們只關(guān)注 push-type: 0 的情況即可。
詳情請參見ClickAction。
4.1 通知權(quán)限申請
判斷是否獲得通知權(quán)限:
notificationManager.isNotificationEnabled()
如果沒有,則請求通知欄權(quán)限:
private requestNotificationPermission = () => {notificationManager.isNotificationEnabled().then((data: boolean) => {console.info("isNotificationEnabled success, data: " + JSON.stringify(data));if(!data){notificationManager.requestEnableNotification().then(() => {console.info(`[ANS] requestEnableNotification success`);}).catch((err : BusinessError) => {if(1600004 == err.code){console.info(`[ANS] requestEnableNotification refused`);} else {console.error(`[ANS] requestEnableNotification failed, code is ${err.code}, message is ${err.message}`);}});}}).catch((err : BusinessError) => {console.error(`isNotificationEnabled fail: ${JSON.stringify(err)}`);});}
4.2 跳轉(zhuǎn)到應用
后端推送消息配置 “actionType”: 0,點擊通知欄消息后,即可拉起應用
4.2 跳轉(zhuǎn)到指定頁面
后端推送消息配置 “actionType”: 1。
這個時候就有兩種指定頁面的方式:
方式1: 指定 action
方式2:指定 uri
4.2.1 Action 跳轉(zhuǎn)到指定頁面
需要在module.json5 中配置 abilibies:
"abilities": [{"name": "MainAbility","launchType": "singleton","srcEntry": "./ets/abilities/MainAbility.ets","description": "$string:MainAbility_desc","icon": "$media:icon","label": "$string:MainAbility_label","exported": true,"startWindowIcon": "$media:icon","startWindowBackground": "$color:startWindowBackgroundColor","skills": [{"entities": ["entity.system.home"],"actions": ["action.system.home",],}, {"actions": ["https://www.huawei.com/test"]}]},
我配置的 action 是:
{"actions": ["https://www.huawei.com/test"]}
細心的你可能會發(fā)現(xiàn)這個ability 上面還有一個配置:
{"entities": ["entity.system.home"],"actions": ["action.system.home",],}
千萬別動,這個是指定啟動的 Ability 的配置,如果你指定的 Abiblity 不是啟動頁的 Ability ,則沒有這個問題。
4.2.2 uri 跳轉(zhuǎn)到指定頁面
"abilities": [{"name": "MainAbility","launchType": "singleton","srcEntry": "./ets/abilities/MainAbility.ets","description": "$string:MainAbility_desc","icon": "$media:icon","label": "$string:MainAbility_label","exported": true,"startWindowIcon": "$media:icon","startWindowBackground": "$color:startWindowBackgroundColor","skills": [{"actions": ["",],"uris": [{"scheme": "https","host": "www.huawei.com","path": "test"},]}]},
記住 actions 里的內(nèi)容必須是 “” 空的,不然會去適配 action。
4.3 參數(shù)解析
拉起應用后,肯定少不了參數(shù)的解析和傳遞。
{"payload": {"notification": {"category": "MARKETING","title": "普通通知標題","body": "普通通知內(nèi)容","clickAction": {"actionType": 0,"data": {"testKey": "testValue"}}}},"target": {"token": ["IQAAAA**********4Tw"]},"pushOptions": {"testMessage": true}
}
這里的 “data”: {“testKey”: “testValue”} 就是我們需要解析的參數(shù)。
解析參數(shù)在兩個地方需要處理,
情況1:應用未啟動,走 UIAbility 的 onCreate(want: Want)
情況1:應用啟動了,在前臺或后臺,走 UIAbility 的 onNewWant(want: Want)
而這兩個方法都有一個參數(shù) want: Want 。我們的參數(shù)也就在這個參數(shù)里面了。
4.3.1 onNewWant
onNewWant() 就比較簡單了,直接解析參數(shù)后,掉用 router 到指定頁面即可:
onNewWant(want: Want): void {if (want?.uri != null && want.uri.length > 0) {router.pushUrl({url: want.parameters?.['page'] as string,params: want.parameters})}// 獲取消息中傳遞的data數(shù)據(jù)hilog.info(0x0000, 'testTag', 'onNewWant --> Succeeded in getting message data: %{public}s', JSON.stringify(want.parameters));}
可以看到,我這里把需要跳轉(zhuǎn)到頁面的 page 路徑傳遞過來了,這樣就方便多了。
4.3.2 onCreate()
onCreate 處理起來就會比較麻煩,因為涉及到參數(shù)的傳遞。
在 onCreate 解析參數(shù)
localStorage = new LocalStorage();async onCreate(want: Want): Promise<void> {// 獲取消息中傳遞的data數(shù)據(jù)if (want?.uri != null && want.uri.length > 0) {let routePage = want.parameters?.['page'] as string;let routePageParam = want.parameters as Record<string, object>this.localStorage.clear()this.localStorage.setOrCreate('page', routePage)this.localStorage.setOrCreate('params', routePageParam)hilog.info(0x0000, 'testTag', 'onCreate --> page: ', ', page: ' + this.routePage);}
因為是應用未啟動,所以會走 onWindowStageCeate(),假設我們的啟動頁是 ‘pages/MainPage
onWindowStageCreate(windowStage: window.WindowStage): void {windowStage.loadContent('pages/MainPage', this.localStorage);}
在 loadContent 方法中,把我們的 localStorage 傳遞過去,剩下的參數(shù)其他頁面自己去解析了。
4.4 啟動頁解析 LocalStorage 參數(shù)
關(guān)于LocalStorage的知識點可以看這里
let storage = LocalStorage.getShared()
@Entry(storage)
@Component
struct MainPage {@State notificationState: string = ''private clickBackTimeRecord: number = 0;@LocalStorageProp('page') page: string = ''@LocalStorageProp('params') params: Record<string, object> = {}
}
差不多就這么多,如果指定喚起的 UIAbility 不是 main Ability 的話,稍微有點不一樣,不過也是大同小異了。
5. Notification 測試
有時候我們不方便用華為后臺推送測試的話,可以自己發(fā)送通知到通知欄,也是一樣的,甚至更方便。因為華為推送后臺,如果是指定啟動應用內(nèi)頁面的話,action 和 uri 都是無法發(fā)送參數(shù)的。但是你硬是要用 uri 拼接參數(shù)傳遞過來,然后自己再解析 uri 中的參數(shù),也不是不行,就是太麻煩了。
那么自己發(fā)送通知到通知欄就方便多了,還可以傳遞 data 參數(shù)。上代碼:
private publishNotification() {// 通過WantAgentInfo的operationType設置動作類型let wantAgentInfo: wantAgent.WantAgentInfo = {wants: [{deviceId: '',bundleName: 'com.huawei.demo',abilityName: 'MainAbility',action: '', // "https://www.huawei.com/test",entities: [],uri: "https://www.huawei.com/test", parameters: {page: 'pages/ClickActionInnerPage',id: '123456'}}],operationType: wantAgent.OperationType.START_ABILITY,requestCode: 0,wantAgentFlags:[wantAgent.WantAgentFlags.CONSTANT_FLAG]};// 創(chuàng)建WantAgentwantAgent.getWantAgent(wantAgentInfo, (err: BusinessError, data: WantAgent) => {if (err) {console.error(`Failed to get want agent. Code is ${err.code}, message is ${err.message}`);return;}console.info('Succeeded in getting want agent.');let notificationRequest: notificationManager.NotificationRequest = {id: 1,content: {notificationContentType: notificationManager.ContentType.NOTIFICATION_CONTENT_BASIC_TEXT, // 普通文本類型通知normal: {title: '我是標題黨',text: 'HarmonyOS 論壇中有研發(fā)人員求助,反饋通知沒有沒有聲音,因此在真機上驗證了一下,果不其然,沒有通知的提示音',additionalText:'通知的附加內(nèi)容',}},notificationSlotType: notificationManager.SlotType.SOCIAL_COMMUNICATION,wantAgent: data,};notificationManager.publish(notificationRequest, (err: BusinessError) => {if (err) {console.error(`Failed to publish notification. Code is ${err.code}, message is ${err.message}`);return;}console.info('Succeeded in publishing notification.');});});}
同樣,跟之前說的一樣, 如果使用 uri 指定跳轉(zhuǎn)頁面的話,action 要是空, bundleName 和 abilityName 必須要填對,也就是我們的包名和指定需要啟動的 UIAbility 。也就是上面我說過的,不一定是要 MainUIAbility作為啟動的Ability 的,是可以指定的哦。
希望對你有幫助。