
Android AI Sample Catalog 是一个独立的应用程序,旨在为开发者提供一系列自包含的示例,集中展示Google AI模型解锁的各种生成式AI能力。这些示例涵盖了从基础文本对话、多模态理解到实时语音交互、视频内容分析以及图像生成与编辑等多个前沿领域,是学习和实践Android AI集成的宝贵资源。
重要提示: 这些示例主要用于在特定场景下展示AI能力,代码可能经过简化。它们属于演示性质,不建议直接用于生产环境。最佳实践请参考官方文档和Now In Android项目。 需要Firebase支持: 依赖于Google云端模型(如Gemini Pro, Gemini Flash)的示例,需要预先设置Firebase项目并将应用连接到Firebase(详细指南)。 🚧 项目状态: 我们正在持续向应用中添加更多示例。
ai-samples根目录)。app模块的包名一致(例如 com.android.ai.samples)。google-services.json,并将其放入 app/ 目录下。app配置并运行。应用将启动并展示示例列表,您可以自由导航和体验所有可用示例。应用运行后,主界面会列出所有集成的AI示例。点击任一示例即可进入对应的功能界面进行交互。
以下是几个核心示例的典型使用场景:
以下是从项目中选取的部分核心代码片段,展示了如何调用不同的AI API。
此代码来自GeminiImageChatViewModel.kt,展示了如何初始化一个支持生成文本和图像的Gemini模型,并处理用户的图文输入。
// 初始化支持图文生成的Gemini模型
val generativeModel = Firebase.ai(backend = GenerativeBackend.googleAI()).generativeModel(
"gemini-3-pro-image-preview",
generationConfig = generationConfig {
temperature = 0.9f
topK = 32
topP = 1f
maxOutputTokens = 4096
// 关键:指定模型可以返回文本和图像两种模态
responseModalities = listOf(ResponseModality.TEXT, ResponseModality.IMAGE)
},
safetySettings = listOf(
SafetySetting(HarmCategory.HARASSMENT, HarmBlockThreshold.MEDIUM_AND_ABOVE),
SafetySetting(HarmCategory.HATE_SPEECH, HarmBlockThreshold.MEDIUM_AND_ABOVE),
SafetySetting(HarmCategory.SEXUALLY_EXPLICIT, HarmBlockThreshold.MEDIUM_AND_ABOVE),
SafetySetting(HarmCategory.DANGEROUS_CONTENT, HarmBlockThreshold.MEDIUM_AND_ABOVE),
),
systemInstruction = content {
text("""You are a friendly assistant. Keep your responses short.""")
},
)
// 构建包含文本和图像的多模态内容并发送请求
fun sendMessageWithImage(message: String, bitmap: Bitmap?) {
viewModelScope.launch {
val content = content {
text(message)
if (bitmap != null) {
image(bitmap) // 将Bitmap添加为图像输入
}
}
val response = chat.sendMessage(content)
// 处理响应...
}
}此代码来自TodoScreenViewModel.kt,展示了如何初始化一个支持实时音频输入和函数调用(连接应用业务逻辑)的Gemini Live模型。
// 定义可供模型调用的函数(以添加待办事项为例)
private val addTodo = functionDeclaration("addTodo") {
description = "Adds a new todo item to the list"
// 定义函数的参数模式
parameters = schema {
property("title", Schema.STRING) {
description = "The title of the todo"
}
}
// 当模型调用此函数时,返回响应的格式
response = schema {
property("result", Schema.STRING) {
description = "The result of the operation"
}
}
}
// 初始化Gemini Live模型,并传入工具(函数)声明
val generativeModel = Firebase.ai(backend = GenerativeBackend.vertexAI()).liveModel(
"gemini-2.5-flash-native-audio-preview-12-2025",
generationConfig = liveGenerationConfig,
systemInstruction = systemInstruction,
tools = listOf(
// 将多个函数声明作为工具提供给模型
Tool.functionDeclarations(
listOf(getTodoList, addTodo, removeTodo, toggleTodoStatus),
),
),
)
// 连接到实时会话
try {
session = generativeModel.connect() // 建立连接,准备接收和发送音频流
} catch (e: Exception) {
Log.e(TAG, "Error connecting to the model", e)
liveSessionState.value = LiveSessionState.Error
}此代码来自GenAIImageDescriptionViewModel.kt,展示了如何使用ML Kit API调用设备端Gemini Nano模型进行图像描述,完全在本地运行。
// 初始化ML Kit图像描述客户端
private var imageDescriber: ImageDescriber = ImageDescription.getClient(
ImageDescriberOptions.builder(context).build(),
)
/**
* 生成图像描述的核心方法。
* @param imageUri 要描述图像的Uri
*/
private suspend fun generateImageDescription(imageUri: Uri) {
// 更新UI状态为“生成中”
_uiState.value = GenAIImageDescriptionUiState.Generating("")
// 从Uri加载Bitmap
val bitmap = MediaStore.Images.Media.getBitmap(context.contentResolver, imageUri)
// 构建图像描述请求
val request = ImageDescriptionRequest.builder(bitmap).build()
// 执行推理。runInference支持流式回调,可以在生成过程中实时更新UI
imageDescriber.runInference(request) { newText ->
// 每次模型生成新的文本片段时回调
_uiState.update { currentState ->
// 累加生成的文本
(currentState as? GenAIImageDescriptionUiState.Generating)
?.copy(partialOutput = currentState.partialOutput + newText)
?: currentState
}
}.await() // 等待推理完全完成
// 推理完成,更新UI状态为“成功”等...
}此代码来自ImagenEditingDataSource.kt,展示了如何使用Imagen编辑模型,根据用户绘制的遮罩和文本提示对图像进行局部修改(Inpainting)。
/**
* 使用遮罩对图像进行局部重绘。
* @param sourceImage 原始图像
* @param maskImage 遮罩图像(白色区域表示需要重绘的部分)
* @param prompt 描述重绘内容的文本提示
* @param editSteps 编辑步数,影响生成质量
* @return 编辑后的图像Bitmap
*/
@OptIn(PublicPreviewAPI::class)
suspend fun inpaintImageWithMask(sourceImage: Bitmap, maskImage: Bitmap, prompt: String, editSteps: Int = DEFAULT_EDIT_STEPS): Bitmap {
// 调用Imagen编辑模型的editImage方法
val imageResponse = editingModel.editImage(
// 参考图像:包含原始图像和遮罩
referenceImages = listOf(
ImagenRawImage(sourceImage.toImagenInlineImage()), // 转换原始图像为Imagen格式
ImagenRawMask(maskImage.toImagenInlineImage()), // 转换遮罩为Imagen格式
),
prompt = prompt, // 重绘提示
config = ImagenEditingConfig(
editMode = ImagenEditMode.INPAINT_INSERTION, // 指定编辑模式为“局部插入重绘”
editSteps = editSteps,
),
)
// 返回生成的第一个图像
return imageResponse.images.first().asBitmap()
}原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。