Slide 1

Slide 1 text

アプリブロック機能のつくりか たと、AI とHTML の不合理な相 性の良さについて potatotips #95 iOS/Android 開発Tips 共有会 2026.05.15 LINE ヤフー株式会社@新オフィス 赤坂トラストタワー

Slide 2

Slide 2 text

自己紹介 経歴 2014.4 - 2016.3 筑波大学大学院 コンピュータサイエンス専攻 2016.4 - 2019.11 ヤフー株式会社 iOS/Android エンジニア 2019.12 - 2023.4 株式会社メルペイ iOS エンジニア 2023.5 - 2024.3 株式会社YOUTRUST Flutter エンジニア 2025.4 - フリーランス Flutter エンジニアとか X @kumamo_tone Claude Code 研究所 (@claudecode_lab) のメンバーとしても活動 ヤフーの熊本としてpotatotips の取り次ぎをしているようす

Slide 3

Slide 3 text

スマホ中毒とのたたかい マジでずっとX とYouTube を見ている 広告のゲームもやってしまう(ゾンビを打ち倒す やつとか、庭を育てるやつとか) デジタルウェルビーイングアプリやアプリを消す などの原始的な方法はダメ 戦いの記録↓ デジタルデトックスチャレンジ 2025/03 版 https://kumamotone.hatenadiary.jp/entry/2025/03/25/024256 デジタルデトックスチャレンジ 2025/03 版 経過報 告 https://kumamotone.hatenadiary.jp/entry/2025/04/01/024636 ← 超おもしろい ← 超おもしろい

Slide 4

Slide 4 text

解決策 1. 表示のミニマルなランチャーを使う 2. 家のWiFi でだけ特定のアプリをブロックするルールを追加 3. 使用時間の統計を取り、上位のアプリをリストに追加 それぞれのアプリに課金や広告などがあり、アプリブロックの広告で出てきた広告のゲームで長時間 遊んでいたことがあった

Slide 5

Slide 5 text

作ったもの Focus Launcher スマホ中毒防止のためのAndroid ネイティブアプリ 1. ミニマルなホーム画面アプリで刺激を適度に減らす 2. ユーザーが指定したルールで指定したアプリを開いたときに全画面でブロック 3. ユーザーが接続した Wi-Fi のみ有効になる ような詳細なルール設定 focus-launcher.com

Slide 6

Slide 6 text

技術スタック UI Jetpack Compose + Material 3 アーキテクチャ MVVM + Repository パターン Hilt (DI) Navigation Compose データ・永続化 Room (SQLite) Kotlinx Serialization 非同期処理 Coroutines + Flow バックグラウンド処理 WorkManager AccessibilityService ( アプリ検知・ブロック) Firebase Crashlytics ( クラッシュ報告) Analytics ( 匿名利用統計) Remote Config ( 強制アップデート制御) 課金・ストア Google Play Billing ( サブスクリプション) Google Play In-App Review ログ Timber ビルド・配信 Gradle (KTS) + KSP Firebase App Distribution ( テスト配布) Gradle Play Publisher ( ストア公開自動化)

Slide 7

Slide 7 text

1. ランチャー 1. 自分をホームアプリとして認識させる AndroidManifest.xml に MAIN / HOME / DEFAULT を設定。 2. アプリを開く PackageManager.getLaunchIntentForPackage(packageName) で起動 Intent を取得し、 startActivity() 。 Android 11 以降で他アプリの起動 Intent を解決するなら、 で MAIN + LAUNCHER などを宣言する。

Slide 8

Slide 8 text

2. アプリブロック Service を登録 前面アプリの切り替わりを検知 TYPE_WINDOW_STATE_CHANGED を受け取り、 event.packageName で開いたアプリを判定。 override fun onAccessibilityEvent(event: AccessibilityEvent) { if (event.eventType != AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) return val packageName = event.packageName?.toString() ?: return if (packageName == applicationContext.packageName) return // ここでルール判定する }

Slide 9

Slide 9 text

3. 使用統計 Usage Access 権限を案内する PACKAGE_USAGE_STATS は通常の runtime permission ではない → 設定画面で許可してもらう。 UsageStatsManager で使用状況を取得する 日単位なら queryUsageStats() 、細かい前面遷移なら queryEvents() 。 startActivity(Intent(Settings.ACTION_USAGE_ACCESS_SETTINGS)) val usageStatsManager = context.getSystemService(UsageStatsManager::class.java) val stats = usageStatsManager.queryUsageStats( UsageStatsManager.INTERVAL_DAILY, startMillis, endMillis, )

Slide 10

Slide 10 text

作ってみてどうだったか 全部バイブコーディングで できてしまった…

Slide 11

Slide 11 text

バイブコーディングのコツ コツは、HTML を先に作る 1. LP とプロトタイプを自然言語で作る 2. その 2 枚の HTML を Claude Code に渡す 3. ストア操作は AI エージェント経由で fastlane を使う Focus Launcher のつくりかた① (note.com/kumamo_tone/n/nd53559ba4ed6 ) X でも似たような主張が最近バズっていた

Slide 12

Slide 12 text

ほかにもAI とHTML の活用方法 アプリのアイコンを作る CSS で形を作ると、AI くささが抜けやすく、解像度などの自由度も高い

Slide 13

Slide 13 text

ほかにもAI とHTML の活用方法 フィーチャーグラフィックの管理と多言語化 ストア用のスクリーンショットを作ってと伝えると画像生成し始めてしまうが、HTML 上でやるよう指定すると良い 同じ構造のまま、言語だけ差し替えて使える 同じ HTML を元に、日本語版と英語版のストア素材をまとめて管理できる

Slide 14

Slide 14 text

まとめ Android でマインドフルネスなランチャーを作るための技術を紹介した HTML は便利 ご清聴ありがとうございました アプリ: focus-launcher.com https://focus-launcher.com/ ブログ: note — Focus Launcher のつくりかた① https://note.com/kumamo_tone/n/nd53559ba4ed6 X: @kumamo_tone https://twitter.com/kumamo_tone