- 投稿日:2020-08-24T19:50:36+09:00
HUAWEI ML Kitでフェースステッカーをアプリに組み込む方法
概要
今では、かわいく、おもしろいフェースステッカーをどこでも見るようになりました。カメラアプリだけでなく、ソーシャルメディアやエンタテイメントのアプリでも使用されています。今回の投稿では、HUAWEI ML Kitを使用して2Dステッカーを作成する方法をご紹介します。近いうちに、3Dステッカーの開発プロセスをお知らせしますので、ご期待ください。
シナリオ
ビューティカメラやソーシャルメディアアプリ(TikTok、Weibo、WeChatなど)など、写真を撮影して編集する場合に使用するアプリは、画像のカスタマイズに使用できる幅広いステッカーを用意しています。このようなステッカーを使って、ユーザーはより人目を引き、共有できるコンテンツを作成できます。
準備
Huawei Mavenリポジトリをプロジェクトレベルのbuild.gradleファイルに追加する
Android Studioプロジェクトのルートディレクトリにあるbuild.gradleファイルを開きます。
Mavenリポジトリアドレスを追加します。buildscript { { maven {url 'http://developer.huawei.com/repo/'} } } allprojects { repositories { maven { url 'http://developer.huawei.com/repo/'} } }SDK依存関係をアプリレベルのbuild.gradleファイルに追加する
// Face detection SDK. implementation 'com.huawei.hms:ml-computer-vision-face:2.0.1.300' // Face detection model. implementation 'com.huawei.hms:ml-computer-vision-face-shape-point-model:2.0.1.300'AndroidManifest.xmlファイルでカメラ、ネットワークアクセス、およびストレージの権限を適用する
<uses-feature android:name="android.hardware.camera" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />コードの開発
顔分析機能を設定する
顔の輪郭ポイントを取得し、FacePointEngineに渡す
MLFaceAnalyzerSetting detectorOptions; detectorOptions = new MLFaceAnalyzerSetting.Factory() .setFeatureType(MLFaceAnalyzerSetting.TYPE_UNSUPPORT_FEATURES) .setShapeType(MLFaceAnalyzerSetting.TYPE_SHAPES) .allowTracing(MLFaceAnalyzerSetting.MODE_TRACING_FAST) .create(); detector = MLAnalyzerFactory.getInstance().getFaceAnalyzer(detectorOptions);カメラのコールバックを使用してカメラのフレームデータを取得し、顔分析機能を呼び出して顔の輪郭ポイントを取得し、FacePointEngineに渡します。これにより、ステッカーフィルタはポイントを後で利用できます。
@Override public void onPreviewFrame(final byte[] imgData, final Camera camera) { int width = mPreviewWidth; int height = mPreviewHeight; long startTime = System.currentTimeMillis(); if (isFrontCamera()){ mOrientation = 0; }else { mOrientation = 2; } MLFrame.Property property = new MLFrame.Property.Creator() .setFormatType(ImageFormat.NV21) .setWidth(width) .setHeight(height) .setQuadrant(mOrientation) .create(); ByteBuffer data = ByteBuffer.wrap(imgData); SparseArray<MLFace> faces = detector.analyseFrame(MLFrame.fromByteBuffer(data,property)); if(faces.size()>0){ MLFace mLFace = faces.get(0); EGLFace EGLFace = FacePointEngine.getInstance().getOneFace(0); EGLFace.pitch = mLFace.getRotationAngleX(); EGLFace.yaw = mLFace.getRotationAngleY(); EGLFace.roll = mLFace.getRotationAngleZ() - 90; if (isFrontCamera()) EGLFace.roll = -EGLFace.roll; if (EGLFace.vertexPoints == null) { EGLFace.vertexPoints = new PointF[131]; } int index = 0; for (MLFaceShape contour : mLFace.getFaceShapeList()) { if (contour == null) { continue; } List<MLPosition> points = contour.getPoints(); for (int i = 0; i < points.size(); i++) { MLPosition point = points.get(i); float x = ( point.getY() / height) * 2 - 1; float y = ( point.getX() / width ) * 2 - 1; if (isFrontCamera()) x = -x; PointF Point = new PointF(x,y); EGLFace.vertexPoints[index] = Point; index++; } } FacePointEngine.getInstance().putOneFace(0, EGLFace); FacePointEngine.getInstance().setFaceSize(faces!= null ? faces.size() : 0); }else{ FacePointEngine.getInstance().clearAll(); } long endTime = System.currentTimeMillis(); Log.d("TAG","Face detect time: " + String.valueOf(endTime - startTime)); }ML Kit APIが返す顔の輪郭ポイントは下記の画像で確認できます。
ステッカーのJSONデータの定義
猫のステッカーを作る
猫のステッカーのJSONファイルを作成し、フェースインデックスを使用して眉毛(84)の間の中心点と鼻(85)の先端の点を見つけます。猫の耳と鼻をペーストし、JSONファイルと画像をassetsディレクトリに置きます。
ステッカーをレンダリングして質感を与える
GLSurfaceViewを使用してステッカーをレンダリングして質感を与えます。これは、TextureViewを使用するより簡単です。onSurfaceChangedでステッカーフィルタのインスタンスを作成し、ステッカーのパスを渡してカメラを開始します。
onSurfaceChangedでステッカーフィルタを初期化する
onDrawFrameで画面にステッカーを描画する
以上で終わりです。作成したフェースステッカーは使用可能です。
早速、使ってみましょう。
詳しくは、当社の公式ウェブサイトをご覧ください。
当社のデモコードもご覧ください。
- 投稿日:2020-08-24T19:28:03+09:00
【Flutter, Dart, freezed】Bad state: Unexpected diagnosticsでbuildが終わらない不具合
TL;DR
pubspec.yaml
に以下の2つを追加してくださいpubspec.yamldependencies: analyzer: ^0.39.14 <- 追加 dev_dependencies: build_runner: ^1.10.0 <- 追加環境
# fvmを使用 [✓] Flutter (Channel unknown, 1.20.2, on Mac OS X 10.15.5 19F101, locale ja-JP) [✓] Android toolchain - develop for Android devices (Android SDK version 29.0.3) [✓] Xcode - develop for iOS and macOS (Xcode 11.6) [✓] Android Studio (version 4.0)症状
Bad state: Unexpected diagnostics:
が大量に表示される[INFO] 1.6s elapsed, 1/12 actions completed.
が永遠に完了しない$ fvm flutter packages pub run build_runner build --delete-conflicting-outputs [...] [INFO] Running build... [INFO] Generating SDK summary... [SEVERE] freezed:freezed on test/widget_test.dart: Bad state: Unexpected diagnostics: /Users/k3ntar0/fvm/versions/1.20.2/bin/cache/dart-sdk/lib/core/uri.dart:3259:39 - Expected an identifier. [SEVERE] freezed:freezed on test/widget_test.dart: [...] Bad state: Unexpected diagnostics: /Users/k3ntar0/fvm/versions/1.20.2/bin/cache/dart-sdk/lib/core/uri.dart:3259:39 - Expected an identifier. [INFO] 1.6s elapsed, 1/12 actions completed. [INFO] 2.6s elapsed, 1/12 actions completed. [INFO] 3.7s elapsed, 1/12 actions completed. [INFO] 4.7s elapsed, 1/12 actions completed. [INFO] 5.8s elapsed, 1/12 actions completed. [INFO] 6.9s elapsed, 1/12 actions completed. [INFO] 8.0s elapsed, 1/12 actions completed. [INFO] 9.0s elapsed, 1/12 actions completed. [INFO] 10.0s elapsed, 1/12 actions completed. [INFO] 11.1s elapsed, 1/12 actions completed. [INFO] 12.1s elapsed, 1/12 actions completed. [INFO] 13.2s elapsed, 1/12 actions completed. [INFO] 14.2s elapsed, 1/12 actions completed. [INFO] 15.2s elapsed, 1/12 actions completed. [WARNING] No actions completed for 15.1s, waiting on: - freezed:freezed on lib/main.dart - freezed:freezed on lib/app.dart - freezed:freezed on lib/presentation/common/colors.dart - freezed:freezed on lib/presentation/pages/home/home_page.dart - freezed:freezed on lib/presentation/pages/index.dart .. and 6 moreやること
pubspec.yaml
を変更する- きれいにする
- buildし直す
※ fvmを使用されていない場合はfvmの部分を消して実行してください
pubspec.yaml
を変更するpubspec.yamldependencies: analyzer: ^0.39.14 <- 追加 dev_dependencies: build_runner: ^1.10.0 <- 追加きれいにする
# pubspec.lockを削除 $ rm -rf pubspec.lock # clean $ fvm flutter clean Cleaning Xcode workspace... 2.9s Deleting .dart_tool... 3ms Deleting Generated.xcconfig... 0ms Deleting flutter_export_environment.sh... 0msbuildし直す
# pub get $ fvm flutter pub get Running "flutter pub get" in my_project... 2.5s # build_runnerを実行 $ fvm flutter packages pub run build_runner build --delete-conflicting-outputs Precompiling executable... Precompiled build_runner:build_runner. [INFO] Generating build script... [...] [INFO] Succeeded after 18.8s with 1 outputs (12 actions)fvmを使用されていない場合は記述不要です!
- 投稿日:2020-08-24T19:14:33+09:00
[MVVM-DataBinding] 数字入力のEditTextに単位とセパレーターを自動で追加する
背景
数字入力に限定した
EditText
(android:inputType="number"
)に対して、3桁ごとのセパレーターとsuffix
として単位をつけたい理由
・ユーザーに極力数字以外のものを受け付けたくない
・桁数と単位でより入力内容をわかりやすくしたい環境
MVVM-DataBinding
※導入方法は省略実装
今回は長さ(m)を例に実装します
やりたい事は、もしユーザーが
1222
と入力したとすると、1,222m
とEditText
に表示させたいですXML
snippet.xml<data> <import type="your.package.name.Converter" /> <variable name="viewModel" type="your.package.name.SnippetViewModel" /> </data> (略) <EditText android:id="@+id/length_m" android:layout_width="match_parent" android:gravity="end|center_vertical" android:hint="0m" android:inputType="number" android:maxLines="1" android:paddingStart="0dp" android:paddingEnd="8dp" android:text="@={Converter.addNumberSeparatorAndUnitMeter(viewModel.length)}" android:textSize="18sp" />・
ViewModel
をbinding
のvariable
として登録
・EditText
の内容を後述するMutableLiveData
と対応させたいので双方向データバインディングしています
・Converter
のimport
と使用、こちらも後述ViewModel
SnippetViewModel.ktclass SnippetViewModel() : ViewModel() { val length = MutableLiveData<Int>() (略)ここでは対象の
MutableLiveData
を定義していますConverter
ここでは
EditText
上でユーザーが数字が入力するものの、EditText
には数字+セパレーター+単位
を表示したいわけです
ただし、今回は双方向データバインディングのため、またユーザーが数字を入力する際に、EditText
に表示されている数字+セパレーター+単位
をそのままgetText
等で使い数字のまま使えるわけではないので不整合が生じやすいですそのため、
・EditTextへの入力内容(Int) -> EditTextの表示内容(String)
・EditTextの表示内容(String) -> EditTextの入力内容(Int)これらをうまく変換するためのメソッドが必要になります
ここで役立つのが、@InverseMethodです
@InverseMethod
では上記の変換、逆変換をスマートにこなしてくれます
今回の例でいうとこのようになりますConverter.ktobject Converter { @InverseMethod("inverseToInt") @JvmStatic fun addNumberSeparatorAndUnitMeter(value: Int): String { val intValueWithFormat = String.format("%,d", value) return "${intValueWithFormat}m" } @JvmStatic fun inverseToInt(value: String?): Int { return kotlin.runCatching { value?.replace("m", "")?.replace(",", "")?.toInt() } .getOrNull() ?: 0 } }ひとつめの
addNumberSeparatorAndUnitMeter
ではユーザーが入力した内容=LiveDataの値
に対してセパレーターとmの単位を付与しています@InverseMethod("inverseToInt")の
inverseToInt
は逆変換するのに必要なメソッド名になります
これにより再度ユーザーが数字を入力した際、逆変換のメソッドが呼ばれIntとなり、そのIntの値を使ってまたaddNumberSeparatorAndUnitMeter
が呼ばれるということになります
inverseToInt
メソッドでは数字+セパレーター+単位をIntに戻していますこれでユーザーが数字を入力するだけで
EditText
にセパレーターと単位を補助入力できるようになりました?InverseMethodを使うと何が嬉しいの?
個人的な意見です
・パターンに応じた複雑なロジックを自前で定義する手間が減る
・変換、逆変換の処理を無限ループしにくい状態で定義できる
・もとのLiveData
の値を変換していないままの型(今回はInt
)として使うことができるので、その値を使ったバリデーションや値変換(Transformations.map
)がしやすいおわり
以上です 参考になれば幸いです
よりよい方法がありましたら是非ご教授ください?
- 投稿日:2020-08-24T16:46:17+09:00
HUAWEI ML Kitを使用した銀行カード認識の実装方法
概要
以前の投稿では、HUAWEI ML Kitを使用してSmile-CameraとID用写真のDIYアプレットを実装する方法について検討しました。今回の投稿では、銀行カード認識機能の実装方法をご紹介します。この機能により、ユーザーは銀行カードを瞬時に紐付けることができます。
銀行カード認識の用途
開発に着手する前に、銀行カード認識機能の用途について確認しましょう。銀行アプリやeコマースアプリなど、支払い機能を備えたアプリに最適です。このようなアプリには、いくつか共通の要件がある場合が多いです。
- 銀行カードの紐付け
ユーザーは自分の銀行カードを紐付けて、オンライン決済を素早く行うことができます。
- 銀行振込
ユーザーは同一銀行内または異なる銀行の口座間でお金を振り込むことができます。
- 本名での認証とID確認
ユーザーは、自分の銀行カードに紐付けられた情報使用して、本名での認証とID確認を素早く実施できます。
このような機能ではそれぞれ、ユーザーはカード番号や有効期限など、銀行カード情報を入力する必要があります。当然、このような情報を手入力するのは時間がかかり、誤入力も発生しやすくなります。しかし、HUAWEI ML Kitの銀行カード認識サービスにより、ユーザーは情報を簡単かつ正確に入力できます。
銀行認識サービスの利用方法
銀行カード認識サービスは、カメラストリームで銀行カードを認識し、カード番号や有効期限など重要な情報を抽出します。このサービスはIDカード認識サービスと連携しており、ID確認や銀行カード番号入力など、幅広い一般向け機能を提供します。
内蔵して、アプリでサービスを利用できるようにする、銀行カード認識プラグインがあります。プラグインは、ユーザーに代わってカメラストリームを処理します。
開発を始める
1.準備
1.1 Huawei Mavenリポジトリをプロジェクトレベルのbuild.gradleファイルに追加する
Android Studioプロジェクトのルートディレクトリにあるbuild.gradleファイルを開き、Mavenリポジトリアドレスを追加します
buildscript { repositories { maven {url 'http://developer.huawei.com/repo/'} } }allprojects { repositories { maven { url 'http://developer.huawei.com/repo/'} }}1.2 SDK依存関係をアプリレベルのbuild.gradleファイルに追加する
dependencies{ implementation 'com.huawei.hms:ml-computer-vision-bcr:1.0.3.303' implementation 'com.huawei.hms:ml-computer-card-bcr-plugin:1.0.3.300' implementation 'com.huawei.hms:ml-computer-card-bcr-model:1.0.3.300'1.3 アプリのモデルが自動的に最新版に更新されるようにする
アプリがHUAWEI AppGalleryからダウンロードされるとすぐに、アプリの機械学習モデルが自動的に最新版に更新されるようにするには、以下の内容をAndroidManifest.xmlファイルに追加します。
<manifest ... <meta-data android:name="com.huawei.hms.ml.DEPENDENCY" android:value= "bcr"/> <!--If multiple models are required,set the parameter as follows: android:value="object,ocr,face,label,icr,bcr,imgseg"--> ... </manifest>1.4 AndroidManifest.xmlファイルでカメラとストレージの権限を適用する
<uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />2 コードの開発
2.1 認識結果の取得後に呼び出されるコールバック関数を作成する
onSuccess、onCanceled、onFailure、およびonDenied関数をオーバーライドします。
onSuccess:認識が成功すると呼び出されます。MLBcrCaptureResultは認識結果を示します。
onCanceled:ユーザーが認識をキャンセルすると呼び出されます
onFailure:認識が失敗すると呼び出されます。
onDenied:何らかの理由で認識要求が却下される(カメラが使用できないなど)と呼び出されます。
private MLBcrCapture.Callback callback = new MLBcrCapture.Callback() { @Override public void onSuccess(MLBcrCaptureResult bankCardResult){ } @Override public void onCanceled(){ } @Override public void onFailure(int retCode, Bitmap bitmap){ } @Override public void onDenied(){ } };2.2 認識機能のcaptureFrame APIを呼び出すための認識パラメータを設定する
認識結果は、2.1で作成したコールバック関数を通して返されます。
private void startCaptureActivity(MLBcrCapture.Callback callback) { MLBcrCaptureConfig config = new MLBcrCaptureConfig.Factory() .setOrientation(MLBcrCaptureConfig.ORIENTATION_AUTO) .create(); MLBcrCapture bankCapture = MLBcrCaptureFactory.getInstance().getBcrCapture(config); bankCapture.captureFrame(this, callback); }2.3 Recognitionボタンのコールバックで、2.2で定義したメソッドを呼び出す
@Override public void onClick(View v) { switch (v.getId()) { case R.id.detect: startCaptureActivity(callback); break; default: break; } }試してみましょう
ソースコード
ソースコードをGitHub にアップロードしているので、機能の向上など自由にお試しください。
銀行カード認識のデモコードはMLKit-Sample\module-text\src\main\java\com\mlkit\sample\activity\BankCardRecognitionActivity.javaをご覧ください。
詳しくは、当社の公式ウェブサイトをご覧ください。近日公開予定
これからも、実用的な場面でのHUAWEI ML Kitの使用方法をお知らせしますので、ワクワクするような内容に是非ご注目ください。
- 投稿日:2020-08-24T16:04:46+09:00
あのファーウェイスマホのカメラ機能をアプリにも取り入れる?
はじめに
ファーウェイのスマートフォンといえば、高性能なカメラ機能で有名ですよね。
アパーチャモード、夜景モード、ポートレートなどの処理にもハードウェアやSoc性能に依存します。
アプリ単体だと簡単に作れない機能です。HMS CameraKit
現在販売しているファーウェイのスマートフォンにはHMS(Huawei Mobile Service)が搭載していて、アプリ開発向けの独自のSDK群が提供しています。
もちろん一般的なPushやIn App purchaseなどのSDKは提供している以外に、HUAWEI独自のSDKもアプリ開発者に提供しています。
それを取り入れたアプリをファーウェイ独自のアプリストアAppGallery公開すれば、全世界のファーウェイスマートフォンユーザーに配信することができます。その中に、ファーウェイスマートフォンで使われているカメラ機能をSDKとして提供されたのがCameraKitです。
![]()
![]()
(引用元:https://developer.huawei.com/consumer/en/doc/development/Media-Guides/3180101)CameraKitをアプリに取り入れる準備
1、HUAWEI IDを新規登録
2、開発者アカウントを登録GooglePlayやAppStoreと同様に開発者登録が必要ですが、
ファーウェイの開発者アカウント開設およびSDK運用はすべて無料で提供しています。
登録方法は公式サイトを参考:
https://developer.huawei.com/consumer/en/doc/10104CameraKitの開発
CameraKitをAppGallery Connectコンソール画面から入手し、AndroidStudioプロジェクトに取り入れ、依存関係を追加します。
(公式サイト:https://developer.huawei.com/consumer/en/doc/development/Media-Guides/3180103)次に、各カメラ機能のAPI導入:
フロントカメラHDRモードSet mCurrentModeType to Mode.Type.HDR_MODE.スーパーナイトモード
Set mCurrentModeType to Mode.Type.SUPER_NIGHT_MODE.ウルトラワイドアングルモード
Set mCurrentModeType to Mode.Type.BOKEH_MODE.レコーディングモード
Set mCurrentModeType to Mode.Type.VIDEO_MODE.ポートレートモード
Set mCurrentModeType to Mode.Type.PORTRAIT_MODE.ノーマルモード
Set mCurrentModeType to Mode.Type.NORMAL_MODE.スーパースローモーションレコーディングモード
Set mCurrentModeType to Mode.Type.SUPER_SLOW_MOTION.スローモーションレコーディングモード
Set mCurrentModeType to Mode.Type.SLOW_MOTION_MODE.など
- 投稿日:2020-08-24T16:04:46+09:00
あのファーウェイスマホのカメラ機能をアプリでも取り入れる?
はじめに
ファーウェイのスマートフォンといえば、高性能なカメラ機能で有名ですよね。
アパーチャモード、夜景モード、ポートレートなどの処理にもハードウェアやSoc性能に依存します。
アプリ単体だと簡単に作れない機能です。HMS CameraKit
現在販売しているファーウェイのスマートフォンにはHMS(Huawei Mobile Service)が搭載していて、アプリ開発向けの独自のSDK群が提供しています。
もちろん一般的なPushやIn App purchaseなどのSDKは提供している以外に、HUAWEI独自のSDKもアプリ開発者に提供しています。
それを取り入れたアプリをファーウェイ独自のアプリストアAppGallery公開すれば、全世界のファーウェイスマートフォンユーザーに配信することができます。その中に、ファーウェイスマートフォンで使われているカメラ機能をSDKとして提供されたのがCameraKitです。
![]()
![]()
(引用元:https://developer.huawei.com/consumer/en/doc/development/Media-Guides/3180101)CameraKitをアプリに取り入れる準備
1、HUAWEI IDを新規登録
2、開発者アカウントを登録GooglePlayやAppStoreと同様に開発者登録が必要ですが、
ファーウェイの開発者アカウント開設およびSDK運用はすべて無料で提供しています。
登録方法は公式サイトを参考:
https://developer.huawei.com/consumer/en/doc/10104CameraKitの開発
CameraKitをAppGallery Connectコンソール画面から入手し、AndroidStudioプロジェクトに取り入れ、依存関係を追加します。
(公式サイト:https://developer.huawei.com/consumer/en/doc/development/Media-Guides/3180103)次に、各カメラ機能のAPI導入:
フロントカメラHDRモードSet mCurrentModeType to Mode.Type.HDR_MODE.スーパーナイトモード
Set mCurrentModeType to Mode.Type.SUPER_NIGHT_MODE.ウルトラワイドアングルモード
Set mCurrentModeType to Mode.Type.BOKEH_MODE.レコーディングモード
Set mCurrentModeType to Mode.Type.VIDEO_MODE.ポートレートモード
Set mCurrentModeType to Mode.Type.PORTRAIT_MODE.ノーマルモード
Set mCurrentModeType to Mode.Type.NORMAL_MODE.スーパースローモーションレコーディングモード
Set mCurrentModeType to Mode.Type.SUPER_SLOW_MOTION.スローモーションレコーディングモード
Set mCurrentModeType to Mode.Type.SLOW_MOTION_MODE.など
- 投稿日:2020-08-24T15:23:30+09:00
既存のAndroidアプリは意外と簡単にHMS対応に改修できます
はじめに
この前の記事では、HMS(Huawei Mobile Service)とは何なのかについて説明しました。今回は、どうやって既存のAndroidアプリを改修すればHMS端末(GMSが使用できないHuawei端末)で使えるようになるのかについて紹介したいと思います。タイトル通り、実は既存のAndroidアプリは意外と簡単にHMS対応に改修することができます。
SDKの使用状況によるアプリの分類
前回の記事で紹介したように、HMS端末ではGMSとfirebaseのSDKが使用できません。
しかし、HMS端末のOSはAOSP(Android Open Source Project)ベースですので、Androidのネティーブコンポーネントは継続的に使用できます。
AOSPとGMSの関係についてはこちらの記事でかなり分かりやすく紹介されていますので気になる方は確認してください。
https://qiita.com/hirossyi73/items/700e1be8e2b8f472b098また、GMS以外のサードパーティーSDKの場合、GMSに依存していなければ継続的にHMS端末で使用できます。
まとめるとこんな感じになります。
1. GMSとfirebaseのSDK:使用できません
2. Androidのネティーブコンポーネント:継続的に使用可能
3. 3rd partyのSDK:GMSに依存していなければ使用可能以上のSDKの使用状況に応じて、既存のAndroidアプリを以下の2種類に分けることができます。
1. GMSとfirebaseのSDKを使用していないアプリ:改修不要→そのままHMS端末で使用できます
2. それ以外のアプリ:若干の改修が必要次に、2の改修が必要なアプリについて詳細を説明します。
どんな改修が必要なのか
必要な改修は、GMSとfirebase関連のSDKをHMSのSDKに差し替えるか、あるいは既存のアプリにHMSのSDKを追加するかだけです。
AOSPの部分は、HMS端末で継続的に使用できますので改修が不要で、HMSのSDKさえあればアプリはHMS端末で問題なく動きますのでHMS SDKが必須となります。
以上のように、HMS版アプリを開発するときにはおもに以下の2つのソリューションがあります。
1. GMS SDKをHMS SDKに差し替える(G2H)
2. 既存アプリにHMS SDKを追加する(G+H)個人的には2のG+Hソリューションが非常に魅力的に感じていますので、G+Hソリューションについて紹介したいと思います。
G+Hソリューションの特徴と実現方法
G+Hソリューションの特徴としては:
Pros: 1つのパッケージで複数のプラットフォームに登録できます
Cons: パッケージのサイズが若干増えます
が挙げられます。実現方法の例として、GoogleとHuaweiが提供しているAPIで端末のGMS/HMSの状況を判別し、それぞれの場合に該当するAPIを使用すればGMS端末とHMS端末両方で問題かく動作できるようになります。
GMSが使えるかどうかの判定方法:
GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this) == com.google.android.gms.common.ConnectionResult.SUCCESSHMSた使えるかどうかの判定方法:
HuaweiApiAvailability.getInstance().isHuaweiMobileNoticeAvailable(this) == com.huawei.hms.api.ConnectionResult.SUCCESS以上の判定方法を使用したG+Hソリューションのイメージ(GMSを優先的に使用する場合):
if(GMS avaliable){ //元コード }else if(HMS available){ //HMSの場合のコード }この方法を採用することで、既存のAndroidアプリを若干修正することでGMS、HMS端末両方で問題なく使用できるアプリに改修できます。
終わりに
この記事では、既存のAndroidアプリのHMS対応方法の概要を説明しました。詳細な改修方法について、今後簡単なデモアプリを用いて説明していきたいと思います。
- 投稿日:2020-08-24T15:12:32+09:00
【Flutter/ Dart】外部アプリを起動して画像をシェアする方法
概要
共有機能(UI」で言うと
<
のやつ)を実装するために試行錯誤した結果、採用した方法を記します。結論
esys_flutter_share
を使って簡単に実装できました。ちなみに他に試したのは下記です。
- Platform Channelsを使ってネイティブのコードに処理を委譲(外部アプリを起動)する。
- shareプラグイン(画像のシェアができず断念)設定
pubspec.yamldependencies: esys_flutter_share: [version]※
flutter pub get
を忘れずにコード
impportして
import 'package:esys_flutter_share/esys_flutter_share.dart';この2行だけで終わり!
final ByteData bytes = await rootBundle.load('assets/image.png'); await Share.file('タイトル', 'ファイル名', bytes.buffer.asUint8List(), 'image/png', text: '本文');複数ファイルのシェアやHTTP経由で取得した画像のシェアも簡単にできるようです。
参考
- 投稿日:2020-08-24T03:21:55+09:00
【Android9.0 Pie Java】LINE風にチャット一覧画面→個人チャット画面の遷移アニメーションを実装(サンプルアプリ付)
環境
Android9.0 Pie Java
はじめに
以前投稿した、
【Android9.0 Pie Java】チャットアプリで横スワイプ→ダイアログ表示→削除を実装する
の続きになります。
- チャット一覧の要素を押すと右から左へ覆い被さるようにチャット画面のfragmentが重なる
- < ボタンを押すと左から右へチャット画面のfragmentが消える
完成品URL
全てのコードを載せると大変なことになるので、この記事では省略しています。
チャット画面のlayoutやAdapter等のファイルも含めてDLして動かしてみたい方はこちらからどうぞ!
https://github.com/yuta-matsumoto/chatコード
ChatListFragment.java
「チャット一覧の要素を押すと右から左へ覆い被さるようにチャット画面のfragmentが重なる」実装のコア部分になります。
チャット一覧の各要素のonItemClickの部分をピックアップします。
ChatListFragment.javaの全文はこちらChatListFragment.java// チャット一覧のアダプター final ChatListAdapter adapter = new ChatListAdapter(list) { @Override public void onItemClick(View view, int pos, List<ChatListRowData> list) { // 選択したユーザーの情報を渡す ChatFragment fragment = new ChatFragment(); // fragment間のデータ受け渡しにはBundleが便利 Bundle args = new Bundle(); if (args != null) { args.putString("userName", list.get(pos).getName()); fragment.setArguments(args); } // 画面遷移の準備 FragmentTransaction transaction = getFragmentManager().beginTransaction(); // 左から右へfragmentを重ねるアニメーション transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); // (1) // ChatListFragmentの上にChatFragmentを重ねる transaction.add(R.id.mainContainer, fragment, "fragment"); // (2) // バックスタックに加える transaction.addToBackStack(null); transaction.commit(); } };(1) Fragment間の画面遷移に好きなアニメーションを利用するために、
FragmentTransaction.setCustomAnimations
を利用しています。
res配下に以下の構成でアニメーションの定義を用意して読み込みます。├res/
├anim/
├slide_in_left.xml
└slide_out_right.xmlslide_in_left.xml<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="100%p" android:toXDelta="0" android:duration="@android:integer/config_mediumAnimTime"/> <alpha android:fromAlpha="1.0" android:toAlpha="1.0" android:duration="@android:integer/config_mediumAnimTime" /> </set>slide_out_right.xml<?xml version="1.0" encoding="utf-8"?> <set xmlns:android="http://schemas.android.com/apk/res/android"> <translate android:fromXDelta="0" android:toXDelta="100%p" android:duration="@android:integer/config_mediumAnimTime"/> <alpha android:fromAlpha="1.0" android:toAlpha="1.0" android:duration="@android:integer/config_mediumAnimTime" /> </set>(2)
transaction.add
を利用することで、ChatListFragmentの上にChatFragmentを重ねることができます。ChatFragment.java
「< ボタンを押すと左から右へチャット画面のfragmentが消える」実装のコア部分になります。
チャット一覧の各要素のonViewCreatedの部分をピックアップします。
ChatFragment.javaの全文はこちらChatFragment.java@Override public void onViewCreated(View view, Bundle savedInstanceState) { //・・・省略 // <ボタンのリスナー ImageButton backButton = view.findViewById(R.id.backButton); backButton.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { // 画面遷移の準備 FragmentTransaction transaction = getFragmentManager().beginTransaction(); // 右から左へfragmentが消えるアニメーション transaction.setCustomAnimations(R.anim.slide_in_left, R.anim.slide_out_right); // (1) // ChatFragmentを削除 transaction.remove(chatFragment); // (2) transaction.commit(); } }); }(1) ChatListFragmentの記述と同様でOKです。
(2)
transaction.remove
を利用することで、ChatFragmentを削除しています。以上です。
最後に
このアニメーションの動きの再現をするには、どうしても複数のActivityを利用すると上手く決まらず、
Activity自体重いので、1 Activity + N Fragmentの構成にしました。
最近実機にビルドしてもらったのですが、結構カッコよく動いたので嬉しいです!!