Android AI示例宝库:一站式探索Google AI模型的无限可能

Android AI Sample Catalog

Android AI Sample Catalog 是一个独立的应用程序,旨在为开发者提供一系列自包含的示例,集中展示Google AI模型解锁的各种生成式AI能力。这些示例涵盖了从基础文本对话、多模态理解到实时语音交互、视频内容分析以及图像生成与编辑等多个前沿领域,是学习和实践Android AI集成的宝贵资源。

重要提示: 这些示例主要用于在特定场景下展示AI能力,代码可能经过简化。它们属于演示性质,不建议直接用于生产环境。最佳实践请参考官方文档和Now In Android项目。

需要Firebase支持: 依赖于Google云端模型(如Gemini Pro, Gemini Flash)的示例,需要预先设置Firebase项目并将应用连接到Firebase(详细指南)。

🚧 项目状态: 我们正在持续向应用中添加更多示例。

功能特性

  • 全方位AI能力展示: 集成Gemini、Imagen等多种Google AI模型,覆盖文本、图像、语音、视频四大模态。
  • 开箱即用的示例应用: 每个示例都是独立、完整的Android模块,拥有清晰的UI界面,可直接运行体验。
  • 云端与本地AI兼顾:
    • 云端AI: 使用Firebase AI SDK调用Gemini系列模型,实现强大的聊天、多模态分析、视频总结、图像生成等功能。
    • 本地AI: 利用ML Kit GenAI API调用设备端Gemini Nano模型,实现图像描述、文本摘要、写作辅助等隐私友好、低延迟的任务。
  • 现代化的架构与实现: 项目遵循Android推荐的架构模式,使用Kotlin、Coroutines、Flow等现代开发技术,代码结构清晰。
  • 实时交互体验:
    • Gemini Live API: 演示如何通过实时语音与AI模型交互,操控一个待办事项应用,实现完全免提的对话式体验。
    • 流式响应: 多个示例展示了如何处理AI模型的流式响应,提供更流畅的用户反馈。

安装指南

前置条件

  1. 开发环境: 最新版本的Android Studio
  2. Firebase项目(针对云端AI示例): 需要创建一个Firebase项目并获取配置文件。

运行步骤

  1. 克隆仓库:

    bash 复制代码
    git clone https://github.com/android/ai-samples.git
    cd ai-samples
  2. 使用Android Studio打开: 打开整个项目(ai-samples根目录)。

  3. 配置Firebase(可选但推荐):

    • 访问Firebase控制台创建新项目。
    • 在项目中添加一个Android应用,包名与app模块的包名一致(例如 com.android.ai.samples)。
    • 下载配置文件 google-services.json,并将其放入 app/ 目录下。
    • 详细步骤可参考Firebase Android设置指南
  4. 同步与运行: 同步Gradle后,选择app配置并运行。应用将启动并展示示例列表,您可以自由导航和体验所有可用示例。

使用说明

应用运行后,主界面会列出所有集成的AI示例。点击任一示例即可进入对应的功能界面进行交互。

以下是几个核心示例的典型使用场景:

  1. Gemini 聊天机器人: 与Gemini Flash模型进行纯文本对话。
  2. Gemini 多模态聊天: 上传一张图片并附加文字问题,让模型根据图文内容回答。
  3. Imagen 图像生成: 输入一段文字描述(如"一只在太空中的柯基犬"),生成对应的图像。
  4. 设备端图像描述: 选择一张本地照片,让设备端Gemini Nano模型生成简短描述,无需网络连接。
  5. Gemini Live 语音待办事项: 通过语音指令添加、删除、切换任务状态,体验实时语音AI交互。

核心代码

以下是从项目中选取的部分核心代码片段,展示了如何调用不同的AI API。

1. Gemini 多模态文本与图像生成

此代码来自GeminiImageChatViewModel.kt,展示了如何初始化一个支持生成文本和图像的Gemini模型,并处理用户的图文输入。

kotlin 复制代码
// 初始化支持图文生成的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)
        // 处理响应...
    }
}

2. Gemini Live 实时语音与函数调用

此代码来自TodoScreenViewModel.kt,展示了如何初始化一个支持实时音频输入和函数调用(连接应用业务逻辑)的Gemini Live模型。

kotlin 复制代码
// 定义可供模型调用的函数(以添加待办事项为例)
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
}

3. 设备端图像描述 (Gemini Nano)

此代码来自GenAIImageDescriptionViewModel.kt,展示了如何使用ML Kit API调用设备端Gemini Nano模型进行图像描述,完全在本地运行。

kotlin 复制代码
// 初始化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状态为"成功"等...
}

4. Imagen 图像编辑(局部重绘)

此代码来自ImagenEditingDataSource.kt,展示了如何使用Imagen编辑模型,根据用户绘制的遮罩和文本提示对图像进行局部修改(Inpainting)。

kotlin 复制代码
/**
 * 使用遮罩对图像进行局部重绘。
 * @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()
}
相关推荐
ekprada4 小时前
Day 41 卷积神经网络(CNN)基础与实战
人工智能·python·机器学习
祝威廉4 小时前
摘下数据分析的皇冠:机器学习,InfiniSynapse 金融评分卡案例
人工智能·机器学习·金融·数据挖掘·数据分析
产品何同学4 小时前
复刻DeepSeek与GPT!AI智能对话Web高保真原型设计全解析
人工智能·gpt·墨刀·高保真原型·deepseek·ai智能写作·ai智能对话
杭州泽沃电子科技有限公司4 小时前
变流器与变压器:风电并网智能监测的“守护神”与“稳定锚”
人工智能·智能监测·发电
中國龍在廣州4 小时前
“太空数据中心”成AI必争之地?
人工智能·深度学习·算法·机器学习·机器人
多则惑少则明4 小时前
AI大模型实用(三)Java快速实现智能体整理(Springboot+LangChain4j)
人工智能·spring ai·langchain4j
恒星科通4 小时前
隧道高清晰广播系统,破解隧道声学难题 为司乘安全加码
人工智能·安全
qq_12498707534 小时前
基于Spring Boot的社区医院管理系统的设计与实现(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·毕业设计
北邮刘老师4 小时前
语音、文本、图形,哪个才是最适合智能体的UI形式?
人工智能·智能体