Hongmeng分散型クロスデバイスファイルサービスレター管理に基づく

Hongmeng分散型クロスデバイスファイルサービスレター管理に基づく

[[431770]]

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ

https://harmonyos..com

I. はじめに

まず、このクロスデバイス ファイル サービス レター管理アプリケーションを作成する前に、何をしようと考えていたかについてお話しします。まず、分散ファイル サービスに基づく Liang Didi のテキスト エディターを読み、Word、Excel、PDF ファイルの作成などのドキュメントを作成し、クリックして WPS ソフトウェアを開いて編集したいと考えました。残念ながら、インターネットで検索しても WPS を開く方法が見つからなかったので、結局諦めました。そこで、お絵かきボードを作って、そこに表現したいものを描いて、それを絵として保存し、その絵を開いてさまざまなデバイスで閲覧できるようにしようと思いました。最初は、画像を保存し、スクリーンショット方式を使用してドキュメントを表示したいと考えていました。 Java でシステムを呼び出すためのスクリーンショット メソッドが見つかりませんでした。 JSも見ましたが、API7でしかサポートされていなかったので結局諦めました。しかし、頭の中でひらめきが起こり、勉強していた頃は自習授業で大声で話す必要はなかったことを思い出しました。多くのクラスメートがメモを渡し合った。当時は手紙を書くことも流行っていたので、このアイデアでコーディングを始めました。テキストボックスに入力した内容を便箋に書き写し、画像として保存する方法など、これまで書いていなかった知識ポイントがいくつかあります。別のデバイスで画像をクリックすると、その中のコンテンツが表示されます。オンライン検索を通じて、同様の知識ポイントが見つかったので、今日このクロスデバイス ファイル表示アプリケーションを作成できます。

まず最初に、このクロスデバイスレター管理アプリケーションについて簡単に説明します。電話Aは文字を作成し、画像を生成します。ローカル エンドは電話機 A に表示され、リモート エンドは電話機 B に表示されます。同時に、電話機 A と B の両方でレターの内容を開いて表示できます。ここでは分散データベース管理が使用されます。リスト表示を容易にするために、画像名はリストに保存されます。次に、対応する画像をクリックして画像名を取得し、分散ファイルパスから画像を取得して表示します。

2. 達成効果

開発ツール環境でのビデオ: https://www.bilibili.com/video/BV16L4y1i7b1/

携帯電話+携帯電話環境でのビデオ:https://www.bilibili.com/video/BV1mL411g72B/

3. プロジェクトを作成する

DevEco-Studio 開発ツールの最新バージョンがインストールされていると仮定し、[ファイル] -> [新規] -> [新しいプロジェクト] をクリックします。[HarmonyOS プロジェクトの作成] ウィンドウがポップアップ表示されます。ここでは、空の Java テンプレートを選択して作成します。前のビデオ再生の例は JS で記述されたインターフェイスであり、このクロスデバイス文字管理インターフェイスは Java で記述されています。JS の方がインターフェイスの記述が速く、デバッグも高速です。


Java モジュール レイアウト モジュール

4. メインインターフェースの開発

まず、パブリック クラスの Java コードを紹介します。これらのパブリック クラスを使用すると、パブリック クラス ファイルを直接コピーし、将来同様の機能を備えたアプリケーションを作成するときに使用できます。

