DEV Community

Cover image for [Learn HarmonyOS Next Knowledge Every Day] Debug Certificates, Webview, Version Numbers, etc.
kouwei qing
kouwei qing

Posted on

[Learn HarmonyOS Next Knowledge Every Day] Debug Certificates, Webview, Version Numbers, etc.

[Learn HarmonyOS Next Knowledge Every Day] Debug Certificates, Webview, Version Numbers, etc.

1. Failed to obtain token with error message: get token fail:, {error.name:Error, error.message:Illegal application identity.}, json:{"code":1000900010}}?

The application has applied for a debug certificate in AppGallery Connect, enabled the push service, configured the debug certificate signature in the app project, and set the client_id. However, token acquisition fails with the error message: get token fail:, {error.name:Error, error.message:Illegal application identity.}, json:{"code":1000900010}}.

Possible causes

The application may have violated regulations:

  • The application was created in AppGallery Connect without selecting the HarmonyOS application type.
  • The application signature certificate fingerprint configured in AppGallery Connect does not match the actual one. For details, see Add Public Key Fingerprint.
  • The client_id is not configured in src/main/module.json5 at the project module level (e.g., entry/src/main/module.json5). For details, see Configure Client ID.

2. How to obtain the app/system version number?

To obtain the app package version number, refer to the document: BundleInfo.

import { bundleManager } from '@kit.AbilityKit';

let bundleFlags = bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION | bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_METADATA;
bundleManager.getBundleInfoForSelf(bundleFlags).then((data) => {
  console.info('versionCode: ' + data.versionCode);
  console.info('versionName: ' + data.versionName);
})
Enter fullscreen mode Exit fullscreen mode

To obtain the system version number, refer to the document: deviceInfo.

import { deviceInfo } from '@kit.BasicServicesKit';
console.info('displayVersion: ' + deviceInfo.displayVersion);
console.info('osFullName: ' + deviceInfo.osFullName);
console.info('versionId: ' + deviceInfo.versionId);
Enter fullscreen mode Exit fullscreen mode

3. Can a phone call be initiated directly via location.href in a webview?

No. The phone subsystem module must be introduced on the application side. The Android implementation principle is the same—calling functionality requires introducing the corresponding module in ArkTS first.

Reference code:

// xxx.ets
import web_webview from '@ohos.web.webview';
import call from '@ohos.telephony.call';

@Entry
@Component
struct WebComponent {
  webviewController: web_webview.WebviewController = new web_webview.WebviewController();

  build() {
    Column() {
      Web({ src: $rawfile('call.html'), controller: this.webviewController })
        .onLoadIntercept((event) => {
          if (event) {
            let url: string = event.data.getRequestUrl();
            // Check if the link is a dialing link
            if (url.indexOf('tel://') === 0) {
              // Navigate to the dialing interface
              call.makeCall(url.substring(6), (err) => {
                if (!err) {
                  console.info('make call succeeded.');
                } else {
                  console.info('make call fail, err is:' + JSON.stringify(err));
                }
              });
              return true;
            }
          }
          return false;
        })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

4. How to implement different code logic by judging function parameter types?

  • Prototype detection via instanceof
  • Judgment via constructor string
class Game{
  // ...
}

function Solve(message:number | string | boolean | Map<string, number> | Record<string, number> | Game){
  // Game type judgment
  if(message instanceof Game){
    console.info('Game')
    return
  }

  let typeStr:string = message.constructor.toString().substring(9,12)
  switch (typeStr){
    case 'Num':console.info('number');break;
    case 'Str':console.info('string');break;
    case 'Boo':console.info('boolean');break;
    case 'Map':console.info('Map');break;  // Map type judgment
    case 'Obj':console.info('Record');break;  // Record type judgment
  }
}
Enter fullscreen mode Exit fullscreen mode

5. How to cancel the selection state when closing the bindSelection custom menu in a Text component?

When a Text component binds a bindSelectionMenu custom menu, long-pressing triggers the custom menu. Using closeSelectionMenu to close the custom menu does not cancel the text selection state.

To cancel the selection state in this scenario, reset the selection area using selection. When calling closeSelectionMenu to close the custom menu, reset the start and end of the selection to cancel the selection state.

Reference code:

@Entry
@Component
struct Demo {
  controller: TextController = new TextController();
  options: TextOptions = { controller: this.controller };
  @State start: number = -1
  @State end: number = -1

  build() {
    Column() {
      Column() {
        Text(undefined, this.options) {
          Span('Hello World')
          ImageSpan($r('app.media.dog'))
            .width('100px')
            .height('100px')
            .objectFit(ImageFit.Fill)
            .verticalAlign(ImageSpanAlignment.CENTER)
        }
        .selection(this.start, this.end)
        .copyOption(CopyOptions.InApp)
        // Long-press to trigger the custom menu
        .bindSelectionMenu(TextSpanType.TEXT, this.LongPressImageCustomMenu, TextResponseType.LONG_PRESS, {
          onDisappear: () => {
            console.info(`Callback when the custom selection menu closes`);
          },
          onAppear: () => {
            console.info(`Callback when the custom selection menu appears`);
          }
        })
        // Callback when the selection area changes to update the start and end indices of the selection area
        .onTextSelectionChange((selectionStart: number, selectionEnd: number) => {
          this.start = selectionStart
          this.end = selectionEnd
          console.info(`Callback for text selection area change, selectionStart: ${selectionStart}, selectionEnd: ${selectionEnd}`);
        })
        .borderWidth(1)
        .borderColor(Color.Red)
        .width(200)
        .height(100)
      }
      .width('100%')
      .backgroundColor(Color.White)
      .alignItems(HorizontalAlign.Start)
      .padding(25)
    }
    .height('100%')
  }

  @Builder
  LongPressImageCustomMenu() {
    Column() {
      Menu() {
        MenuItemGroup() {
          MenuItem({
            startIcon: $r('app.media.app_icon'),
            content: "Right Click Menu 1",
            labelInfo: ""
          })// When clicking the custom menu, reset the start and end indices of the selection area
            .onClick((event) => {
              this.start = -1
              this.end = -1
              this.controller.closeSelectionMenu();
            })

          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Select Mixed Menu 2", labelInfo: "" })
          MenuItem({ startIcon: $r('app.media.app_icon'), content: "Select Mixed Menu 3", labelInfo: "" })
        }
      }
      .MenuStyles()
    }
  }
}

@Extend(Menu)
function MenuStyles() {
  .radius($r('sys.float.ohos_id_corner_radius_card'))
  .clip(true)
  .backgroundColor('#F0F0F0')
}
Enter fullscreen mode Exit fullscreen mode

Top comments (0)