たくさんの自由帳
Androidのお話
たくさんの自由帳
文字数(だいたい) : 2970
どうもこんばんわ。Google I/Oもうすぐってマジ?Android 開発のサイトを見るとAndroid 17の新機能(新API)があんまり書かれてないのですが、API 追加差分を見るとそこそこ増えている。
たとえばMediaProjection(画面共有API)に、既存の画面共有に加えてアプリコンテンツプロジェクション?とか言うのが追加されたのですが、↑で取り上げられてないため何者なのかは分かっていません。
あとは、ついにSurfaceViewをぼかす?APIが追加される模様。やった!!!でもAndroid 17以降しか使えない悲しみも同時に襲われる。
これらがGoogle I/Oで発表があるかは謎です。
Xiaomiのスマートフォンは、なぜかadb installするためにはUSB デバッグとは別の設定を有効にする必要があるのですが、
この設定を有効にするにはSIM カードを刺したりXiaomiのアカウントが要求される謎の仕様がある。
パソコンからapkをインストールしたいが、SIMカード刺したりアカウントうんぬんは出来ないとして、adb install以外の方法を考える必要がある。
apkファイルを転送→APK ファイルを処理できるサードパーティーアプリのActivityを開く→そのサードパーティーアプリ経由でapkをインストールする。
この方法のデメリットは、apkをインストールしてくれるサードパーティーアプリを探す手間があるのと、画面でいちいちインストールボタンを押さないといけない点だが、
必要な手順の半分くらいはショートカットできた、
apkファイルをActivityで受け入れてインストールをしてくれるアプリを探す必要があります。SAIなら<intent-filter>で受け入れてインストールしてくれてそうです。てかこれくらいなら自分で作ってもよいかもしれませんね?
SAIAndroid開発の場合は、build.gradle.ktsにこのGradle タスクを書けばよい。build.gradleをまだ使ってる?そんな、、、
このタスクをAndroid Studioで実行すれば、二回目以降は再生ボタンを押したときの挙動がこのタスクの実行になる。
ただ、:appモジュール(Android Studio初期状態のやつ)の、プロダクト フレーバーも使ってない状態のコードなので、assembleDebugの部分も、apkのパスも修正が必要かもしれない。
cmdもWindowsなのでmacOSとかだと使えないな
tasks.register<Exec>("xiaomiAdbInstallAlternative") {
// app モジュール想定
// デバッグ APK を作る
dependsOn("app:assembleDebug")
// APK を探す
val apkFile = project.project("app").projectDir
.resolve("build")
.resolve("outputs")
.resolve("apk")
.resolve("debug")
.resolve("app-debug.apk")
// ADB を探すために local.properties を見る
val properties = project.rootProject.file("local.properties").inputStream().use { inputStream ->
java.util.Properties().apply {
load(inputStream)
}
}
val sdkFolder = File(properties["sdk.dir"].toString())
val adbBin = sdkFolder.resolve("platform-tools").resolve("adb.exe")
// apk を転送して、APK を受け入れる Activity を開く
commandLine("cmd", "/c", "${adbBin.path} push ${apkFile.path} /sdcard/app-debug.apk && ${adbBin.path} shell am start -d file:///storage/emulated/0/app-debug.apk -a android.intent.action.VIEW -t application/vnd.android.package-archive")
// この先は Android 端末でインストールする...
}実行すると、こんな感じにSAIがインストールするか聞いてくれるので、インストールボタンを押す。この工程はたぶんスキップできないため、adb installをちゃんと使えるようにする方が良いかと。
これの良くないところはAPK転送とActivity起動のコマンドを無理やりつないでcommandLine()に渡してますが、
たぶん正解はtasks.register()をAPK 転送とActivity 起動で分けるのだと思います。
もしマルチプラットフォームでVSCodeを使っている場合などは、こんな感じのシェルスクリプトを書けばよいはず。
以下のシェルスクリプトはWindowsのGit Bashで動くのをみました。bat ?はWindowsユーザーなのに書いたことなくshです!
LinuxとかmacOSの場合、たぶんパス区切り~とかの部分をすっ飛ばせるはず。sed 's/\\\\/\//g' | sed 's/C\\:/\/c/g'の部分。そもそもここやらないとだめなんですかね(?)
マルチプラットフォーム、ろくに触ったことないから何のコマンドでデバッグ APK作れるのか知らない。gradlew直接呼ぶの違う気がしてきた。APKのパスとかも皆さんの環境に合わせてください。
# デバッグ APK をつくるコマンド
./gradlew assembleDebug
# local.properties から ADB のパスを探す
GRADLE_MODULE_NAME='app'
# sdk.dir= を消し、パス区切りを修正し、C\: を /c/ にする
SDK_PATH=$(cat local.properties | sed -n '$p' | sed 's/sdk.dir=//' | sed 's/\\\\/\//g' | sed 's/C\\:/\/c/g')
APK_PATH="${GRADLE_MODULE_NAME}/build/outputs/apk/debug/app-debug.apk"
ADB_PATH="${SDK_PATH}/platform-tools/adb.exe"
# 転送する
# 先頭の // の出所はここ → https://stackoverflow.com/questions/16344985
"${ADB_PATH}" push "${APK_PATH}" "//sdcard\app-debug.apk"
# APK を処理できる Activity を立ち上げる
${ADB_PATH} shell am start -d file:///storage/emulated/0/app-debug.apk -a android.intent.action.VIEW -t application/vnd.android.package-archiveadb installできないし、apkを転送してファイルマネージャーで開くのもつらい。
かといってadb installを使えるようにするのもめんどい。adb installを無理やり有効にする案があるとかないとからしいんですが、一旦ここから離れた案を探したほうがよさそう。
adb installだけを弾いてるっぽいので、まあよく考えたらできる。
ほなAPKをインストールしてくれる(APKインストールのダイアログを開いてくれるアプリ)を探せばよさそう。
これがGradleとかシェルスクリプトでやってることです!
デバッグ APK 作成→Android 端末の適当なところに転送→APK インストール ダイアログを開いてくれるアプリを立ち上げる
で最後に、人間がインストールボタンを押す
adbのPATHは通ってるはず(もしくは通してるはず)なので、Android SDKの中のplatform-tools/adb.exeを探すことなくadbコマンドを叩けるはずです。
私が書いたコードは無駄にlocal.propertiesからadbを探しているのでたぶん無駄です。