What You'll Learn
Gemini AI + Android(Firebase AI SDK、Text Generation、Image Recognition、Chat UI、ストリーミング)を解説します。
Setup
dependencies {
implementation("com.google.firebase:firebase-ai:16.0.0")
implementation(platform("com.google.firebase:firebase-bom:33.7.0"))
}
Text Generation
class GeminiRepository @Inject constructor() {
private val model = Firebase.ai(backend = GenerativeBackend.googleAI())
.generativeModel("gemini-2.0-flash")
suspend fun generateText(prompt: String): String {
val response = model.generateContent(prompt)
return response.text ?: ""
}
fun generateTextStream(prompt: String): Flow<String> = flow {
model.generateContentStream(prompt).collect { chunk ->
chunk.text?.let { emit(it) }
}
}
}
Chat UI
@Composable
fun ChatScreen(viewModel: ChatViewModel = hiltViewModel()) {
val messages by viewModel.messages.collectAsStateWithLifecycle()
var input by remember { mutableStateOf("") }
val isGenerating by viewModel.isGenerating.collectAsStateWithLifecycle()
Column(Modifier.fillMaxSize()) {
LazyColumn(Modifier.weight(1f).padding(horizontal = 16.dp), reverseLayout = true) {
items(messages.reversed()) { message ->
ChatBubble(message)
}
}
Row(Modifier.fillMaxWidth().padding(8.dp), verticalAlignment = Alignment.CenterVertically) {
OutlinedTextField(
value = input,
onValueChange = { input = it },
modifier = Modifier.weight(1f),
placeholder = { Text("メッセージを入力") },
enabled = !isGenerating
)
IconButton(
onClick = {
viewModel.sendMessage(input)
input = ""
},
enabled = input.isNotBlank() && !isGenerating
) {
if (isGenerating) CircularProgressIndicator(Modifier.size(24.dp))
else Icon(Icons.AutoMirrored.Filled.Send, "送信")
}
}
}
}
@Composable
fun ChatBubble(message: ChatMessage) {
val isUser = message.role == "user"
Row(
Modifier.fillMaxWidth().padding(vertical = 4.dp),
horizontalArrangement = if (isUser) Arrangement.End else Arrangement.Start
) {
Card(
colors = CardDefaults.cardColors(
containerColor = if (isUser) MaterialTheme.colorScheme.primaryContainer
else MaterialTheme.colorScheme.surfaceVariant
)
) {
Text(message.text, Modifier.padding(12.dp), style = MaterialTheme.typography.bodyMedium)
}
}
}
Image Recognition
suspend fun analyzeImage(bitmap: Bitmap, prompt: String): String {
val content = content {
image(bitmap)
text(prompt)
}
val response = model.generateContent(content)
return response.text ?: ""
}
// Compose UI
@Composable
fun ImageAnalyzer(viewModel: GeminiViewModel = hiltViewModel()) {
var selectedImage by remember { mutableStateOf<Bitmap?>(null) }
val result by viewModel.analysisResult.collectAsStateWithLifecycle()
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.GetContent()) { uri ->
uri?.let { /* load bitmap */ }
}
Column(Modifier.padding(16.dp)) {
Button(onClick = { launcher.launch("image/*") }) { Text("画像を選択") }
selectedImage?.let { bitmap ->
Image(bitmap.asImageBitmap(), null, Modifier.fillMaxWidth().height(200.dp))
Button(onClick = { viewModel.analyzeImage(bitmap, "この画像を説明してください") }) {
Text("AI分析")
}
}
result?.let { Text(it, Modifier.padding(top = 8.dp)) }
}
}
Summary
| 機能 | API |
|---|---|
| Text Generation | generateContent() |
| ストリーミング | generateContentStream() |
| Image Recognition | content { image() } |
| チャット | startChat() |
- Firebase AI SDKでGeminiモデルを簡単利用
- ストリーミングでリアルタイム応答表示
- マルチモーダルSupport(テキスト+画像)
- Low latency with on-device inference
8種類のAndroidAppTemplates(AIIntegration Support)を公開しています。
Template List → Gumroad
Related Articles:
Ready-Made Android App Templates
8 production-ready Android app templates with Jetpack Compose, MVVM, Hilt, and Material 3.
Browse templates → Gumroad
Top comments (0)