DistributedFileUtil 分散ファイル ツール クラス:

  1. パッケージ com.army.study.util;
  2.  
  3. com.army.study.ResourceTable をインポートします。
  4. ohos.agp.render.Canvas をインポートします。
  5. ohos.agp.render.Paint をインポートします。
  6. ohos.agp.render.Texture をインポートします。
  7. ohos.agp.utils.Color をインポートします。
  8. ohos.app.Context をインポートします。
  9. ohos をインポートします。グローバル.resource.NotExistException;
  10. ohos.media.image.ImagePacker をインポートします。
  11. ohos.media.image.ImageSource をインポートします。
  12. ohos.media.image.PixelMap をインポートします。
  13. ohos.media.image.common.Sizeをインポートします
  14.  
  15. java.io.* をインポートします。
  16. java.util.ArrayList をインポートします。
  17. java.util.Arrays をインポートします。
  18. java.util.List をインポートします。
  19.  
  20. /**
  21. * 分散ファイルツール
  22. */
  23. パブリッククラスDistributedFileUtil {
  24. // コンテクスト
  25. プライベート最終コンテキスト mContext;
  26.  
  27. /**
  28. * 施工方法
  29. * @param コンテキスト
  30. */
  31. パブリックDistributedFileUtil(コンテキストコンテキスト) {
  32. this.mContext = コンテキスト;
  33. }
  34.  
  35. /**
  36. * 手紙を書く
  37. * @param ファイル名
  38. * @param 文字コンテンツ
  39. * @戻る 
  40. */
  41. パブリックPixelMap writeLetter(文字列ファイル名、文字列文字コンテンツ) {
  42. // 分散ファイルパスを取得する
  43. 文字列 filePath = mContext.getDistributedDir() + File.separator + fileName + ".jpg" ;
  44. テクスチャ テクスチャ = null ;
  45. 試す {
  46. // リソースファイルから文房具の背景画像を取得します
  47. 入力ストリーム inputStream = mContext.getResourceManager().getResource(ResourceTable.Media_bg);
  48. ImageSource.SourceOptions srcOpts = 新しい ImageSource.SourceOptions();
  49. srcOpts.formatHint = "image/jpeg" ;
  50. ImageSource imageSource = ImageSource. (入力ストリーム、srcOpts)を作成します
  51. // 画像のパラメータを設定する
  52. ImageSource.DecodingOptions デコーディングオプション = new ImageSource.DecodingOptions();
  53. デコードオプション.desiredSize=新しいサイズ(720,1080);
  54. ピクセルマップpixelMap = imageSource.createPixelmap(デコーディングオプション);
  55. //描画結果を保存するために使用される
  56. テクスチャ=新しいテクスチャ(ピクセルマップ);
  57. キャンバス canvas=新しいキャンバス(テクスチャ);
  58. ペイント paint = new Paint();
  59. ペイント.setTextSize(50);
  60. ペイントのストローク幅を設定します。
  61. ペイントの色を黒に設定します。
  62. // 便箋に内容を書きます
  63. キャンバスに文字を描画します。
  64. // ファイル出力ストリーム
  65. FileOutputStream fos = 新しい FileOutputStream(filePath);
  66.  
  67. ImagePacker imagePacker = ImagePacker.create ();
  68. ImagePacker.PackingOptions パッキングオプション = 新しい ImagePacker.PackingOptions();
  69. 梱包オプション.format = "image/jpeg" ; //image/jpegのみサポート
  70. 梱包オプション.品質 = 90;
  71. ブール結果 = imagePacker.initializePacking(fos, packedOptions);
  72. if(結果)
  73. {
  74. //ここでペイントした後、ピクセルマップを取得して保存します
  75. 結果 = imagePacker.addImage(texture.getPixelMap());
  76. if (結果) {
  77. 長いデータサイズ = imagePacker.finalizePacking();
  78. System.out.println ( "ファイルサイズ: " +dataSize) ;
  79. ToastUtil.getInstance().showToast(mContext, "正常に作成されました!" );
  80. }
  81. }
  82.  
  83. fos.flush();
  84. fos.close ();
  85. } キャッチ (IOException | NotExistException e) {
  86. システム。 out .println( "ファイルの保存中にエラーが発生しました: " + e.getMessage());
  87. e.printStackTrace();
  88. }
  89.          
  90. texture.getPixelMap()を返します
  91. }
  92.  
  93. /**
  94. * 手紙を読む
  95. * @param ファイル名
  96. * @param 文字コンテンツ
  97. * @戻る 
  98. */
  99. パブリックPixelMap readImage(文字列ファイル名、文字列文字コンテンツ) {
  100. // 分散ファイルパスを取得する
  101. 文字列 filePath = mContext.getDistributedDir() + File.separator + fileName;
  102. // 分散ファイルパスに基づいてファイルを生成する
  103. ファイル file = new File(filePath);
  104. ファイルが存在する場合(){
  105. // ファイルが存在しない場合はwriteを呼び出します
  106. writeLetter(ファイル名、文字の内容);
  107. }
  108. // 画像パラメータ
  109. ImageSource.SourceOptions srcOpts = 新しい ImageSource.SourceOptions();
  110. srcOpts.formatHint = "image/jpeg" ;
  111. // 画像ソースを作成する
  112. ImageSource imageSource = ImageSource.作成(ファイル、srcOpts);
  113. // 画像を生成する
  114. ピクセルマップpixelMap = imageSource.createPixelmap( null );
  115.  
  116. ピクセルマップを返します
  117. }
  118.  
  119. /**
  120. * ファイルのリストを取得する
  121. * @戻る 
  122. */
  123. パブリックリスト<文字列> getFileList() {
  124. // 配布されたファイルリストを取得する
  125. ファイル[] files = mContext.getDistributedDir().listFiles();
  126. リスト<File> listFile = 新しい ArrayList<>(Arrays.asList(files));
  127. // ファイルを順番に並べ替える
  128. listFile.sort((ファイル, newFile) -> {
  129. (file.lastModified() > newFile.lastModified()) の場合 {
  130. -1 を返します
  131. }そうでない場合 (file.lastModified() == newFile.lastModified()) {
  132. 0を返します
  133. }それ以外{
  134. 1 を返します
  135. }
  136. });
  137. リスト<文字列> listFileName = 新しいArrayList<>();
  138. // ファイルリストのファイル名を取得する
  139. for (ファイル f : listFile) {
  140. if (f.isFile()) {
  141. 文字列= f.getName();
  142. リストファイル名。 (名前)を追加します
  143. }
  144. }
  145. listFileNameを返します
  146. }
  147. }

