邢臺網(wǎng)站建設(shè)包括哪些專業(yè)北京seo公司
1 應(yīng)用內(nèi)支付
開發(fā)步驟
步驟一:判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付
在使用應(yīng)用內(nèi)支付之前,您的應(yīng)用需要向IAP Kit發(fā)送queryEnvironmentStatus請求,以此判斷用戶當(dāng)前登錄的華為帳號所在的服務(wù)地是否在IAP Kit支持結(jié)算的國家/地區(qū)中。
// pages/Index.ets
/*** @description 應(yīng)用內(nèi)支付服務(wù)示例-消耗型商品* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-01*/
import { common } from '@kit.AbilityKit'
import { iap } from '@kit.IAPKit';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {private context: common.UIAbilityContext = {} as common.UIAbilityContext;@State querying: boolean = true;@State queryingFailed: boolean = false;@State productInfoArray: iap.Product[] = [];@State queryFailedText: string = "查詢失敗!";showLoadingPage() {this.queryingFailed = false;this.querying = true;}showFailedPage(failedText?: string) {if (failedText) {this.queryFailedText = failedText;}this.queryingFailed = true;this.querying = false;}showNormalPage() {this.queryingFailed = false;this.querying = false;}aboutToAppear(): void {this.showLoadingPage();this.context = getContext(this) as common.UIAbilityContext;this.onCase();}async onCase() {this.showLoadingPage();const queryEnvCode = await this.queryEnv();if (queryEnvCode !== 0) {let queryEnvFailedText = "當(dāng)前應(yīng)用不支持IAP Kit服務(wù)!";if (queryEnvCode === iap.IAPErrorCode.ACCOUNT_NOT_LOGGED_IN) {queryEnvFailedText = "請通過桌面設(shè)置入口登錄華為賬號后再次嘗試!";}this.showFailedPage(queryEnvFailedText);return;}}// 判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付。async queryEnv(): Promise<number> {try {console.log("IAPKitDemo queryEnvironmentStatus begin.");await iap.queryEnvironmentStatus(this.context);return 0;} catch (error) {promptAction.showToast({message: "IAPKitDemo queryEnvironmentStatus failed. Cause: " + JSON.stringify(error)})return error.code;}}build() {...}
}
步驟二:確保權(quán)益發(fā)放
用戶購買商品后,開發(fā)者需要及時發(fā)放相關(guān)權(quán)益。但實際應(yīng)用場景中,若出現(xiàn)異常(網(wǎng)絡(luò)錯誤、進(jìn)程被中止等)將導(dǎo)致應(yīng)用無法知道用戶實際是否支付成功,從而無法及時發(fā)放權(quán)益,即出現(xiàn)掉單情況。為了確保權(quán)益發(fā)放,您需要在以下場景檢查用戶是否存在已購未發(fā)貨的商品:
- 應(yīng)用啟動時。
- 購買請求返回1001860001時。
- 購買請求返回1001860051時。
如果存在已購未發(fā)貨商品,則發(fā)放相關(guān)權(quán)益,然后向IAP Kit確認(rèn)發(fā)貨,完成購買。
// pages/Index.ets
/*** @description 應(yīng)用內(nèi)支付服務(wù)示例-消耗型商品* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-01*/
import { common } from '@kit.AbilityKit'
import { iap } from '@kit.IAPKit';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {private context: common.UIAbilityContext = {} as common.UIAbilityContext;@State querying: boolean = true;@State queryingFailed: boolean = false;@State productInfoArray: iap.Product[] = [];@State queryFailedText: string = "查詢失敗!";showLoadingPage() {...}showFailedPage(failedText?: string) {...}showNormalPage() {...}aboutToAppear(): void {...}async onCase() {...await this.queryPurchase();}// 判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付。async queryEnv(): Promise<number> {...}async queryPurchase() {console.log("IAPKitDemo queryPurchase begin.");const queryPurchaseParam: iap.QueryPurchasesParameter = {productType: iap.ProductType.CONSUMABLE,queryType: iap.PurchaseQueryType.UNFINISHED};const result: iap.QueryPurchaseResult = await iap.queryPurchases(this.context, queryPurchaseParam);// 處理訂單信息if (result) {const purchaseDataList: string[] = result.purchaseDataList;if (purchaseDataList === undefined || purchaseDataList.length <= 0) {console.log("IAPKitDemo queryPurchase, list empty.");return;}for (let i = 0; i < purchaseDataList.length; i++) {const purchaseData = purchaseDataList[i];const jwsPurchaseOrder = (JSON.parse(purchaseData) as PurchaseData).jwsPurchaseOrder;if (!jwsPurchaseOrder) {console.log("IAPKitDemo queryPurchase, jwsPurchaseOrder invalid.");continue;}const purchaseStr = JWTUtil.decodeJwtObj(jwsPurchaseOrder);const purchaseOrderPayload = JSON.parse(purchaseStr) as PurchaseOrderPayload;}}}build() {...}
}
步驟三:查詢商品信息
通過queryProducts來獲取在AppGallery Connect上配置的商品信息。發(fā)起請求時,開發(fā)者需在請求參數(shù)QueryProductsParameter中攜帶相關(guān)的商品ID,并根據(jù)實際配置指定其productType。
當(dāng)接口請求成功時,IAP Kit將返回商品信息Product的列表。 您可以使用Product包含的商品價格、名稱和描述等信息,向用戶展示可供購買的商品列表。
// pages/Index.ets
/*** @description 應(yīng)用內(nèi)支付服務(wù)示例-消耗型商品* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-01*/
import { common } from '@kit.AbilityKit'
import { iap } from '@kit.IAPKit';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {private context: common.UIAbilityContext = {} as common.UIAbilityContext;@State querying: boolean = true;@State queryingFailed: boolean = false;@State productInfoArray: iap.Product[] = [];@State queryFailedText: string = "查詢失敗!";showLoadingPage() {...}showFailedPage(failedText?: string) {...}showNormalPage() {...}aboutToAppear(): void {...}async onCase() {...await this.queryProducts();}// 判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付。async queryEnv(): Promise<number> {...}// 查詢商品信息async queryProducts() {try {console.log("IAPKitDemo queryProducts begin.");const queryProductParam: iap.QueryProductsParameter = {productType: iap.ProductType.CONSUMABLE,productIds: ['nutpi_course_1']};const result: iap.Product[] = await iap.queryProducts(this.context, queryProductParam);this.productInfoArray = result;this.showNormalPage();} catch (error) {this.showFailedPage();}}async queryPurchase() {...}build() {...}
}
步驟四:構(gòu)建商品列表UI
// pages/Index.ets
/*** @description 應(yīng)用內(nèi)支付服務(wù)示例-消耗型商品* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-01*/
import { common } from '@kit.AbilityKit'
import { iap } from '@kit.IAPKit';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {private context: common.UIAbilityContext = {} as common.UIAbilityContext;@State querying: boolean = true;@State queryingFailed: boolean = false;@State productInfoArray: iap.Product[] = [];@State queryFailedText: string = "查詢失敗!";showLoadingPage() {...}showFailedPage(failedText?: string) {...}showNormalPage() {...}aboutToAppear(): void {...}async onCase() {...}// 判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付。async queryEnv(): Promise<number> {...}// 查詢商品信息async queryProducts() {...}async queryPurchase() {...}build() {Column() {Column() {Text('應(yīng)用內(nèi)支付服務(wù)示例-消耗型').fontSize(18).fontWeight(FontWeight.Bolder)}.width('100%').height(54).justifyContent(FlexAlign.Center).backgroundColor(Color.White)Column() {Column() {Row() {Text('Consumables').fontSize(28).fontWeight(FontWeight.Bold).margin({ left: 24, right: 24 })}.margin({ top: 16, bottom: 12 }).height(48).justifyContent(FlexAlign.Start).width('100%')// 商品列表信息List({ space: 0, initialIndex: 0 }) {ForEach(this.productInfoArray, (item: iap.Product) => {ListItem() {Flex({ direction: FlexDirection.Row, alignItems: ItemAlign.Center }) {Image($r('app.media.app_icon')).height(48).width(48).objectFit(ImageFit.Contain)Text(item.name).width('100%').height(48).fontSize(16).textAlign(TextAlign.Start).padding({ left: 12, right: 12 })Button(item.localPrice).width(200).fontSize(16).height(30).onClick(() => {this.createPurchase(item.id, item.type)}).stateEffect(true)}.borderRadius(16).backgroundColor('#FFFFFF').alignSelf(ItemAlign.Auto)}})}.divider({ strokeWidth: 1, startMargin: 2, endMargin: 2 }).padding({ left: 12, right: 12 }).margin({ left: 12, right: 12 }).borderRadius(16).backgroundColor('#FFFFFF').alignSelf(ItemAlign.Auto)}.backgroundColor('#F1F3F5').width('100%').height('100%').visibility(this.querying || this.queryingFailed ? Visibility.None : Visibility.Visible)// 加載進(jìn)度組件Stack() {LoadingProgress().width(96).height(96)}.backgroundColor('#F1F3F5').width('100%').height('100%').visibility(this.querying ? Visibility.Visible : Visibility.None)// 異常文本提示Stack({ alignContent: Alignment.Center }) {Text(this.queryFailedText).fontSize(28).fontWeight(FontWeight.Bold).margin({ left: 24, right: 24 })}.backgroundColor('#F1F3F5').width('100%').height('100%').visibility(this.queryingFailed ? Visibility.Visible : Visibility.None).onClick(() => {this.onCase();})}.width('100%').layoutWeight(1)}.width('100%').height('100%').backgroundColor(0xF1F3F5)}
}
步驟五:發(fā)起購買
用戶發(fā)起購買時,開發(fā)者的應(yīng)用可通過向IAP Kit發(fā)送createPurchase請求來拉起IAP Kit收銀臺。發(fā)起請求時,需在請求參數(shù)PurchaseParameter中攜帶開發(fā)者此前已在華為AppGallery Connect網(wǎng)站上配置并生效的商品ID,并根據(jù)實際配置指定其productType。
// pages/Index.ets
/*** @description 應(yīng)用內(nèi)支付服務(wù)示例-消耗型商品* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-01*/
import { common } from '@kit.AbilityKit'
import { iap } from '@kit.IAPKit';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {private context: common.UIAbilityContext = {} as common.UIAbilityContext;@State querying: boolean = true;@State queryingFailed: boolean = false;@State productInfoArray: iap.Product[] = [];@State queryFailedText: string = "查詢失敗!";showLoadingPage() {...}showFailedPage(failedText?: string) {...}showNormalPage() {...}aboutToAppear(): void {...}async onCase() {...}// 判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付。async queryEnv(): Promise<number> {...}// 查詢商品信息async queryProducts() {...}async queryPurchase() {...}/*** 發(fā)起購買* @param id AppGallery Connect控制臺配置的商品ID* @param type 商品類型*/createPurchase(id: string, type: iap.ProductType) {console.log("IAPKitDemo createPurchase begin.");try {const createPurchaseParam: iap.PurchaseParameter = {productId: id,productType: type};iap.createPurchase(this.context, createPurchaseParam).then(async (result) => {console.log("IAPKitDemo createPurchase success. Data: " + JSON.stringify(result));// 獲取PurchaseOrderPayload的JSON字符串const purchaseData: PurchaseData = JSON.parse(result.purchaseData) as PurchaseData;const jwsPurchaseOrder: string = purchaseData.jwsPurchaseOrder;// 解碼 JWTUtil為自定義類,可參見Sample Code工程const purchaseStr = JWTUtil.decodeJwtObj(jwsPurchaseOrder);const purchaseOrderPayload = JSON.parse(purchaseStr) as PurchaseOrderPayload;// 處理發(fā)貨}).catch((error: BusinessError) => {promptAction.showToast({message: "IAPKitDemo createPurchase failed. Cause: " + JSON.stringify(error)})if (error.code === iap.IAPErrorCode.PRODUCT_OWNED || error.code === iap.IAPErrorCode.SYSTEM_ERROR) {// 參考權(quán)益發(fā)放檢查是否需要補(bǔ)發(fā)貨,確保權(quán)益發(fā)放this.queryPurchase();}})} catch (err) {promptAction.showToast({message: "IAPKitDemo createPurchase failed. Error: " + JSON.stringify(err)})}}build() {...}
}
步驟六:完成購買
對PurchaseData.jwsPurchaseOrder解碼驗簽成功后,如果PurchaseOrderPayload.purchaseOrderRevocationReasonCode為空,則代表購買成功,即可發(fā)放相關(guān)權(quán)益。
發(fā)貨成功后,開發(fā)者需在應(yīng)用中發(fā)送finishPurchase請求確認(rèn)發(fā)貨,以此通知IAP服務(wù)器更新商品的發(fā)貨狀態(tài),完成購買流程。發(fā)送finishPurchase請求時,需在請求參數(shù)FinishPurchaseParameter中攜帶PurchaseOrderPayload中的productType、purchaseToken、purchaseOrderId。請求成功后,IAP服務(wù)器會將相應(yīng)商品標(biāo)記為已發(fā)貨。
對于消耗型商品,應(yīng)用成功執(zhí)行finishPurchase之后,IAP服務(wù)器會將相應(yīng)商品重新設(shè)置為可購買狀態(tài),用戶即可再次購買該商品。
// pages/Index.ets
/*** @description 應(yīng)用內(nèi)支付服務(wù)示例-消耗型商品* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-01*/
import { common } from '@kit.AbilityKit'
import { iap } from '@kit.IAPKit';
import { JSON } from '@kit.ArkTS';
import { BusinessError } from '@kit.BasicServicesKit';
import { promptAction } from '@kit.ArkUI';@Entry
@Component
struct Index {private context: common.UIAbilityContext = {} as common.UIAbilityContext;@State querying: boolean = true;@State queryingFailed: boolean = false;@State productInfoArray: iap.Product[] = [];@State queryFailedText: string = "查詢失敗!";showLoadingPage() {...}showFailedPage(failedText?: string) {...}showNormalPage() {...}aboutToAppear(): void {...}async onCase() {...}// 判斷當(dāng)前登錄的華為賬號所在服務(wù)地是否支持應(yīng)用內(nèi)支付。async queryEnv(): Promise<number> {...}// 查詢商品信息async queryProducts() {...}async queryPurchase() {...}/*** 發(fā)起購買* @param id AppGallery Connect控制臺配置的商品ID* @param type 商品類型*/createPurchase(id: string, type: iap.ProductType) {console.log("IAPKitDemo createPurchase begin.");try {const createPurchaseParam: iap.PurchaseParameter = {productId: id,productType: type};iap.createPurchase(this.context, createPurchaseParam).then(async (result) => {console.log("IAPKitDemo createPurchase success. Data: " + JSON.stringify(result));// 獲取PurchaseOrderPayload的JSON字符串const purchaseData: PurchaseData = JSON.parse(result.purchaseData) as PurchaseData;const jwsPurchaseOrder: string = purchaseData.jwsPurchaseOrder;// 解碼 JWTUtil為自定義類,可參見Sample Code工程const purchaseStr = JWTUtil.decodeJwtObj(jwsPurchaseOrder);const purchaseOrderPayload = JSON.parse(purchaseStr) as PurchaseOrderPayload;// 處理發(fā)貨this.finishPurchase(purchaseOrderPayload);}).catch((error: BusinessError) => {promptAction.showToast({message: "IAPKitDemo createPurchase failed. Cause: " + JSON.stringify(error)})if (error.code === iap.IAPErrorCode.PRODUCT_OWNED || error.code === iap.IAPErrorCode.SYSTEM_ERROR) {// 參考權(quán)益發(fā)放檢查是否需要補(bǔ)發(fā)貨,確保權(quán)益發(fā)放this.queryPurchase();}})} catch (err) {promptAction.showToast({message: "IAPKitDemo createPurchase failed. Error: " + JSON.stringify(err)})}}finishPurchase(purchaseOrder: PurchaseOrderPayload) {console.log("IAPKitDemo finishPurchase begin.");const finishPurchaseParam: iap.FinishPurchaseParameter = {productType: purchaseOrder.productType,purchaseToken: purchaseOrder.purchaseToken,purchaseOrderId: purchaseOrder.purchaseOrderId};iap.finishPurchase(this.context, finishPurchaseParam).then((result) => {console.log("IAPKitDemo finishPurchase success");}).catch((error: BusinessError) => {promptAction.showToast({message: "IAPKitDemo finishPurchase failed. Cause: " + JSON.stringify(error)})})}build() {...}
}
2 推送服務(wù)
開發(fā)步驟
步驟一:請求通知授權(quán)
為確保應(yīng)用可正常收到消息,建議應(yīng)用發(fā)送通知前調(diào)用requestEnableNotification()方法彈出提醒,告知用戶需要允許接收通知消息。
// entryability/EntryAbility.ets
/*** @description 應(yīng)用入口* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-13*/
import { AbilityConstant, UIAbility, Want } from '@kit.AbilityKit';
import { hilog } from '@kit.PerformanceAnalysisKit';
import { window } from '@kit.ArkUI';
import { BusinessError } from '@kit.BasicServicesKit';
import { JSON } from '@kit.ArkTS';
import { notificationManager } from '@kit.NotificationKit';export default class EntryAbility extends UIAbility {async onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): Promise<void> {hilog.info(0x0000, 'testTag', '%{public}s', 'Ability onCreate');// 請求通知授權(quán)await this.requestNotification();}async requestNotification() {try {console.info("requestNotification: 請求通知授權(quán)開始。");// 查詢通知是否授權(quán)const notificationEnabled: boolean = await notificationManager.isNotificationEnabled();console.info("requestNotification: " + (notificationEnabled ? '已' : '未') + "授權(quán)");if (!notificationEnabled) {// 請求通知授權(quán)await notificationManager.requestEnableNotification();}} catch (error) {const e: BusinessError = error as BusinessError;console.error("requestNotification failed. Cause: " + JSON.stringify(e));}}
}
步驟二:獲取Push Token
導(dǎo)入pushService模塊。建議在應(yīng)用的UIAbility(例如EntryAbility)的onCreate()方法中調(diào)用getToken()接口獲取Push Token并上報到開發(fā)者的服務(wù)端,方便開發(fā)者的服務(wù)端向終端推送消息。本示例便于應(yīng)用端測試發(fā)送通知消息請求,將Push Token獲取放置在Index.ets頁面。
// pages/Index.ets
import { pushService } from '@kit.PushKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { JSON } from '@kit.ArkTS';
import { http } from '@kit.NetworkKit';
import { promptAction } from '@kit.ArkUI';
/*** @description 推送服務(wù)示例* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-13*/
@Entry
@Component
struct Index {@State pushToken: string = "";async aboutToAppear(): Promise<void> {try {// 獲取Push Tokenconst pushToken: string = await pushService.getToken();console.log("getToken succeed. Token: " + pushToken);const now = new Date();const timestamp = now.getTime();console.log("getToken succeed. Time: " + Math.floor(timestamp / 1000));console.log("getToken succeed. Time: " + (Math.floor(timestamp / 1000) + 3600));this.pushToken = pushToken;// 此處需要上報Push Token到應(yīng)用服務(wù)端} catch (error) {const e: BusinessError = error as BusinessError;console.error("getToken failed. Cause: " + JSON.stringify(e));}}build() {...}
}
步驟三:獲取項目ID
登錄AppGallery Connect控制臺,選擇“我的項目”,在項目列表中選擇對應(yīng)的項目,左側(cè)導(dǎo)航欄選擇“項目設(shè)置”,拷貝項目ID。
步驟四:創(chuàng)建服務(wù)賬號密鑰文件
- 開發(fā)者需要在華為開發(fā)者聯(lián)盟的API Console上創(chuàng)建并下載推送服務(wù)API的服務(wù)賬號密鑰文件。點擊“管理中心 > API服務(wù) > API庫”,在API庫頁面選擇“項目名稱”,在展開的App Services列表中點擊“推送服務(wù)”。
- 點擊推送服務(wù)頁面中的“啟用”,完成API添加。
- 點擊“管理中心 > API服務(wù) > 憑證”,在憑證頁面點擊“服務(wù)賬號密鑰”卡片中的“創(chuàng)建憑證”按鈕。
- 在“創(chuàng)建服務(wù)賬號密鑰”頁面輸入信息并點擊“生成公私鑰”,點擊“創(chuàng)建并下載JSON”,完成“服務(wù)賬號密鑰”憑證創(chuàng)建,需要開發(fā)者保存“支付公鑰”,用于后期生成JWT鑒權(quán)令牌。
步驟五:生成JWT Token
開發(fā)者在正式開發(fā)前調(diào)試功能,可使用在線生成工具獲取JWT Token,需要注意生成JWT Token時Algorithm請選擇RS256或PS256。若用于正式環(huán)境,為了方便開發(fā)者生成服務(wù)賬號鑒權(quán)令牌,華為提供了JWT開源組件,可根據(jù)開發(fā)者使用的開發(fā)語言選擇進(jìn)行開發(fā)。
- HEADER中的kid指下載的服務(wù)賬號密鑰文件中key_id字段。
- PAYLOAD數(shù)據(jù)中iss指下載的的服務(wù)賬號密鑰文件中sub_account字段。
- VERIFY SIGNATURE中復(fù)制粘貼公鑰和私鑰。
步驟六:調(diào)用推送服務(wù)REST API
該模塊需要開發(fā)者在應(yīng)用服務(wù)端自行開發(fā),需要結(jié)合用戶信息留存設(shè)備Token,本課程中該功能位于應(yīng)用端僅用于學(xué)習(xí),不推薦該方法。應(yīng)用服務(wù)端調(diào)用Push Kit服務(wù)端的REST API推送通知消息,需要傳遞的參數(shù)說明如下所示:
- [projectId]:項目ID。
- Authorization:JWT格式字符串,JWT Token前加“Bearer ”,需注意“Bearer”和JWT格式字符串中間的空格不能丟。
- push-type:0表示Alert消息,此處為通知消息場景。
- category:表示通知消息自分類的類別,MARKETING為資訊營銷類消息。
- actionType:0表示點擊消息打開應(yīng)用首頁。
- token:Push Token。
- testMessage:測試消息標(biāo)識,true標(biāo)識測試消息。
- notifyId:(選填)自定義消息標(biāo)識字段,僅支持?jǐn)?shù)字,范圍[0, 2147483647],若要用于消息撤回則必填。

