- 投稿日:2020-07-30T13:42:46+09:00
Firebase Dynamic Links について
はじめに
Firebase Dynamic Links で Android の Deeplink を実装することになったので、そのメモとして残しておきます。
Android プロジェクトに Firebase を追加する
公式に手順がまとめられているの
https://firebase.google.com/docs/android/setup?hl=ja※ SHA-1 情報は Firebase Dynamic Links で必要になるため忘れないようにする。さらに App Links を利用する場合は、 SHA-256 情報も必要になる。
※ ディープリンク URL は有効な URL でなければならない。google-services.json をダウンロードして設定
app └── src ├── main │ ├── AndroidManifest.xml │ ├── java │ └── res ├── dev │ └── google-servicesjson.json ├── stg │ └── google-services.json └── prd └── google-services.jsonDynamicLinks の設定
コンソール上で作成する
or
手動で以下のようにする
{DynamicLinksのURL}/ ?link={http(s)://で始まるリンク、主にアプリ用のURLエンコード済みのDeepLinkURL} &apn={Androidアプリパッケージ名} &ibi={iOSアプリバンドルID} &isi={iOSアプリストアID} &ius={iOSアプリをフックするカスタムスキーム} &dfl={デスクトップ用リンク}※ クエリパラメータを使う場合には基本的には後者を利用する
詳しくは以下をご覧ください
https://firebase.google.com/docs/dynamic-links/create-manuallyAndroid で Firebase Dynamic Links を受信する
https://firebase.google.com/docs/dynamic-links/android/receive?hl=ja#kotlin+ktx
おわりに
まだ、きちんとした実装に入っていないため、追記+修正すると思います
- 投稿日:2020-07-30T12:17:22+09:00
Android: VideoをBitmapに変換する
はじめに
Android で、Video のデコードは、
MediaCodec
で、簡単に実装できる。
が、MediaCodec
ではデコード結果は、Image
かByteBuffer
として取得できる。
これをBitmapに変換する方法に苦労したので知見をここに残す。開発環境
Android, Kotlin
コード
サンプルコードは https://github.com/kenmasumitsu/VideoToImages 参照
解説
一言で言うと、
Android CameraXのドキュメント で言及されている、YuvToRgbConverter.kt
を使って、Image
をBitmap
に変換のがポイント。ググると、
- https://stackoverflow.com/questions/41775968/how-to-convert-android-media-image-to-bitmap-object
- https://stackoverflow.com/questions/44486188/android-convert-image-object-to-bitmap-does-not-work
など見つかるが、うまく動かない。
は、正しく動くが、処理時間が長い。
YuvToRgbConverter.kt
の 約6倍。 (Pixel 3)補足
https://bigflake.com/mediacodec/ で紹介されている、https://bigflake.com/mediacodec/ExtractMpegFramesTest_egl14.java.txt でも、同程度高速に正しく動作する。
- 投稿日:2020-07-30T10:23:38+09:00
内部アプリ共有したアプリでGoogleログインができない
結論
内部アプリ共有では、ビルド時に指定した署名ファイルのSHA-1フィンガープリントではなく、内部アプリ共有用のフィンガープリントで、OAuthクライアントを指定してやる必要がある。
手順
AndroidでGoogleログインする際には、Google Developer ConsoleにてOAuthクライアントの認証情報を設定してやる必要がありますよね。
その際に、アプリの署名のSHA-1フィンガープリントを設定する項目があります。
内部アプリ共有でテスターにアプリを配信する際、この項目を内部アプリ共有用のSHA-1フィンガープリントにしてやる必要があります。
本番用の設定を変更して本番のアプリが動かなくなっても困るので、「内部アプリ共有用」とでも名前をつけたOAuthクライアント認証情報を新たに作成してやるのがいいかと思います。
パッケージ名は認証情報同士で重複しても平気なようです。内部アプリ共有用のSHA-1フィンガープリント
で、その内部アプリ共有用のSHA-1フィンガープリントがどこで手に入るかというと、GooglePlay Consoleです。
内部アプリ共有の中に「アプリの証明書」というタブがあるので、その中にある「SHA-1 証明書のフィンガープリント」をコピーしてGoogle Developer Consoleに設定してあげてください。
背景
ローカルでUSB経由で実機にデプロイしたリリースビルドだと動作するのに、内部アプリ共有だとGoogleから「DEVELOPER_ERROR」が返ってきて何事だよ…と思ったらこういうことでした。
- 投稿日:2020-07-30T08:57:59+09:00
シンボルを見つけられません。import android.support.v4.app.ActivityCompatの読み込みエラー
ReactNativeでAndroidのネイティブモジュールを実装しようとしたところ、前使っていたコードが動かないことがわかりました。
/path/project/android/app/src/main/java/com/project/TestModule.java:28: エラー: シンボルを見つけられません import android.support.v4.app.ActivityCompat; ^ シンボル: クラス ActivityCompat 場所: パッケージ android.support.v4.app
というエラーがでました。
どうやら、android.v4はサポートが切れ、
代替えとして、androidx.に移行する必要があるようです。調べたところ、やることは2つで、
① dependencyの追加
build.gradleのdependenciesに
implementation "androidx.core:core-ktx:+"を追加
② importするパッケージの変更
import android.support.v4.app.ActivityCompat -> import androidx.core.app.ActivityCompat import android.support.v4.content.ContextCompat -> import androidx.core.content.ContextCompaに変更することで動くようになります。
- 投稿日:2020-07-30T07:44:14+09:00
新卒プログラマの学習ログ 〜 其の二 〜
App Architecture
Codelabsをとりあえず一周、手を動かしながら進めてみました。
その中で、書かれているコードのパターンが、MVVM(Model-View-ViewModel)と呼ばれるアーキテクチャです。
Googleより推奨されているライブラリを用いた実装パターンで、これに従うことでメンテナンス性、可読性に優れたプログラムとして開発を行うことができるとされています。
しかし、普及としては割と最近のようで、Androidアプリ開発者用の参考書ではまだまだ異なるパターンの記述が多い印象です。MVVMとは?
先述の通りModel-View-ViewModelを表しています。
Model
データを管理する役割を担います。
APIやデータベースを扱う際のDaoやdataクラスに当たります。View
UIコントローラーの役割を担います。
画面表示や遷移、Fragmentの切り替えやユーザーのアクションを検知するリスナーをここで設定します。
Viewの管理はDataBindingのライブラリによって行っています。
下記のコードではフラグメントでの実装です。MainFragment.ktclass MainFragment : Fragment() { // OnCreateView以外でも参照するため、lateinitで定義しておきます private lateinit var binding: MainFragmentBinding private lateinit var viewModel: ViewModel override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? { binding = DataBindingUtil.inflate( inflater, R.layout.game_fragment, container, false ) Log.i("MainFragment", "Called ViewModelProviders.of") // viewModelの取得 viewModel = ViewModelProviders.of(this).get(GameViewModel::class.java) binding.sampleButton.setOnClickListener { onClick() } return binding.root } /** ボタンクリック時に実行するメソッド **/ViewModel
Modelからデータを取得するViewとModel間の仲介的役割を担います。
とりあえず。。
メモ代わりに書いていますが、これから理解が深まれば書き足していきます。
初学者から一人前まで、、
ここでは一人前のプログラマの定義を
「おおよそ自力で様々なツールを活用しながら、ある程度思い通りの実装ができること」
とします。また、人生においてプログラミングに向き合う時間として、現時点で2000時間取り組めればある程度の基盤が備わると仮定しています。
(言語やツールに依存しない思考法や情報収集能力)プログラミングは大学で学んで来ましたが、特に根詰めてやってきていないので、ノーカウントとして取り組みます。
現在までの学習時間
およそ340時間
どんどん更新していきます。
- 投稿日:2020-07-30T04:15:52+09:00
ConstraintLayout入門その3 - percent
ConstraintLayoutを使用するための設定については、ConstraintLayout入門その1をご覧ください。
ConstraintLayout自動変換があればFrameLayoutやLinearLayoutを捨てられる?
Android Studioは、レイアウトXMLファイルに書かれた既存のViewを他のViewクラスに自動変換する機能を持っており、これを使ってLinearLayoutなどをConstraintLayoutに変換することができます。しかし、本稿執筆時点の最新安定版のAndroid Studio ver.4.0.1でこの機能を試してみた結果は期待はずれ、とても自動変換だけでそのままアプリに使えるConstraintLayoutになってくれません。LinearLayoutで垂直ないし水平に並んだViewの並びをConstraintLayoutの制約表現に変える機能だけならまだしも、LinearLayoutでよく使われる
android:layout_weight
などの指定が入ったレイアウトをConstraintLayoutに変換するには手作業が不可欠のようです。本稿ではその辺りを突っ込んでみます。percent
LinearLayoutは単に子Viewをまっすぐ並べるだけでなく、
android:layout_weight
という属性を子Viewに持たせることによって、その長さを柔軟に設定することができます。ConstraintLayoutでは、app:layout_constraintWidth_percent
,app:layout_constraintHeight_percent
の2つの属性がそれに近い機能を果たします。
ConstraintLayoutの他の多くの属性と同様、1つの子Viewに水平方向と垂直方向に独立にpercentを設定できる点において、LinearLayoutよりも柔軟です。layout_constraint_1<?xml version="1.0" encoding="utf-8"?> <androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="wrap_content" xmlns:app="http://schemas.android.com/apk/res-auto" android:orientation="horizontal" android:background="#CAEB5E" tools:showIn="@layout/activity_main"> <TextView android:id="@+id/txtC11" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.167" android:gravity="center_horizontal" android:background="@drawable/rect_frame" android:textColor="@android:color/black" android:textSize="14sp" /> <TextView android:id="@+id/txtC12" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="@id/txtC11" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.333" android:gravity="center_horizontal" android:background="@drawable/rect_frame" android:textColor="@android:color/black" android:textSize="14sp" /> <TextView android:id="@+id/txtC13" android:layout_width="0dp" android:layout_height="wrap_content" app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toEndOf="@id/txtC12" app:layout_constraintWidth_default="percent" app:layout_constraintWidth_percent="0.5" android:gravity="center_horizontal" android:background="@drawable/rect_frame" android:textColor="@android:color/black" android:textSize="14sp" /> </androidx.constraintlayout.widget.ConstraintLayout>上の記述例のポイントは、子Viewに
android:layout_width="0dp"
を設定しているところです。ConstraintLayoutは、「長さゼロ」に MATCH_CONSTRAINT, すなわち従来からの MATCH_PARENT や WRAP_CONTENT のような特別な意味を割り当てています。「長さゼロ」のときにのみ、app:layout_constraintWidth_percent
が無視されず意味を持ちます(同様に、app:layout_constraintHeight_percent
を有効にするには、android:layout_height="0dp"
が必要)。
一般にapp:layout_constraintWidth_percent
,app:layout_constraintHeight_percent
には0から1の間の小数を設定し、親Viewの水平ないし垂直の長さとの比率を表します。
上の表示例は、3つのTextViewを1:2:3の長さの比率で横に並べています。percentはチェーンでも使うことができ、1–3., 2–3. はチェーンを使っています。percentの合計が1に満たないようにすると、LinearLayoutでandroid:weightSum
を設定して余白部分を余らせるのと同様の表示ができます。2–3. はチェーンの効果で均等配列されます。LinearLayoutの完全上位互換ではない?
今回、LinearLayoutで
android:layout_weight
を使って表示できるレイアウトのすべてをConstraintLayoutで実現するつもりで記事を書いたのですが、筆者がやってみた限りでは、表示例の3. のように「子Viewにゼロを超える長さ (ここでは100dp) を与えておいてウェイト (ここでは1:2:3) を設定する」というケースをConstraintLayoutで表現できませんでした。
LinearLayoutでこのように設定すると、子Viewで幅を100dp (ここでは262.5px) ずつ確保しておいて、さらにLinearLayoutが持っている余白を1:2:3の比率で子Viewに分配する (48.5px, 97.5px, 146.5px) という2段階の長さ割り当てが行われます。
しかしConstraintLayoutのpercentではこのような割り当てができません。percentを設定する子Viewは「長さゼロ」を指定しなければならないので子View固有の長さを設定できません。layout_constraintWidth_min
を使っても同じようにはなりませんでした。
ConstraintLayoutはFrameLayoutやLinearLayoutなど配置用のViewGroupの完全上位互換を目指しているのかと筆者は勝手に考えていたのですが、そうではないのかもしれません。本当に上位互換でないのかどうかは、筆者の当面の宿題とさせていただくことにします。サンプルコード
今回のサンプルコードは以下のリポジトリにあります。
https://github.com/csayamada/ConstraintLayout3ConstraintLayout入門その1、ConstraintLayout入門その2と歩みの遅いシリーズですが、ConstraintLayoutの習得は遠回りのようでも少しずつ出来ることを増やしていくのが確実だと思います。
参考文献
Constraintlayout | Android デベロッパー | Android Developers
ConstraintLayout | Android Developers余談
percentという名を使っていますが百分率ではありません (1分率) 。 'proportion' などの名前にしなくてよかったのでしょうか…?