2026年5月12日、Antigravityを開いて作業していたとき、Androidチームからメールが届きました。件名は「The Android Show: Developer's Cut」。最初は流そうと思いましたが、本文の冒頭で手が止まりました。
「Android is transitioning from an operating system to an intelligence system.」
OSからIntelligence Systemへ。この一文が何を意味するのか、しばらく考え込みました。2014年からAndroidアプリを作り続けてきた私にとって、このプラットフォームはいつも「ユーザーが直接操作するもの」という前提の上に成立していました。その前提が変わると言っています。
累計5,000万ダウンロードを超えた壁紙アプリ群を抱える身として、この変化を「あとで対応すればいい」と流せる気がしませんでした。今日は、実際にAppFunctions APIを触ってみた翌日の記録をまとめます。
AndroidがOSからIntelligence Systemに変わった意味
発表の中核にあるのは「Gemini Intelligence」と呼ばれる新しいAI統合レイヤーです。Androidデバイスがユーザーのニーズを先読みし、アプリが適切なタイミングでその体験を届けられるようにする——という設計思想です。
開発者向けに、2つの統合パスが用意されています。
パス1: Task Automation(コード変更なし) Geminiが既存のアプリ画面を直接ナビゲートして、ユーザーの代わりにタスクをこなします。フードデリバリーへの注文やライドシェアの予約などが例として挙げられており、アプリ側でのコード変更は不要です。
パス2: AppFunctions API(開発者が制御) 開発者がアプリの機能を「ツール」として明示的に定義し、自然言語の説明と共にOSに公開します。Geminiはそのツールを発見し、適切なタイミングで呼び出します。
興味深いのは、Googleが公式ブログで「in an MCP-like fashion(MCPに近い形で)」という言葉を使ったことです。AIコーディングで馴染み深いModel Context Protocolのコンセプトを、Androidプラットフォームに適用したと理解できます。
2つの統合パスと個人開発者の現実
「どちらを選ぶか」ではなく「どちらが自分のアプリの価値観に合うか」という問いで考えた方がしっくりきます。
Task Automation が向いているケース:
- アプリが標準的なNavigation Componentで実装されており、画面遷移がシンプル
- ユーザーが繰り返す操作パターンが明確(例: 毎朝特定のカテゴリから壁紙を選ぶ)
- 開発リソースが限られており、まず様子を見たい
AppFunctions APIが向いているケース:
- アプリが複数のビジネスロジックを持ち、画面遷移だけでは意図が伝わりにくい
- 「気分で壁紙を選ぶ」のように、抽象的な入力からアプリ内操作につなぎたい
- AIエコシステムへの統合に長期的な投資価値を感じている
壁紙アプリの場合、「今日の気分に合わせた壁紙をGeminiに選んでもらいたい」という用途には、Task Automationでは限界があります。「気分」という抽象的な入力から「壁紙カテゴリの絞り込み」「お気に入りフォルダへの保存」というビジネスロジックを呼び出す必要があるからです。この場合、AppFunctions APIの方が正しい選択です。
AppFunctions APIの仕組み — 「名前付きツール」の設計思想
AppFunctions APIの本質は、アプリの機能を「名前と説明を持つツール」として定義することです。
MCPのツール定義と非常に近い感覚があります。関数名・引数・返り値・自然言語による説明を組み合わせて、AIが「何をできるか」を理解できる形で公開します。
発表ではKakaoTalkがEarly Access Programの参加企業として挙げられており、「send messages」「initiate voice calls」という2つのAppFunctionを公開しているとのことです。すでに25のアプリのユースケースがデバイス上でローカル実行されているという数字も示されています。
AppFunction の構造:
- id: アプリのパッケージ名を含む一意の識別子
- description: Geminiが理解するための自然言語の説明
- parameters: 型と意味の定義(具体的な例を含める)
- 実装: Kotlinの suspend fun
このうち description と parameters の質が、Geminiがこの関数を正しく使えるかどうかを直接左右します。
Kotlinで実装するAppFunctions最小構成
EAP(Early Access Program)のα版APIと、AndroidのApp Actionsで培われてきたアノテーションベースのパターンをもとに、壁紙アプリ向けの最小構成を組みました。
まず build.gradle.kts に依存関係を追加します。
// build.gradle.kts(app モジュール)
dependencies {
implementation("androidx.appfunctions:appfunctions:1.0.0-alpha01")
implementation("com.google.firebase:firebase-ai:25.0.0")
kapt("androidx.appfunctions:appfunctions-compiler:1.0.0-alpha01")
}次に、AppFunctionを定義します。壁紙アプリの場合、「気分に合わせて壁紙を選んで適用する」機能を公開します。
// WallpaperAppFunctions.kt
import androidx.appfunctions.AppFunction
import androidx.appfunctions.AppFunctionContext
import androidx.appfunctions.AppFunctionResult
@AppFunction(
id = "com.example.wallpaper.SET_WALLPAPER_BY_MOOD",
description = "Set device wallpaper based on user's current mood or preference. " +
"Supports moods like 'calm', 'energetic', 'nature', 'minimal', and 'seasonal'. " +
"Use this when the user wants to change their wallpaper based on how they feel.",
parameters = [
AppFunction.Parameter(
name = "mood",
description = "The mood or theme for wallpaper selection. " +
"Examples: calm, nature, minimal, energetic, space, warm, seasonal",
type = String::class
),
AppFunction.Parameter(
name = "setImmediately",
description = "Whether to apply the wallpaper right away (true) " +
"or show a preview screen first (false). Default is false.",
type = Boolean::class,
required = false
)
]
)
class SetWallpaperByMoodFunction(
private val wallpaperRepository: WallpaperRepository,
private val wallpaperManager: WallpaperManager
) : AppFunction {
override suspend fun execute(
context: AppFunctionContext,
parameters: Map<String, Any?>
): AppFunctionResult {
val mood = parameters["mood"] as? String
?: return AppFunctionResult.error("mood parameter is required")
val setImmediately = parameters["setImmediately"] as? Boolean ?: false
// 気分に合う壁紙をリポジトリから取得
val wallpaper = wallpaperRepository.findByMood(mood)
?: return AppFunctionResult.error("「${mood}」に合う壁紙が見つかりませんでした")
return if (setImmediately) {
// 即時適用
wallpaperManager.setWallpaper(wallpaper.bitmap)
AppFunctionResult.success(
message = "壁紙を「${wallpaper.title}」(${mood}テーマ)に変更しました",
data = mapOf("wallpaperId" to wallpaper.id, "title" to wallpaper.title)
)
} else {
// プレビュー画面への遷移
AppFunctionResult.deepLink(
uri = "wallpaperapp://preview/${wallpaper.id}",
message = "「${wallpaper.title}」のプレビューを開きます"
)
}
}
}このコードで最もこだわったのは description と parameters の書き方です。「Supports moods like 'calm', 'energetic'...」という具体的な列挙が、GeminiがこのFunctionをいつ呼ぶかの判断精度を上げます。MCPのツール説明を書くときと同じ感覚です。
AppFunctionをManifestに登録します。
<!-- AndroidManifest.xml -->
<application>
<meta-data
android:name="androidx.appfunctions.APP_FUNCTIONS"
android:resource="@xml/app_functions" />
</application><!-- res/xml/app_functions.xml -->
<app-functions>
<app-function
android:id="com.example.wallpaper.SET_WALLPAPER_BY_MOOD"
android:enabled="true"
android:allowedCallers="com.google.android.apps.assistant" />
</app-functions>allowedCallers に com.google.android.apps.assistant を指定することで、Geminiアシスタントからのみこの関数が呼び出せるようになります。セキュリティの観点から、EAP期間中はこの設定が推奨されています。
Firebase AI Logic × Gemini 2.5 Proでアプリ内体験を拡張する
AppFunctionsでGeminiにアプリを「操作させる」のとは別に、アプリ内でGeminiを使って「ユーザー体験を向上させる」アプローチもあります。Firebase AI Logicを使ったアプリ内AI機能の実装です。
壁紙アプリの場合、「この壁紙に合う時間帯は?」「今日の天気に合ったカテゴリを教えて」のような自然言語インタラクションを追加できます。
// AIWallpaperAdvisor.kt
import com.google.firebase.ai.FirebaseAI
import com.google.firebase.ai.GenerativeModel
import com.google.firebase.ai.type.GenerationConfig
import com.google.firebase.ai.type.content
class AIWallpaperAdvisor {
private val model: GenerativeModel by lazy {
FirebaseAI.getInstance().generativeModel(
modelName = "gemini-2.5-pro",
generationConfig = GenerationConfig.builder()
.maxOutputTokens(512)
.temperature(0.4f) // 壁紙提案は低めの温度で安定した回答を得る
.build(),
systemInstruction = content {
text(
"""
あなたは壁紙アプリのAIアドバイザーです。
ユーザーの気分・時間帯・天気をもとに、
おすすめの壁紙カテゴリと設定理由を提案してください。
回答は必ず日本語で、2文以内に簡潔にまとめてください。
カテゴリ候補: nature, minimal, space, warm, cool, abstract, city, art, seasonal
""".trimIndent()
)
}
)
}
// 気分・時間帯からカテゴリ推薦
suspend fun recommendCategory(
mood: String,
timeOfDay: String,
weather: String = "不明"
): RecommendationResult {
return try {
val prompt = buildString {
append("現在の気分: $mood\n")
append("時間帯: $timeOfDay\n")
append("天気: $weather\n")
append("この状況に最もふさわしい壁紙カテゴリを1つ選び、理由を1文で説明してください。")
append("形式: カテゴリ名|理由")
}
val response = model.generateContent(content { text(prompt) })
val text = response.text?.trim() ?: return RecommendationResult.Fallback
val parts = text.split("|")
if (parts.size >= 2) {
RecommendationResult.Success(
category = parts[0].trim(),
reason = parts[1].trim()
)
} else {
RecommendationResult.Fallback
}
} catch (e: Exception) {
RecommendationResult.Fallback
}
}
}
sealed class RecommendationResult {
data class Success(val category: String, val reason: String) : RecommendationResult()
object Fallback : RecommendationResult()
}ここで temperature = 0.4f に設定している理由があります。壁紙の提案は「創造的な発散」よりも「文脈に合った安定した提案」の方が価値があります。毎回違うカテゴリが返ってくると、ユーザーが「いつもと違う」と感じて混乱します。アプリの種類によって適切な温度は異なりますが、ユーティリティ系は低めが安定します。
また、systemInstruction で「2文以内に簡潔に」と指定しているのは、UIの表示スペースに収まるためです。AIの回答がUIから溢れてトランケートされると、回答の質が高くても体験が損なわれます。
Antigravityで加速するAndroid Intelligence System対応
AppFunctions APIはα版なので、まだドキュメントが薄い部分があります。こういうときにAntigravityが効きます。AGENTS.mdに以下のコンテキストを追加することで、Antigravityがプロジェクトの意図を正確に把握した上でコードを書いてくれます。
# AGENTS.md(Android Intelligence System対応プロジェクト用)
## プロジェクトの目的
壁紙アプリにGemini Intelligence対応を追加する。
AppFunctions APIを用い、ユーザーが自然言語で壁紙を操作できるようにする。
## 技術スタック
- Android 17 / Kotlin 2.x / Jetpack Compose
- AppFunctions API alpha(androidx.appfunctions:1.0.0-alpha01)
- Firebase AI Logic SDK(Gemini 2.5 Pro)
- EAP段階のAPIのため、公式ドキュメントはgoo.gle/eap-af参照
## AppFunctions 設計原則
- description と parameter説明は英語で記述(Geminiの理解精度が高い)
- parameter の description に必ず具体的な値の例を含める
- エラーメッセージと success.message は日本語(エンドユーザー向け)
- setImmediately のデフォルト値は false にする(壁紙の誤適用防止)
- deepLinkはプレビュー遷移にのみ使用し、確認不要なアクションは直接実行する
## Firebase AI Logic の原則
- temperature は 0.3〜0.5 の範囲で設定する(ユーティリティアプリのため)
- systemInstruction で必ず返答の文字数・言語・フォーマットを指定する
- レスポンステキストはUIに表示する前にtrim()とサニタイズを行う
## 既知の制約(2026-05-14時点)
- AppFunctions はAndroid 17以上でのみ動作確認済み
- allowedCallers は現在 com.google.android.apps.assistant のみ
- EAP登録URL: goo.gle/eap-afこのAGENTS.mdを設置した状態でAntigravityに「AppFunctionを追加して」と依頼すると、descriptionを英語で書き、setImmediatelyのデフォルトをfalseにし、エラーメッセージを日本語にする——という設計方針を守ったコードを生成してくれます。
α版APIへの対応で特に効果的なのが、AGENTS.mdの「既知の制約」セクションです。Antigravityは最新のα APIを学習していないケースもあるため、EAPドキュメントから引用したコード断片をAGENTS.mdに貼り付けておくと、正しいAPIの使い方でコードが生成されます。
実装後の動作確認には、AntigravityのAgentKit機能でテストシナリオを自動実行する方法が有効です。
// AppFunctionsテスト(Antigravity AgentKit連携想定)
@Test
fun `気分がcalmのとき適切な壁紙が選ばれること`() = runTest {
// Given
val mockRepo = mockk<WallpaperRepository> {
coEvery { findByMood("calm") } returns WallpaperFixtures.calmWallpaper
}
val function = SetWallpaperByMoodFunction(mockRepo, mockk(relaxed = true))
// When
val result = function.execute(
context = AppFunctionContext.forTest(),
parameters = mapOf("mood" to "calm", "setImmediately" to true)
)
// Then
assertThat(result).isInstanceOf(AppFunctionResult.Success::class.java)
assertThat((result as AppFunctionResult.Success).message).contains("calm")
}5,000万DLのアプリ群を持つ個人開発者の設計判断
10年以上アプリを作り続けてきた立場で、新しいAPIが出たときに「全部のアプリに即対応」が現実的でないことは分かっています。今回のAndroid Intelligence System対応も、まず優先度を整理しました。
優先度高: メインの壁紙アプリ 毎日使われるアプリなのでGemini Intelligenceとの連携価値が高いです。「朝に自動で壁紙を変える」用途はTask Automationで対応可能で、「気分や天気に合わせた選定」にはAppFunctions APIが有効です。まずTask Automationで様子を見て、3ヶ月後にAppFunctionsを追加する計画を立てています。
優先度中: 癒し系サウンドアプリ 「仕事モードの音楽を流して」のような自然言語操作は価値があります。壁紙との連携(Visual + Sound)でシナジーが生まれる可能性もあります。AppFunctions EAPに登録して情報収集しています。
優先度低: 引き寄せ系アプリ このカテゴリのアプリは、ユーザーの自発的な行動が価値の核心にあります。AI自動化との相性を慎重に見極める必要があります。今は静観の判断です。
ここで大切だと感じるのは「なぜ対応しないかを言語化すること」です。新技術だからといって全ての機能にAIを組み込む必要はありません。
祖父たちは宮大工として一つ一つの部材に向き合い、「どこを機械に任せ、どこを手で仕上げるか」を職人の目で判断していました。その感覚が私にも受け継がれているのかもしれません——どこをAIに委ね、どこに人間の手触りを残すかを、アプリごとに丁寧に判断したいと思っています。
今から取れる3つのアクション
Google I/O 2026は来週(5月19〜20日)です。そこでさらに詳細な開発者向け情報が出ると予想されます。今すぐ始められることを整理します。
1. Task Automationの動作確認(今週) コード変更不要です。Google Pixel または Samsung Galaxyの最新機種を持っている方は、Gemini Intelligence(Android 17プレビュー)でアプリを操作してみてください。アプリがどの程度自動操作されるかを先に体感することで、AppFunctions APIで何を補完すべきかが見えてきます。
2. AppFunctions EAPへの登録(今週)
goo.gle/eap-af からEarly Access Programへの参加申請が可能です。EAP登録後に詳細なAPIドキュメントと開発者サポートへのアクセスが得られます。承認まで数日かかる場合があります。
3. AntigravityのAGENTS.mdを整備する(来週) Google I/O 2026の発表後、具体的なAPIリファレンスが公開されたタイミングで、AGENTS.mdにその内容を追記します。α版APIはドキュメントが急速に更新されるため、AGENTS.mdを「生きたコンテキスト」として継続的に更新していく運用が効果的です。
Android Intelligence Systemへの対応は、一度で完成させるものではなく、プラットフォームの成熟とともに育てていくものだと思います。来週のGoogle I/O 2026でさらに何が発表されるか、一緒に見届けましょう。