[[439852]] 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ https://harmonyos..com 1. はじめにHarmonyOS に注目している人のほとんどは、HarmonyOS の機能についてある程度理解していると思います。公式サイトからは、「統一された OS、柔軟な展開」、「ハードウェア相互支援、リソース共有」、「ワンタイム開発、マルチ端末展開」といったいくつかの重要な抽象化がわかります。 今後数回にわたって、HarmonyOS の機能に関する理解をさらに深め、柔軟に適用することを目的として、HarmonyOS の機能を皆さんと一緒に学習し、実践するケースをいくつか紹介したいと思います。 今回は、分散ID認証の機能を通じて、一般的な通信方法について見ていきます。 共有コンテンツ: - デバイスを移行または連携する場合、利用可能なデバイスのリストを表示する必要があります。デバイスを個別に取得したり、リスト レイアウト ファイルを自分で定義したりしなくても、デバイス ウィンドウを表示する方法があります。
- 分散 ID 認証および承認機能を実装する方法。
このケースは、公式コードラボの例である分散認証 (Java) から取得されています。この投稿は学習とコミュニケーションのために整理され、分析されています。 2. エフェクト表示
3. 環境を構築するDevEco Studio をインストールします。詳細については、DevEco Studio のダウンロードを参照してください。 DevEco Studio 開発環境をセットアップします。 DevEco Studio 開発環境はネットワーク環境に依存する必要があります。ツールを正常に使用するには、ネットワークに接続する必要があります。次の 2 つの状況に応じて開発環境を構成できます。 インターネットに直接アクセスできる場合は、HarmonyOS SDK をダウンロードするだけで済みます。 ネットワークがインターネットに直接アクセスできず、プロキシ サーバー経由でアクセスする必要がある場合は、「開発環境の構成」を参照してください。 ソースコードをダウンロードしたら、DevEco Studio を使用してプロジェクトを開き、シミュレーターを実行します。 実際のデバイスで実行する場合は、「実際のデバイスでアプリケーションを実行する」を参照してください。 4. プロジェクト構造
5. コードの説明5.1 ストリーミングデバイスのリストを表示する方法 この方法では、デバイスを別途取得する必要はなく、デバイス ウィンドウを表示するための対応するレイアウト ファイルを定義する必要もありません。 ①ContinuationRegisterManagerでリダイレクト機能を登録し、機能に割り当てられた登録トークンを取得する - /**
- * 登録および流通機能
- * 継続を登録する
- *
- * @param コンテキスト
- * @param デバイスコールバック
- * @param 利用可能なストリーミングデバイスを表示するかどうかを示します
- */
- パブリックvoid registerContinuation(AbilitySlice コンテキスト、DeviceCallback deviceCallback、boolean show) {
- LogUtils.info( "registerContinuation" );
- 継続レジスタマネージャがnullの場合
- this.deviceCallback = デバイスコールバック;
- this.show = 表示;
- 継続レジスタマネージャー = context.getContinuationRegisterManager();
-
- //サポートされているデバイスタイプ
- ExtraParams パラメータ = 新しい ExtraParams();
- String[] devTypes = 新しいString[]{ExtraParams.DEVICETYPE_SMART_PAD,
- 追加パラメータ.DEVICETYPE_SMART_WATCH、
- ExtraParams.DEVICETYPE_SMART_PHONE};
- パラメータを設定します。
-
- //ContinuationRegisterManager でリダイレクト機能を登録し、機能に割り当てられた登録トークンを取得します。
- // IContinuationDeviceCallback を使用して、ユーザーが機能ジャンプ用のデバイスを選択した後のデバイス接続ステータスの変化を監視し、独自の処理ロジックを実装できます。
- 継続RegisterManager.register(context.getBundleName(), params, callback, requestCallback);
- }それ以外{
- if (表示) {
- // デバイスリストを表示する
- 継続デバイスを表示します。
- }
- }
- }
② 転送が完了した後、デバイス接続ステータス変更コールバックをリッスンするためのステータスコールバックが提供される。 - //フローが完了した後のステータス コールバックは、デバイスの接続ステータスの変化をリッスンするためのコールバックを提供します。
- プライベートIContinuationDeviceCallbackコールバック = 新しいIContinuationDeviceCallback() {
- @オーバーライド
- パブリックvoid onDeviceConnectDone(文字列デバイスID、文字列値) {
- LogUtils.info( "onDeviceConnectDone" );
-
- //デバイスが接続された後、選択したデバイスのタスクをキューに送信します。これは、転送するデバイスをクリックするのと同じです。
- イベント ハンドラ eventHandler = 新しい EventHandler(EventRunner.getMainEventRunner());
- //タスクをイベント キューに送信します。
- イベントハンドラ.postTask(新しい実行可能() {
- @オーバーライド
- パブリックボイド実行(){
- デバイスコールバックがnullの場合
- デバイスコールバック。onItemClick(デバイスID);
- }
- //指定された機能が正常に転送されたデバイスの接続ステータスを更新します。
- 継続レジスタマネージャ
- .updateConnectStatus(アビリティトークン、
- //接続ステータスを更新する必要があるデバイスの ID を示します。
- デバイスID、
- DeviceConnectState.IDLE.getState()、 null
- );
- }
- });
- }
-
- @オーバーライド
- パブリックvoid onDeviceDisconnectDone(String deviceId) {
- LogUtils.info( "デバイスの切断が完了したら" );
- }
- };
③転送要求のコールバックを完了し、転送可能なデバイスを表示する - //ストリーミング要求のコールバックを完了し、ホップ タスク管理サービスの接続ステータスの変更をリッスンするためのコールバックを提供します。
- プライベートリクエストコールバック requestCallback = 新しいリクエストコールバック() {
- @オーバーライド
- パブリックvoid onResult( int結果) {
- 能力トークン = 結果;
- if (表示) {
- //転送可能なデバイスを表示
- 継続デバイスを表示します。
- }
- }
- };
-
- /**
- * 譲渡可能なデバイスを表示
- * 続きを表示
- */
- プライベートvoid showContinuationDevice() {
- LogUtils.info( "継続の表示" );
-
- ExtraParams extraParams = 新しい ExtraParams();
- extraParams.setDevType(新しいString[]{ExtraParams.DEVICETYPE_SMART_TV,
- 追加パラメータ.DEVICETYPE_SMART_PAD、
- 追加パラメータ.DEVICETYPE_SMART_WATCH、
- ExtraParams.DEVICETYPE_SMART_PHONE});
- extraParams.setDescription( "デバイスフローテスト" );
-
- //転送可能なデバイスを表示
- 継続RegisterManager.showDeviceList(abilityToken, extraParams, null );
-
- }
5.2 分散ID認証および認可機能の実装 理解を容易にするために、要求を送信するデバイスを認可要求デバイスと呼び、認可操作を実行するデバイスを認可デバイスと呼びます。 RegisterManager は、MainAbilitySlice によって実装されるカスタム CommonEvent インターフェースを定義します。したがって、RegisterManager は MainAbilitySlice と通信することができます。 RegisterManager は、ConstUtil.ORDER_CODE タイプのパブリック イベントへのサブスクリプションを完了し、このタイプのパブリック イベントを受信できるようになります。 認証と承認の完全なプロセス: ① 認可を要求するデバイスでは、RegisterManager がデバイスのフロー機能を登録する機能を提供し、デバイス接続完了のステータスコールバックで「デバイスをクリック」タスクを実行キューに送信します。 - //フローが完了した後のステータス コールバックは、デバイスの接続ステータスの変化をリッスンするためのコールバックを提供します。
- プライベートIContinuationDeviceCallbackコールバック = 新しいIContinuationDeviceCallback() {
- @オーバーライド
- パブリックvoid onDeviceConnectDone(文字列デバイスID、文字列値) {
- LogUtils.info( "onDeviceConnectDone" );
-
- //デバイスが接続された後、選択したデバイスのタスクをキューに送信します。これは、転送するデバイスをクリックするのと同じです。
- イベント ハンドラ eventHandler = 新しい EventHandler(EventRunner.getMainEventRunner());
- //タスクをイベント キューに送信します。
- イベントハンドラ.postTask(新しい実行可能() {
- @オーバーライド
- パブリックボイド実行(){
- デバイスコールバックがnullの場合
- デバイスコールバック。onItemClick(デバイスID);
- }
- //指定された機能が正常に転送されたデバイスの接続ステータスを更新します。
- 継続レジスタマネージャ
- .updateConnectStatus(アビリティトークン、
- //接続ステータスを更新する必要があるデバイスの ID を示します。
- デバイスID、
- DeviceConnectState.IDLE.getState()、 null
- );
- }
- });
- }
MainAbilitySlice では、フロー機能の登録が完了した後、「デバイスをクリック」のコールバックで、リモート認可デバイスの AuthrRemoteSlice ページが開かれ、ConstUtil.DEVICE_ID と ConstUtil.ORDER_CODE (ConstUtil.START_ORDER) パラメータが渡されますが、このうち ConstUtil.START_ORDER は使用されません。 - /**
- * 登録コラボレーション機能
- *
- * @param 表示
- */
- プライベートvoidレジスタ継続(ブール値表示) {
- LogUtils.info( "registerContinuation" );
-
- registerManager.registerContinuation(これ、
- 新しい RegisterManager.DeviceCallback() {
- @オーバーライド
- パブリックvoid onItemClick(文字列デバイスID) {
-
- LogUtils.info( "onItemClick,デバイスID:" + デバイスID);
-
- //リモート機能を起動する
- リモート機能を開始します(デバイスID)。
- }
- }、 見せる);
- }
-
- /**
- * リモートFAを開始
- *
- * @param デバイスID
- */
- プライベートvoid startRemoteAbility(文字列デバイスID) {
- LogUtils.info( "リモートアビリティを開始" );
-
- DialogUtil.showToast(getContext(), "リクエストが送信され、相手側の確認を待っています。" );
- //
- 文字列 localDeviceId = KvManagerFactory.getInstance().createKvManager()
- 新しい KvManagerConfig(this)).getLocalDeviceInfo().getId();
-
- インテントのintent = 新しいIntent();
- 操作操作 =
- 新しい Intent.OperationBuilder()
- .withDeviceId(デバイスID)
- .withBundleName(バンドル名を取得())
- .withAbilityName(MainAbility.class.getName())
- // 承認されたデバイスの認証ページにルーティングします
- .withAction( MainAbility.ACTION )は、
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- 。建てる();
- 操作をインテントに設定します。
- パラメータをintent.setParam(ConstUtil.DEVICE_ID, ローカルデバイスID);
- //リモートFAコマンドコードを開始
- パラメータを constUtil.ORDER_CODE に設定します。
- 開始アビリティ(インテント);
- }
② 承認されたデバイスのAuthrRemoteSliceページが開いた後、配布権限を要求した後に「許可」または「許可しない」をクリックすると、承認を要求しているデバイスのMainAbilityが再度開きます。 - プライベートvoid initViewData() {
- LogUtils.info( "initViewData" );
-
- findComponentById(ResourceTable.Id_yes_btn).setClickedListener(コンポーネント -> {
- メッセージを送信します(AUTH_TYPE1);
- });
- findComponentById(ResourceTable.Id_no_btn).setClickedListener(コンポーネント -> {
- メッセージを送信します(AUTH_TYPE2);
- });
- }
-
- プライベートvoid sendMessage( int型) {
- LogUtils.info( "sendMessage" );
-
- //MainAbilityからHPermissionインスタンスを取得する
- HPermission hPermission = ((MainAbility) getAbility()).getPermission();
-
- //ユーザーが分散権限を許可している場合は、設定ボタンが使用可能になります
- hPermission.requestPermissions(this, () -> {
- //ボタンが有効
- コンポーネントIDを検索します(ResourceTable.Id_yes_btn)。有効にするにはfalseに設定します。
- コンポーネント ID を検索します (ResourceTable.Id_no_btn)。有効にするにはfalseに設定します。
-
- //リクエスト側のページを開く
- リモートアビリティを開始します(タイプ);
- });
- }
-
- /**
- * 認可リクエスト側でMainAbilityを開く
- *
- * @param type 承認に同意するかどうか
- */
- プライベートvoid startRemoteAbility( int type) {
- LogUtils.info( "リモートアビリティを開始" );
-
- DialogUtil.showToast(getContext(), type == AUTH_TYPE1 ? "ゲームのプレイを許可する" : "ゲームへのアクセスが拒否されました" );
- インテントのintent = 新しいIntent();
- 操作操作 =
- 新しい Intent.OperationBuilder()
- .withDeviceId(リモートデバイスId == null ? "" : リモートデバイスId)
- .withBundleName(バンドル名を取得())
- .withAbilityName(MainAbility.class.getName())
- .withFlags(Intent.FLAG_ABILITYSLICE_MULTI_DEVICE)
- 。建てる();
- インテントをsetOperation(操作);
-
- //認証コード
- 意図を設定します。ORDER_CODE、タイプ。
- 開始アビリティ(インテント);
-
- //現在のホストの能力を無効にする
- getUITaskDispatcher().delayDispatch(() ->terminateAbility(), DELAY);
- }
③ 認可をリクエストするデバイスでは、MainAbilityがシングルトンモード("launchType": "singleton")に設定され、インスタンス化されているため、リクエストはonNewIntent関数に入ります。 config.json - {
- ...
- 「方向」 : 「未指定」 、
- 「表示」 : true 、
- 「名前」 : 「com.buty.javadistributedemo.MainAbility」 、
- "アイコン" : "$media:icon" ,
- "説明" : "$string:mainability_description" ,
- "ラベル" : "$string:entry_MainAbility" ,
- 「タイプ」 : 「ページ」 、
- 「起動タイプ」 : 「シングルトン」
- }
onNewIntent 関数では、タイプ ConstUtil.ORDER_CODE のイベントが CommonEventManager を通じて公開されます。イベントは RegisterManager によって受信され、処理されます。どのように処理されますか?これは、RegisterManager.CommonEvent を介して RegisterManager.CommonEvent インターフェースを実装する MainAbilitySlice に渡され、最終的にピアデバイスの認証結果 (許可/不許可) が表示されます。 - /**
- * 能力はシングルトンモードに設定されています
- * 作成時にインスタンスがすでに存在する場合は、この関数をトリガーします
- *
- * @param 意図
- */
- @オーバーライド
- 保護されたvoid onNewIntent(インテントインテント) {
- LogUtils.info( "onNewIntent" );
- スーパーの onNewIntent(インテント);
- // 許可されますか?
- intコード = 意図.getIntParam(ConstUtil.ORDER_CODE, 0);
- //
- 文字列デバイスID = intent.getStringParam(ConstUtil.DEVICE_ID);
- 共通イベントを送信します(コード、デバイスID)。
- }
MainAbilitySliceはメッセージを受信する - /**
- * RegisterManagerのCommonEventインターフェースを実装する
- *
- * @param コードコード
- * @param デバイスID デバイスID
- */
- @オーバーライド
- パブリックvoid onReceiveEvent( intコード、StringデバイスID) {
- LogUtils.info( "onReceiveEvent,コード:" +コード);
- スイッチ(コード){
- //ゲームをプレイすることに同意する
- ConstUtil.AUTH_TYPE1の場合:
- //start.setVisibility(Component.HIDE);
- tips.setVisibility(Component.VISIBLE);
- tips.setText( "承認されました。ゲームを開始できます" );
-
- 壊す;
- //ゲームを拒否する
- ConstUtil.AUTH_TYPE2の場合:
- tips.setVisibility(Component.VISIBLE);
- //DialogUtil.exitDialog(getAbility());
- tips.setText( "拒否されました。再生できません" );
- 壊す;
- デフォルト:
- 壊す;
- }
- }
6. まとめ分散システムで一般的に使用される通信方法: 1. インテントがパラメータを直接渡す(intent.setParam(ORDER_CODE, type)) 2. パブリックイベントのサブスクリプション/公開方法(CommonEventDataにカプセル化されたインテント) 3. カスタム インターフェース メソッド (RegisterManager.CommonEvent) 記事に関連する添付ファイルをダウンロードするには、以下のリンクをクリックしてください。 https://harmonyos..com/resource/1574 詳細については、以下をご覧ください。 51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ https://harmonyos..com |