- 投稿日:2022-02-23T21:58:47+09:00
【AndroidStudio】xmlにあるandroidとかtoolsとかappの違いって何?
xmlにあるandroidとかtoolsとかappの違い xmlには以下の画像のようにandroidとかappとかtoolsという名前空間?が存在します。 これらは何を表していて、お互いどのように違うのでしょうか。 調べる 調べてみるとtoolsに関しては公式ドキュメントで以下の通りに説明されていました。 Android Studio では tools 名前空間でさまざまな XML 属性がサポートされており、これを使用して設計時の機能(フラグメントに表示するレイアウトの選択など)やコンパイル時の動作(XML リソースに適用する圧縮モードの選択など)を有効にできます。これらの XML 属性はアプリのビルド時にビルドツールによって削除されるため、APK のサイズと実行時の動作には影響しません。 これらの XML 属性を使用するには、次のように、それらを使用する各 XML ファイルのルート要素に tools 名前空間を追加します。 参考:ツール属性のリファレンス 先輩に聞く しかし他については分からなかったので先輩に聞くと次のような 大変わかりやすい回答が得られました。 android : View毎の属性(オプション?)を設定するときに指定する app : 上記に加えて、カスタムViewを作った際にattr.xmlで定義した属性を設定するときに指定する tools : 主にプレビューウィンドウで確認したい属性を設定するときに指定する わかりやすっ!!
- 投稿日:2022-02-23T21:26:15+09:00
Android12のバックグランドからのフォアグランドサービス起動制限が起きそうで起きない件を調べた話
概要 targetSdkversionを31に上げて影響を調査していたときの話です。バックグランドからのフォアグランドサービス起動制限の影響を食らうだろうと思っていたのにテストしてみたら全然クラッシュしませんでした。理由がわからないと不安なので、時間の許す範囲で調べてみました。 条件・環境 端末:Pixel6 OS:Android12 経緯 ドキュメントを見るとバックグランドからフォアグランドサービス起動時はForegroundServiceStartNotAllowedExceptionがスローされるとあります。 しかし、バックグランドからのフォアグランドサービス起動をテストしても狙ったところでこの例外は発生せず、意図しないところで発生しました。 調査方法 Androidのソースコードを見ていると起動中のサービスについての情報がServiceRecordなるものに書かれている雰囲気なので、それが確認できればなぜ例外が発生しないのかわかりそうに思いました。検索すると下記の記事に表示方法がありました。 結果 アプリをバックグランドにしてしばらくしてから前回テストしたときと同じフォアグランドサービスを起動させてServiceRecordを確認したところ、次のような部分を見つけました。 code:BLUETOOTH_BROADCAST; tempAllowListReason:<broadcast:1000:android.bluetooth.adapter.action.STATE_CHANGED, reason:,reasonCode:BLUETOOTH_BROADCAST,duration:10000,callingUid:1000> どうもBLUETOOTH_BROADCASTのため一時的にサービス起動が許可されているように見えます。 ドキュメントを見直すと、BLUETOOTH_CONNECT又はBLUETOOTH_SCANパーミッションが必要なBluetoothブロードキャストを受信したときは、この制限の例外とありました。 追加確認1 アプリをバックグランドにして、Bluetoothのブロードキャストを受信するフォアグラウンドサービスを起動した状態で、ブロードキャストを受信しない別のフォアグラウンドサービス(以後サービス2と呼ぶ)を起動してみました。サービス2のServiceRecord確認すると、tempAllowListResonはnullとなっています。アプリがホワイトリスト入りしたような状態になり、他のフォアグラウンドサービスの起動もできているように見えます。サービス2の動作も正常でした。 code:PROC_STATE_FGS; tempAllowListReason:<null>; 追加確認2 アプリをバックグランドにして、Bluetoothのブロードキャストを受信するフォアグラウンドサービスを終了し、ブロードキャストを受信しないフォアグラウンドサービスを起動すると、このサービスのServiceRecordはありませんでした。logcatを確認してみるとForegroundServiceStartNotAllowedExceptionが発生していました。 追加確認1で「サービス2」が起動できたのは、「Bluetoothのブロードキャストを受信するフォアグラウンドサービス」のお陰だったようです。 補足 前述の「Androidのソースコードを見ていると起動中のサービスについての情報がServiceRecordなるものに書かれている雰囲気」についての補足です。 Androidのソースはこちらから確認しました。 「ForegroundServiceStartNotAllowedException」で検索すると、下記ファイルが怪しいと思いました。 frameworks/base/services/core/java/com/android/server/am/ActiveServices.java ※他の検索結果はファイルパスの途中にtestとかあったり、コメントだったりしました。 次の部分で問題の例外がスローされるようです。 if (fgRequired) { logFgsBackgroundStart(r); if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) { String msg = "startForegroundService() not allowed due to " mAllowStartForeground false: service + r.shortInstanceName; Slog.w(TAG, msg); showFgsBgRestrictedNotificationLocked(r); logFGSStateChangeLocked(r, FrameworkStatsLog.FOREGROUND_SERVICE_STATE_CHANGED__STATE__DENIED, 0); if (CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) { throw new ForegroundServiceStartNotAllowedException(msg); } return null; } 例外スローまでに通るif分岐は3つ 1. if (fgRequired) { 2. if (r.mAllowStartForeground == REASON_DENIED && isBgFgsRestrictionEnabled(r)) 3. if(CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid)) 1. if (fgRequired) 関数の参照元を辿るとStartForegroundSericeから呼ばれたならTrueになる模様。フォアグラウンドサービスなのでStartForegroundSerice()を使っておりTrueのはずです。 2-1(2の前半). r.mAllowStartForeground == REASON_DENIED REASON_DENIED、mAllowStartForegroundでコード検索してもセットされている場所はヒットしませんでした。ただ、serviceRecord.javaのserviceRecordクラスにこの変数が定義されているようです。 2-2(2の後半). isBgFgsRestrictionEnabled(r) 関数の定義を見ると互換性フレームワークツール※のフラグをチェックしている様子。開発者オプションから確認するとすべてONなので、ここもTrueのはずです。(ざっとしか見てないので、違ってたらすみません。) ※互換性フレームワークについて 3. CompatChanges.isChangeEnabled(FGS_START_EXCEPTION_CHANGE_ID, callingUid) 関数名からここも互換性フレームワークのフラグをチェックしていると判断。Trueのはずです。(ざっとしか見てないので、違ってたらすみません。) 補足のまとめ 結局、mAllowStartForegroundの値次第のようですが、何を判定してここにREASON_DENIED がセットされるかまでは追跡出来ませんでした。ソースコードにこだわると時間がかかるため、ServiceRecordの確認方法を探すことにしました。
- 投稿日:2022-02-23T21:07:36+09:00
【Appium】自動テストがしたいのにAndroid Chromeのようこそ画面が邪魔
事の発端 業務でウェブアプリの自動テストの需要が高まってきたので、Appiumの環境構築をして動作確認をしていた時の話です。 なんとかPC版Chromeで動作するようになったので、じゃあAndroid実機でも!と思い実行。 これじゃテスト動かんやん!なんでや!! でも新品の端末買ってきた、みたいな新鮮さだけはある。 【環境】 - Mac OS 12.2.1 - Android 12(実機Pixel 3a) - Appium 1.22.2(CUI) - Python3.6 解決法 capabilitiesにappPackageとappActivityではなく、browserNameを使用する。 driver = webdriver.Remote( command_executor='http://127.0.0.1:4723/wd/hub', desired_capabilities={ 'platformName': 'Android', 'platformVersion': '12', 'deviceName': 'Pixel 3a', 'browserName': 'Chrome', # 必須 # 'appPackage': 'com.android.chrome', # NG # 'appActivity': 'com.google.android.apps.chrome.Main', # NG 'chromeOptions': { 'w3c': False, }, }) 原因 GitHubのIssueが参考になりました。 When browser name is not strictly equals one from CHROME_BROWSERS array Appium 1.5+ is using ADB instead of Chromedriver and this is why we get such strange screenshots. Appium 1.4 contrarily was matching Chrome by app package name and this is why it worker with any browser name capability. So to solve this issue you just need to change browser name to one from the list above. Appium 1.4まではパッケージ名を指定してましたが、1.5以降はブラウザ名を指定するようになっていると。パッケージ名が指定されているとchromedriverでなくADB経由でchromeを起動するので、welcomeページが表示される…みたいです(解釈合ってます?)。 調べたら'chromeOptions': {'args': ['--disable-fre']}をつけるとか、色々見つかったんですが、私の場合効果はなかったです。 ネイティブアプリでの構築記事を参考にしたのがまずかったか。。appActivityの設定が悪いのかと思い、随分遠回りしましたが、なんとかなりました。ようこそページの操作も自動化する…なんて力技をしなくてよかったです。
- 投稿日:2022-02-23T19:28:37+09:00
build.gradleをbuild.gradle.ktsへ移行したい!
ビルド構成を Groovy から KTS に移行するのドキュメントによると、 Kotlin の方が可読性が高く、コンパイル時のチェックと IDE サポートが優れているため、今後、Gradle スクリプトの記述には Groovy よりも KTS が優先されます。 とあります。今後はGroovyのビルドスクリプトよりもKotlinビルドスクリプトの方が主流になっていくものと思われます。 とはいえ、未だにAndroid Studioで新規作成したプロジェクトはbuild.gradleで作られるし、Groovyのスクリプトで運用している開発環境はたくさんあると思います。 Android StudioではJavaからKotlinへは自動変換できますが、GroovyのビルドスクリプトをKotlinに変換する機能はまだありません。そのため、移行は手動で行う必要があります。 移行方法は上記リンク先にも記載がありますが、ビルドスクリプトの一部分しか紹介されていないため初見だと難しいです。 なので、今回はチュートリアルみたいな感じで、実際のbuild.gradleをbuild.gradle.ktsに置き換える手順を紹介したいと思います。 Step 0: 元のbuild.gradle 以下のようなbuild.gradleがあったとします。これをbuild.gradle.ktsへ移行してみます。 build.gradle plugins { id 'com.android.application' id 'org.jetbrains.kotlin.android' } android { compileSdk 31 defaultConfig { applicationId "com.niusounds.myapplication" minSdk 24 targetSdk 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = '1.8' } buildFeatures { viewBinding true } } dependencies { implementation 'androidx.core:core-ktx:1.7.0' implementation 'androidx.appcompat:appcompat:1.4.1' implementation 'com.google.android.material:material:1.5.0' implementation 'androidx.constraintlayout:constraintlayout:2.1.3' testImplementation 'junit:junit:4.13.2' androidTestImplementation 'androidx.test.ext:junit:1.1.3' androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0' } Step 1: 'を"に置き換える。 まだファイル名はbuild.gradleのままです。 まずはbuild.gradleの中にある'を"に置き換えましょう。 エディタの一括置換を使ったり、マルチカーソルを使ったりして機械的に置き換えると良いでしょう。 build.gradle plugins { id "com.android.application" id "org.jetbrains.kotlin.android" } android { compileSdk 31 defaultConfig { applicationId "com.niusounds.myapplication" minSdk 24 targetSdk 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { viewBinding true } } dependencies { implementation "androidx.core:core-ktx:1.7.0" implementation "androidx.appcompat:appcompat:1.4.1" implementation "com.google.android.material:material:1.5.0" implementation "androidx.constraintlayout:constraintlayout:2.1.3" testImplementation "junit:junit:4.13.2" androidTestImplementation "androidx.test.ext:junit:1.1.3" androidTestImplementation "androidx.test.espresso:espresso-core:3.4.0" } Step 2: ()を付ける 次に、以下の箇所に()を付けるように修正します。 pluginsブロックのid dependenciesブロックのimplementation等 proguardFiles consumerProguardFiles ※なぜ()を付けるのかというと、これらはGradleのAPI的にはメソッドとして定義されているものだからです。 build.gradle plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { compileSdk 31 defaultConfig { applicationId "com.niusounds.myapplication" minSdk 24 targetSdk 31 versionCode 1 versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { viewBinding true } } dependencies { implementation("androidx.core:core-ktx:1.7.0") implementation("androidx.appcompat:appcompat:1.4.1") implementation("com.google.android.material:material:1.5.0") implementation("androidx.constraintlayout:constraintlayout:2.1.3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") } Step 3: =を付ける 次に、以下の箇所に=を付けるように修正します。 compileSdk minSdk targetSdk applicationId versionCode versionName testInstrumentationRunner sourceCompatibility targetCompatibility useSupportLibrary buildFeaturesブロックのviewBinding等 ※なぜ=を付けるのかというと、これらはGradleのAPI的にはプロパティとして定義されているものだからです。 build.gradle plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { compileSdk = 31 defaultConfig { applicationId = "com.niusounds.myapplication" minSdk = 24 targetSdk = 31 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { minifyEnabled false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { viewBinding = true } } dependencies { implementation("androidx.core:core-ktx:1.7.0") implementation("androidx.appcompat:appcompat:1.4.1") implementation("com.google.android.material:material:1.5.0") implementation("androidx.constraintlayout:constraintlayout:2.1.3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") } ここまでの手順ではbuild.gradleのままでもビルドは通っているはずです。もし、ビルドエラーが出る箇所があったら、=か()のどちらを付けるか間違えているのだと思います。逆の方を付けてみましょう。 それでも難しい場合は、一旦コメントアウトして修正を後回しにするのも良いです。 Step 4: ktsにリネーム ここまで来たら、一度build.gradleをbuild.gradle.ktsにリネームします。 リネーム後に./gradlew assembleなどを実行すると、おそらくビルドが失敗します。が、Step 1〜3の手順を行っていればエラーが出る箇所は限定的になるため、一つずつエラーの行を直していけば修正できます。 この段階では、エラーが出る行はとりあえずコメントアウトするのがおすすめです。そしてひとまず./gradlew tasksだけでもエラーなく通るようにしましょう。 一度ビルドを通せる状態になればAndroid Studioがbuild.gradle.kts内をコード補完できるようになります。 エラー箇所をコメントアウトしていき、./gradlew tasksが通せるようになったら、次のStepに進みます。 build.gradle.kts plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { compileSdk = 31 defaultConfig { applicationId = "com.niusounds.myapplication" minSdk = 24 targetSdk = 31 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { // minifyEnabled false // TODO あとで直す proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { viewBinding = true } } dependencies { implementation("androidx.core:core-ktx:1.7.0") implementation("androidx.appcompat:appcompat:1.4.1") implementation("com.google.android.material:material:1.5.0") implementation("androidx.constraintlayout:constraintlayout:2.1.3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") } Step 5: 壊れた箇所を置き換える ./gradlew tasksが通るようになったら、コメントアウトした箇所をちょっとずつコメント解除して、Kotlinの書き方に直していきます。 その際、Android Studioのコード補完が使えるはずなので、参考にしましょう。 minifyEnabledをisMinifyEnabled =にする build.gradle android { buildTypes { release { minifyEnabled false } } } build.gradle.kts android { buildTypes { release { isMinifyEnabled = false } } } task定義を置き換える カスタムタスク、たとえばプロジェクトルートのbuild.gradleで宣言されているcleanタスクのようなものを移行する場合は、以下のような感じになります。 task clean(type: Delete) { delete rootProject.buildDir } tasks.create<Delete>("clean") { delete(rootProject.buildDir) } というわけで、シンプルなビルドスクリプトであればここまでの手順で置き換えが完了しているはずです。 出来上がったのがこちらになります。 build.gradle.kts plugins { id("com.android.application") id("org.jetbrains.kotlin.android") } android { compileSdk = 31 defaultConfig { applicationId = "com.niusounds.myapplication" minSdk = 24 targetSdk = 31 versionCode = 1 versionName = "1.0" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } buildTypes { release { isMinifyEnabled = false proguardFiles(getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro") } } compileOptions { sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 } kotlinOptions { jvmTarget = "1.8" } buildFeatures { viewBinding = true } } dependencies { implementation("androidx.core:core-ktx:1.7.0") implementation("androidx.appcompat:appcompat:1.4.1") implementation("com.google.android.material:material:1.5.0") implementation("androidx.constraintlayout:constraintlayout:2.1.3") testImplementation("junit:junit:4.13.2") androidTestImplementation("androidx.test.ext:junit:1.1.3") androidTestImplementation("androidx.test.espresso:espresso-core:3.4.0") } Step 6: その他、いろいろ置き換える ここから先はプロジェクトにより様々だと思うので、個別の事例を紹介していくのは難しいです。 私が趣味でメンテしているプロジェクトでbuild.gradleのkts移行を行った際の差分はこんな感じですので、よかったら参考にしてみてください。 https://github.com/niusounds/libReaStream/pull/16/files https://github.com/niusounds/wdl-android/pull/1/files
- 投稿日:2022-02-23T17:36:21+09:00
Play console上のFlutterアプリ更新手順メモ
#バージョンを更新 pubspec.yaml内のバージョンを更新する version: 1.0.0+3 #Appbundleファイルを作成する $ flutter build appbundle 下記フォルダにaabファイルが作成される build\app\outputs\bundle\release\app-release.aab #Play Consoleにファイルアップロード 製品版 → 新しいリリースを作成 → AppBundle内にアップロード リリースの詳細に修正箇所などを記載 保存 → リリースのレビューを確認 確認して公開で完了
- 投稿日:2022-02-23T13:59:49+09:00
【Android/iOS】Webブラウザのアドレスバーを非表示にする方法
はじめに Android/iOSのWebブラウザのアドレスバーを非表示にする方法です。 ネットで調べて出てくることには出てくるのですが、なかなかたどり着かなかったのでQiitaに投稿しておきます。 やりたいこと 据え置きのタブレット端末でWebアプリを動作させるときに、アドレスバーを非表示にしたい。 ↓ 調べたところ、Webブラウザの設定でフルスクリーン(アドレスバー非表示)にするのは無理そう。 (フィッシングサイトによる悪用などを考慮している?) ↓ Webブラウザの設定変更以外の方法でアドレスバーを非表示にしたい。←今回やりたいこと 結論 以下のサイトを参考にしました。 [HTML5] フルスクリーンの開始と解除 対象ページのheadタグ内に以下のmetaタグを記述します。 <!-- iOS用 --> <meta name="apple-mobile-web-app-capable" content="yes"> <!-- Android用 --> <meta name="mobile-web-app-capable" content="yes"> 対象ページへのショートカットをホーム画面に追加し、ホーム画面から対象ページに移動するとアドレスバーが表示されなくなります。 AndroidのChromeブラウザであれば、対象ページを開いた状態でブラウザのメニューから「ホーム画面に追加」を選択することでショートカットを作成できます。 作成したショートカットから対象ページに移動するとアドレスバーが非表示になります。 (スクショ撮るのにXperia 1を使ってるので画面が長い。。。) アドレスバーが非表示になりました。 ちなみに、普通に表示したとき(アドレスバーあり)はこんな感じです。 Androidを例にしましたが、iOSでも同様です。 おわりに Android/iOSのWebブラウザのアドレスバーを非表示にすることで、Webアプリをネイティブアプリっぽくすることができました。 初めからネイティブアプリで作っていれば、こんなことに煩わされなくて済むんですけどね。 モバイルアプリ開発の知見がまだないので、時間があるときにUdemyあたりで勉強してみようと思います。
- 投稿日:2022-02-23T11:46:06+09:00
【Flutter-Android】【GithubActions】flutterのCD環境を整備してみた
はじめに 普段仕事ではiOSアプリを開発していますが、 昨年5月頃からFlutterに興味を持ち始め、趣味の時間でFlutterアプリの勉強を始めました。 アプリの配信は毎回手間に感じていて自動化できないか?と調査をしていた内容を共有します。 今回はAndroid編です。iOS編はこちら。 目標 Githubにコードがpushされたときに、AndroidアプリをStoreにビルド配信する。 Storeにビルド配信する。 では作業を開始します。 最終的なフォルダ構成 . ├── .github │ └── workflows │ ├── cd_aos.yml・・・・Android用githubActionsの設定ファイル ├── android │ └── fastlane │ ├── Appfile・・・・Store関係の設定が書かれたファイル │ └── Fastfile・・・・fastlaneの設定ファイル └── 以下省略 注意!!~今回説明しないもの~ 申し訳ないのですが、今回は以下の環境設定方法については省略します。 - GooglePlayStore(deveploper)の登録や設定方法 - Githubの登録や設定方法 - GithubActionsの知識 作業の流れ fastlaneを用意する Storeに配信するための設定 Fastfileを設定する github actionsを準備 あとはコミット!! 1. fastlaneを用意する ※作業ディレクトリは、/android/ で実施します。 今回は署名の管理や面倒なビルドコマンドの省略のためにfastlaneを使用しました。 (xcodebuildやgradleなどのコマンド、flutterのコマンドからでもビルドが作成できれば、それでも良いと思います) fastlaneには多くの便利な"アクション"が定義されています。アプリのビルドであったり、配信であったり、単体テストなども、fastlaneに定義されているアクションを利用可能です。 1-1. fastlaneを準備する fastlaneは、iOSアプリ開発 及び Androidアプリ開発をサポートするツールです。 https://docs.fastlane.tools/ fastlaneの導入は以下のコマンドより実行します。 xcode-select --install sudo gem install fastlane -NV fastlane init fastlane/にファイルが作成されたでしょうか? 作成されたAppfileやFastfileに設定を書き加えていきます。 2. Storeに配信するための設定 いよいよfastlaneを使って、ビルドから配信を行うまでの設定を行います、fastlaneの細かな設定はFastfileで行います。 と、、その前に更にいくつかの設定を行います。Storeに配信するための設定です。 2-1. fastlane supplyの準備 Android側では、fastlane supplyを使ってAndroidのStore配信を行います。 その準備として、iOSと同じようにStoreアップロード用にAPIなどを用意します。 iOSと比べて、こちらは少し面倒です。。。 2-1-1. 認証用のjsonファイルを作成 Google Play Consoleを開いて、メニューから「アカウントの詳細」を開いて「ディベロッパーアカウントID」をメモしておきます 次に、メニューから「設定」→「APIアクセス」を開きます。 「リンクするプロジェクトを選択」を押下すると、次のような画面となります。 そこで「新しいサービスアカウントを作成」を押下します。ダイアログが開くため指示に従っていきます。 GCPを開きます。メニューから「サービスアカウント」を開きます。アカウントがない場合は次の画像のような画面が開きます。そこで「+サービスアカウントを作成」を選びます。 サービスアカウントの作成では以下のような画面になります。サービスアカウント名を入力します。その後に「@...」の部分に、手順2でメモした「ディベロッパーアカウントID」があることを確認して下さい。また、「.iam.gserviceaccount.com」があることも確認して下さい。問題なければ「作成して続行」を押下します。 次のステップではアカウントにロールを設定します。ここでは「サービスアカウントユーザー」を設定します。 次のステップは特に何もせずに完了とします。 GCPの画面では下記のような状態になります。 キーがないため、キーを作成します。3点リーダーでメニューを開き、「鍵を管理」を選びます。 次の画面にて「新しい鍵を作成」します。 JSONを選択していることを確認して、鍵を作成します。 元の画面(GooglePlayConsole)に戻ります。元表示されていたダイアログを閉じる、再リロードすると作成したサービスアカウントの情報が反映されます。 ここでアクセス権を設定します。fastlaneのドキュメント上ではAdminが推奨されていますが、リリース関係のみ許可をして「ユーザーを招待」します。 ここまででjsonファイルの作成は完了です。 2-1-2. 作成したjsonファイルの確認 まずは下記のコマンドで動きを確認します。 fastlane run validate_play_store_json_key json_key:/path/to/your/downloaded/file.json 下記の結果が得られれば成功です。 [21:08:37]: ------------------------------------------ [21:08:37]: --- Step: validate_play_store_json_key --- [21:08:37]: ------------------------------------------ +----------+--------------------------------------+ | Summary for validate_play_store_json_key | +----------+--------------------------------------+ | json_key | /Users/hogetaro/Desktop/pc-api-4XXXX | | | 4YYYYYYYYYYYYYYYYYYYYYYYYYYYYY.json | | timeout | 300 | +----------+--------------------------------------+ [21:08:37]: Successfully established connection to Google Play Store. 2-1-3. AppFileを設定 今作成したjsonファイルなどをAppfile内に設定します。 json_key_file("path/to/your/play-store-credentials.json") package_name("my.package.name") 記載を終えたら、 fastlane supply init これでsupplyの準備は完了です。 3. Fastfileを設定する fastlaneでは、Fastfileに自動化タスクを「レーン」として定義することで、1コマンド(fastlane {レーン名})でタスクが実行できるようになります。 3-1. 署名済みaabファイルをfastlaneで作成 まずはローカル環境で署名済みaabファイルをfastlaneで作成してみましょう。 default_platform(:android) platform :android do desc "Deploy a new version to the Google Play" lane :deploy do gradle( task: "clean bundle", build_type: "Release", print_command: false, properties: { "android.injected.signing.store.file" => "{ビルドマシン内のjksファイルのパス}", "android.injected.signing.store.password" => "{KeyStoreのパスワード}", "android.injected.signing.key.alias" => "{keyエイリアス}", "android.injected.signing.key.password" => "{keyエイリアスのパスワード}", } ) end end 上記は、laneにdeployを定義しました。 署名つきのaabファイルを作成するfastlaneのアクションを探したところ「gradle」が使えそうなので、 「gradle」というアクションを使っています。 propertiesの設定は、ビルド時の署名情報です。リリース時に設定している内容を使います。 こちらをFastflieに記述したら、動かしてみます。 fastlane deploy これで以下のフォルダに作成されていればOKです。 /build/app/outputs/bundle/release/app-release.aab ログは以下のような感じです。 [20:19:34]: ▸ BUILD SUCCESSFUL in 53s [20:19:34]: ▸ 154 actionable tasks: 133 executed, 21 up-to-date [20:19:34]: Couldn't find any new signed apk files... +------+---------------------+-------------+ | fastlane summary | +------+---------------------+-------------+ | Step | Action | Time (in s) | +------+---------------------+-------------+ | 1 | default_platform | 0 | | 2 | clean bundleRelease | 53 | +------+---------------------+-------------+ [20:19:34]: fastlane.tools finished successfully ? 3-2. ローカルで作成した署名済みaabファイルをアップロードする 3-1で作成したFastfileに以下の処理を追加します。 upload_to_play_store( aab: "../build/app/outputs/bundle/release/app-release.aab", skip_upload_metadata: true, skip_upload_images: true, skip_upload_screenshots: true ) こちらのactionも、play storeに配信するfastlaneのアクションを探して見つけました。 Fastflieに追記したら、動かしてみます。 fastlane deploy 以下のログを得られたらOKです! [22:37:49]: Preparing aab at path '../build/app/outputs/bundle/release/app-release.aab' for upload... [22:38:17]: Updating track 'production'... [22:38:19]: Preparing to upload for language 'ja-JP'... [22:38:20]: Updating changelog for '4' and language 'ja-JP'... [22:38:20]: Uploading all changes to Google Play... [22:38:23]: Successfully finished the upload to Google Play +------+----------------------+-------------+ | fastlane summary | +------+----------------------+-------------+ | Step | Action | Time (in s) | +------+----------------------+-------------+ | 1 | default_platform | 0 | | 2 | clean bundleRelease | 32 | | 3 | upload_to_play_store | 39 | +------+----------------------+-------------+ [22:38:23]: fastlane.tools finished successfully ? 4. github actionsを準備 ルートの直下に、以下の構成でファイルを用意します。 .github/workflows/{githubActionsの設定ファイル名}.yml バイナリの署名の設定を「app/build.gradle」に移動します。 署名のファイルをリポジトリ管理するようにして、以下のような設定を行います。 ※iOSのfastlaneのような署名管理方法があれば教えて欲しいです・・・ signingConfigs { release { storeFile file("../config/KeyStore.jks") //check that the file exists storePassword "KeyStorePassword" keyAlias "keyAlias" keyPassword "keyPassword" } } buildTypes { release { signingConfig signingConfigs.release } } 署名関係については、 ・supplyの設定で作成したjsonファイル ・リリース用のjksファイル ・署名設定を反映したapp/build.gradleファイル 以上が準備できていればOKと思います。 さて、ようやくですが。。yamlファイルの中身は以下を設定しました。 name: CD_Android # Controls when the workflow will run on: # Triggers the workflow on push or pull request events but only for the master branch push: branches: [ master ] # Allows you to run this workflow manually from the Actions tab workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: aos_distribution: runs-on: macos-11 if: | contains(github.event.head_commit.message, '[Release]') == true && contains(github.event.head_commit.message, '[AOS]') == true name: Distribution(AOS) steps: - uses: actions/checkout@v2 # install fastlane - name: Install fastlane run: gem install fastlane - name: Setup flutter uses: subosito/flutter-action@v1 with: flutter-version: '2.5.3' - name: Set up tools run: | flutter pub get - name: ExportPath run: | export PATH=$PATH:${FLUTTER_HOME}/bin/cache/dart-sdk/bin export PATH=$PATH:${FLUTTER_HOME}/.pub-cache/bin # Build & Deploy - name: Run builds(fastlane) run: | cd android/ ls fastlane deploy env: JSON_KEY_PATH: ${{ secrets.JSON_KEY_PATH }} GithubSecrets上に環境変数を定義します。 JSON_KEY_PATH:fastlane supplyの設定で作成したJSONファイルへのパス 簡単な説明や補足 flutterのリポジトリのため、コミットメッセージに[Release]と[AOS]がある場合にTestFlightへのアップロードを行うこととしました。 if: | contains(github.event.head_commit.message, '[Release]') == true && contains(github.event.head_commit.message, '[AOS]') == true gradlewに関する以下のエラーが発生した場合は、gradle関連のファイルをコミットします。 エラー: Couldn't find gradlew at path gradle関連のファイルがコミットされていなければコミットします。 android/gradle/ android/gradlew localPropertiesFileに関する以下のエラーが発生した場合も修正します。 エラー: assert localPropertiesFile.exists() こちらを参考にして修正しました。 Flutter SDKが見つからないエラーがあったため、SDKのセットアップ処理を追加しました。 エラー: Flutter SDK not found. - name: Set up tools run: | flutter pub get - name: ExportPath run: | export PATH=$PATH:${FLUTTER_HOME}/bin/cache/dart-sdk/bin export PATH=$PATH:${FLUTTER_HOME}/.pub-cache/bin - name: Setup flutter uses: subosito/flutter-action@v1 with: flutter-version: '2.5.3' 5. あとはコミット。祈るだけ。 あとはコミットしてみて祈るだけです。 さいごに お疲れ様でした。 iOS、Androidの二部構成で記事を作成しています。もしよければiOS側の記事もご覧いただけますと幸いです。Flutterの良さは1コードで2OSに配信できることです。CD環境を整備して、そのリリース速度を加速していければと思います。
- 投稿日:2022-02-23T00:06:04+09:00
Mattermost スマホアプリ インストール手順
Apple iPhone (iOS) 【インフォメーション】 端末: Apple iPhone 7 Plus OS: 15.4 1. 「App Store」をタップします 2. 右下の「検索」をタップします 3. 「? ゲー、App、ストーリーなど」と書かれている領域をタップします 4. 「Mattermost」と入力して検索します 5. 「Mattermost」の右横にある「入手」をタップします 6. ホーム画面に戻り、Mattermostのアプリがインストールされていることを確認してください Google Android OS (Xiaomi MIUI / OPPO ColorOS / Huawei EMUI) 【インフォメーション】 端末: SHARP AQUOS R3 型番: 808SH OS: Android 11 ビルド: S2006 キャリア: SoftBank GooglePlayストア: 29.2.13-21[0][PR]426460052 1. 「Play ストア」をタップします 2. 上の「? アプリやゲームを検索」と書かれている領域をタップします 3. 「Mattermost」と入力して検索します 4. 一番最初の「Mattermost」をタップします 5. 「インストール」をタップします 6. ホーム画面に戻り、Mattermostのアプリがインストールされていることを確認してください Google Playが使えない端末 (例: Amazon Kindle, Huawei P40 Series) 【インフォメーション】 端末: Huawei P40 lite 5G 型番: CDY-NX9A OS: EMUI 10.1.1(Android 10ベース) ビルド: 10.1.1.295(C635E2R1P1) セキュリティパッチレベル: 2022年1月1日 1. 「ブラウザ」をタップして開きます 2. 検索に「Mattermost git」と入力して検索します 3. 「Mattermost・GitHub」をタップします 4. 「mattermost-mobile」をタップします 5. 「Mobile Version ○○○」をタップします 6. 「Mattermost arm54-v8a」をタップします 7. インストールを許可してインストールします ※自動的にこの画面にならない場合は通知バーからダウンロード完了通知をタップしてください 8. ホーム画面にアプリが追加されていることを確認してください