ToastUtil プロンプト メッセージ ボックス:

  1. パッケージ com.army.study.util;
  2.  
  3.  
  4. com.army.study.ResourceTable をインポートします。
  5. ohos.agp.components.Component をインポートします。
  6. ohos.agp.components.LayoutScatter をインポートします。
  7. ohos.agp.components.Text をインポートします。
  8. ohos.agp.window.dialog.ToastDialog をインポートします。
  9. ohos.app.Context をインポートします。
  10.  
  11. /**
  12. * トーストツール
  13. *
  14. */
  15. パブリッククラスToastUtil {
  16. プライベート ToastDialog toastDialog;
  17.  
  18. プライベートToastUtil() {
  19. }
  20.  
  21. 公共 静的ToastUtil getInstance() {
  22. ToastUtilInstance.INSTANCEを返します
  23. }
  24.  
  25. プライベート静的クラス ToastUtilInstance {
  26. プライベート静的最終 ToastUtil INSTANCE = new ToastUtil();
  27. }
  28.  
  29. /**
  30. * トーストを表示
  31. *
  32. * @param コンテキスト
  33. * @param コンテンツ
  34. */
  35. パブリックvoid showToast(コンテキスト コンテキスト、文字列コンテンツ) {
  36. toastDialog がnullの場合、 toastDialog.isShowing() は次のように記述します。
  37. トーストダイアログをキャンセルします。
  38. }
  39.  
  40. コンポーネント toastLayout = LayoutScatter.getInstance(context)
  41. .parse(ResourceTable.Layout_layout_toast, null false );
  42. テキスト toastText = (テキスト) toastLayout.findComponentById(ResourceTable.Id_text_msg_toast);
  43. toastText.setText(コンテンツ);
  44. toastDialog = 新しい ToastDialog(コンテキスト);
  45. toastDialog.setComponent(toastLayout);
  46. pastDialog.setTransparent( true );
  47. トーストダイアログを表示します。
  48. }
  49. }