在應(yīng)用端按鈕組件Button的點擊事件onClick中通過數(shù)據(jù)請求API實現(xiàn)發(fā)送通知消息。
// pages/Index.ets
import { pushService } from '@kit.PushKit';
import { BusinessError } from '@kit.BasicServicesKit';
import { JSON } from '@kit.ArkTS';
import { http } from '@kit.NetworkKit';
import { promptAction } from '@kit.ArkUI';
/*** @description 推送服務(wù)示例* @author 白曉明* @organization 堅果派* @website: nutpi.com.cn* @date 2024-06-13*/
@Entry
@Component
struct Index {@State pushToken: string = "";@State isLoading: boolean = false;// 步驟五生成的JWT Tokenauthorization: string = "Bearer ****";async aboutToAppear(): Promise<void> {try {// 獲取Push Tokenconst pushToken: string = await pushService.getToken();console.log("getToken succeed. Token: " + pushToken);const now = new Date();const timestamp = now.getTime();console.log("getToken succeed. Time: " + Math.floor(timestamp / 1000));console.log("getToken succeed. Time: " + (Math.floor(timestamp / 1000) + 3600));this.pushToken = pushToken;// 上報Push Token} catch (error) {const e: BusinessError = error as BusinessError;console.error("getToken failed. Cause: " + JSON.stringify(e));}}async deletePushTokenFunc() {try {await pushService.deleteToken();} catch (error) {const e: BusinessError = error as BusinessError;console.error("deleteToken failed. Cause: " + JSON.stringify(e));}}build() {Column() {Row() {Text('推送服務(wù)示例').fontSize(18).fontWeight(FontWeight.Bolder)}.width('100%').height(54).justifyContent(FlexAlign.Center).alignItems(VerticalAlign.Center)Column({ space: 16 }) {Row() {LoadingProgress()Text('等待通知發(fā)送完成').fontSize(16)}.width('100%').height(64).justifyContent(FlexAlign.Center).visibility(this.isLoading ? Visibility.Visible : Visibility.Hidden)Button('發(fā)送通知消息').type(ButtonType.Normal).borderRadius(8).enabled(!this.isLoading).onClick(async () => {try {this.isLoading = true;const url = "https://push-api.cloud.huawei.com/v3/388421841222199046/messages:send";const httpRequest = http.createHttp();const response: http.HttpResponse = await httpRequest.request(url, {header: {"Content-Type": "application/json","Authorization": this.authorization,"push-type": 0},method: http.RequestMethod.POST,extraData: {"payload": {"notification": {"category": "MARKETING","title": "普通通知標(biāo)題","body": "普通通知內(nèi)容","clickAction": {"actionType": 0},"notifyId": 12345}},"target": {"token": [this.pushToken]},"pushOptions": {"testMessage": true}}})if (response.responseCode === 200) {const result = response.result as string;const data = JSON.parse(result) as ResultData;promptAction.showToast({message: data.msg})}} catch (error) {const e: BusinessError = error as BusinessError;console.error("getToken failed. Cause: " + JSON.stringify(e));} finally {this.isLoading = false;}})}.width('100%').layoutWeight(1)}.height('100%').width('100%')}
}// 接口返回數(shù)據(jù)類
interface ResultData {code: string;msg: string;requestId: string;
}