手紙の内容をプレビューします:

  1. /**
  2. * 手紙の内容をプレビューする
  3. */
  4. パブリッククラスPreviewLetterDialogはCommonDialogを拡張します{
  5.  
  6. パブリックプレビューレターダイアログ(コンテキストコンテキスト、ピクセルマップ画像ID) {
  7. super(コンテキスト);
  8. コンポーネント コンテナー = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dialog_previce_letter, null , false );
  9. コンテナにカスタムコンポーネントを設定します。
  10. MATCH_PARENT と MATCH_CONTENT のサイズを設定します。
  11.  
  12. SetCornerRadius(AttrHelper.vp2px(20, コンテキスト));
  13.  
  14. 画像 image = (画像) container.findComponentById(ResourceTable.Id_preview);
  15. イメージIDをピクセルマップに設定します。
  16.  
  17.  
  18. ボタン btnCancel = (Button) container.findComponentById(ResourceTable.Id_button_dialog_create_file_cancel);
  19. ボタン btnConfirm = (Button) container.findComponentById(ResourceTable.Id_button_dialog_create_file_confirm);
  20.  
  21. btnCancel.setClickedListener(コンポーネント -> { destroy();});
  22. btnConfirm.setClickedListener(コンポーネント -> { destroy();});
  23. }
  24.  
  25. }

手紙を書くダイアログボックス:

  1. /**
  2. * 手紙を書くダイアログ
  3. */
  4. パブリッククラスCreateLetterDialogはCommonDialogを拡張します{
  5. プライベートOnCallBack onCallBack;
  6.  
  7. パブリックCreateLetterDialog(コンテキストコンテキスト) {
  8. super(コンテキスト);
  9. コンポーネント コンテナー = LayoutScatter.getInstance(context).parse(ResourceTable.Layout_dialog_write_letter, null , false );
  10. コンテナにカスタムコンポーネントを設定します。
  11.  
  12. オプション<Display> display = DisplayManager.getInstance().getDefaultDisplay(context);
  13. int幅 = ( int ) (display.get().getAttributes().width * 0.9);
  14. int高さ = AttrHelper.vp2px(270, コンテキスト);
  15. setSize(幅、高さ);
  16. SetCornerRadius(AttrHelper.vp2px(20, コンテキスト));
  17.  
  18. テキストフィールド letterContent = (テキストフィールド) container.findComponentById(ResourceTable.Id_tf_dialog_create_file_name);
  19. ボタン btnCancel = (Button) container.findComponentById(ResourceTable.Id_button_dialog_create_file_cancel);
  20. ボタン btnConfirm = (Button) container.findComponentById(ResourceTable.Id_button_dialog_create_file_confirm);
  21. btnConfirm.setEnabled( false );
  22. btnConfirm.setAlpha(0.5f);
  23. letterContent.addTextObserver((テキスト、i、i1、i2) -> {
  24. テキストが空の場合
  25. btnConfirm.setEnabled( false );
  26. btnConfirm.setAlpha(0.5f);
  27. }それ以外{
  28. btnConfirm.setEnabled( true );
  29. btnConfirm.setAlpha(1f);
  30. }
  31. });
  32.  
  33. btnCancel.setClickedListener(コンポーネント -> { destroy();});
  34.  
  35. btnConfirm.setClickedListener(コンポーネント -> {
  36. onCallBack! = nullの場合{
  37. // デバイスID
  38. 文字列デバイスID = KvManagerFactory.getInstance().createKvManager(新しいKvManagerConfig(コンテキスト))
  39. .getLocalDeviceInfo().getId();
  40. // ファイル名を結合して、現在のデバイスによって作成されたファイルかどうかを区別します
  41. 文字列= deviceID + "-" + letterContent.getText();
  42. onCallBack.onConfirm(名前);
  43. }
  44. 破壊する();
  45. });
  46. }
  47.  
  48. パブリックvoid setOnCallBack(OnCallBack onCallBack) {
  49. onCallBack メソッドは、次のコードで呼び出されます。
  50. }
  51.  
  52. パブリックインターフェースOnCallBack{
  53. void onConfirm(文字列);
  54. }
  55. }

メインインターフェースコード図:


それだけです。 config.json ファイルで権限を設定することを忘れないでください。モジュールの下に追加します。

  1. 「必要な権限」 : [
  2. {
  3. 「名前」 : 「ohos.permission.DISTRIBUTED_DATASYNC」  
  4. },
  5. {
  6. 「名前」 : 「ohos.permission.GET_DISTRIBUTED_DEVICE_INFO」  
  7. },
  8. {
  9. 「名前」 : 「ohos.permission.DISTRIBUTED_DEVICE_STATE_CHANGE」  
  10. },
  11. {
  12. 「名前」 : 「ohos.permission.WRITE_MEDIA」  
  13. },
  14. {
  15. 「名前」 : 「ohos.permission.READ_MEDIA」  
  16. }
  17. ]、

詳細については、以下をご覧ください。

51CTOとHuaweiが共同で構築したHongmengテクノロジーコミュニティ

https://harmonyos..com

<<:  テンセントクラウドテクノハブテクノロジーツアー成都駅が終了、文化・クリエイティブ産業におけるフルスタックテクノロジーの実践を専門家がどのように解釈するかをご覧ください

>>:  FaaS(Function as a Service)市場は急速な成長を遂げる

推薦する

クラウドコンピューティング業界のアップグレードを支援するH3Cがクラウドネイティブ変革に関する洞察を共有

政策の恩恵とデジタル経済の加速的な発展に牽引され、クラウドネイティブ技術は急速に発展し、企業のデジタ...

マルチクラウド戦略のベストプラクティス

マルチクラウド戦略を追求する企業にはさまざまなメリットがあります。パブリック クラウドまたはハイブリ...

インターネットは格闘技の世界のようなものです。いまだに何人のウェブマスターがさまよっているのでしょうか?

人がいるところに武術の世界があります。どうやってやめることができますか?これは映画「微笑む誇り高き放...

思考と洞察がウェブマスターの人生を決定する

今日、私はこのトピックについて根拠もなく話しているのではなく、何人かのウェブマスター(SEO担当者)...

ビジネスを台無しにする可能性のあるクラウド コンピューティングの 10 の間違い

クラウドは IT とビジネスの世界を永久に変えました。そして、全体としてこれらの変化は良い方向へ向か...

ドメイン名投資ポジショニング分析: 鶏の頭よりも不死鳥の尾の方が良い

先日、A5チャットイベントにゲストが招かれ、ウェブマスター向けのドメイン名投資について講演しました。...

アップルは中国で「グーグルのジレンマ」に直面

Google が中国の検閲への協力をやめることを決定したとき、同社は中国発のサイバー攻撃を指摘した。...

スクイーズページを最適化するための 4 つのヒント

スクイーズページとは、電子メール情報収集ページを指します。通常、電子メール入力ボックスを備えた小さな...

ispserver: ロシアの VPS、ロシアのサーバー、無制限のトラフィック、PayPal 支払い

ispserver、設立年は不明ですが、ドメイン名は1998年に登録され、公式発表情報は2001年か...

Kubernetes Gateway API が Ingress に勝る理由

オープンソースの Kubernetes Gateway API のリリースにより、ネットワーク In...

メタバース総合知識分析

メタバースは、一般的には現実世界と並行する仮想世界として理解できます。現実世界で人々ができることはす...

ウェブサイト上のglobal.asaトロイの木馬の被害と解決策

この期間中、顧客の Web サイトがハッキングされたケースがいくつか見つかりました。これらの Web...

SEO はいつまで人気が続くのでしょうか? 「遅れをとっている」 SEO 担当者はどうすれば台頭できるのでしょうか?

誰もが初めて SEO 業界に入るとき、自分が選んだ業界が近い将来、社会や人々から忘れ去られ、見捨てら...

クラスター化されたウェブサイト構造におけるランキングの弱点の原因の分析

クラスターサイト開発モデルを採用している人材募集サイトの場合、省都のランキングは長い間あまり理想的で...