文章目录
-
- 一、开发前准备:环境+工具清单
- 二、核心原理:手机端AI智能体怎么跑起来?
- 三、实战开发:3步搭建手机AI超级助理
-
- 第一步:创建项目+导入模型
- 第二步:集成核心依赖+权限配置
- 第三步:核心代码实现(离线交互+功能模块)
-
- [1. 模型加载工具类(ModelLoader.kt)](#1. 模型加载工具类(ModelLoader.kt))
- 第三步:核心代码实现(离线交互+功能模块)
-
- [1. 模型加载工具类(ModelLoader.kt)](#1. 模型加载工具类(ModelLoader.kt))
- [2. 语音交互模块(VoiceAssistant.kt)](#2. 语音交互模块(VoiceAssistant.kt))
- [3. 主Activity整合(MainActivity.kt)](#3. 主Activity整合(MainActivity.kt))
- 第四步:UI布局(activity_main.xml)
- 四、运行测试+优化技巧
-
- [1. 测试步骤](#1. 测试步骤)
- [2. 常见问题解决](#2. 常见问题解决)
- [3. 功能扩展建议](#3. 功能扩展建议)
- 五、总结
电脑端的Agent工具一大堆,但手机端能真正落地、还支持离线运行的实战教程少得可怜。今天就带大家手把手搞定------基于AndroidGen-GLM搭建专属手机AI超级助理,全程低代码+详细步骤,新手也能跟着做,做完直接能用还能二次开发!
先给大家划重点:这款手机AI智能体支持离线语音交互、本地文档问答、日常助手功能(日程管理、翻译、计算),不用依赖网络,隐私性拉满。核心用到的AndroidGen-GLM是专为安卓端优化的轻量大模型,占用内存小、响应速度快,比直接移植PC端模型靠谱多了。话不多说,咱们直接开干!
一、开发前准备:环境+工具清单
做开发前先把"弹药"备足,我整理了一份新手友好的清单,照着装就行:
| 工具/环境 | 版本要求 | 推荐理由 | 下载地址 |
|---|---|---|---|
| Android Studio | 2023.1.1+ | 安卓开发官方工具,兼容性最好 | 官网直接下载 |
| AndroidGen-GLM模型 | v1.3轻量版 | 离线运行核心,支持中文优化 | 文末留言获取 |
| TensorFlow Lite | 2.15.0+ | 模型轻量化部署核心框架 | 集成在Android Studio中 |
| 测试设备 | Android 10.0+ | 低版本系统可能不支持离线推理 | 真机/模拟器均可 |
| 辅助工具 | Postman(可选) | 调试接口用,新手可跳过 | 官网下载 |
这里要提醒下:如果是第一次做安卓+AI开发,不用慌!Android Studio的安装和配置我就不赘述了,网上有很多教程,跟着一步步来就行。模型文件我已经帮大家整理好了轻量版,解压后直接导入项目,省得大家到处找资源。
二、核心原理:手机端AI智能体怎么跑起来?
很多朋友好奇:为啥PC端的AI模型放到手机上就卡得不行,还不能离线?其实关键就3点:
- 模型轻量化:AndroidGen-GLM通过量化、剪枝技术,把原本几十GB的模型压缩到2GB以内,手机内存完全能扛住;
- 硬件适配:专门针对手机CPU/GPU优化,不用依赖高端配置,千元机也能流畅运行;
- 离线推理:把模型权重文件直接打包进APK,运行时不用调用云端接口,响应速度毫秒级。
用个通俗的比喻:PC端大模型是"超级计算机",手机端轻量模型是"便携式笔记本",虽然算力有差距,但满足日常需求完全足够,还能随时用、不用联网------这就是手机AI智能体的核心优势!
三、实战开发:3步搭建手机AI超级助理
第一步:创建项目+导入模型
- 打开Android Studio,新建Empty Views Activity项目,包名建议设为"com.ai.mobileassistant"(方便后续调试);
- 解压下载的AndroidGen-GLM模型文件,得到"model.tflite"和"vocab.txt"两个核心文件;
- 在项目的"app/src/main/assets"目录下创建"model"文件夹,把两个核心文件复制进去(没有assets目录就手动创建)。
第二步:集成核心依赖+权限配置
首先在app/build.gradle中添加依赖(直接复制粘贴就行):
gradle
dependencies {
// 基础依赖
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
// TensorFlow Lite依赖
implementation 'org.tensorflow:tensorflow-lite:2.15.0'
implementation 'org.tensorflow:tensorflow-lite-support:0.4.4'
// 语音识别依赖(离线版)
implementation 'com.google.android.gms:play-services-speech:16.0.0'
// 文档解析依赖
implementation 'com.itextpdf:itextg:5.5.10'
}
然后在AndroidManifest.xml中添加必要权限(离线运行+功能所需):
xml
<!-- 存储权限:读取本地文档 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 麦克风权限:语音交互 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 网络权限:可选,用于在线更新模型(关闭也能离线运行) -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 硬件加速权限:提升推理速度 -->
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.audio.low_latency" />
第三步:核心代码实现(离线交互+功能模块)
1. 模型加载工具类(ModelLoader.kt)
负责加载TFLite模型,初始化推理环境:
kotlin
import android.content.Context
import org.tensorflow.lite.Interpreter
import org.tensorflow.lite.support.common.FileUtil
import java.io.FileInputStream
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel
class ModelLoader(private val context: Context) {
private lateinit var interpreter: Interpreter
private lateinit var vocab: Map<String, Int>
// 初始化模型和词表
fun init() {
// 加载模型文件
val modelBuffer = loadModelFile("model/model.tflite")
val options = Interpreter.Options().apply {
setNumThreads(4) // 开启4线程加速(根据手机配置调整)
setUseNNAPI(true) // 启用手机NNAPI硬件加速
}
interpreter = Interpreter(modelBuffer, options)
// 加载词表
vocab = loadVocab("model/vocab.txt")
}
// 加载模型文件
private fun loadModelFile(modelPath: String): MappedByteBuffer {
val fileDescriptor = context.assets.openFd(modelPath)
val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
val fileChannel = inputStream.channel
val startOffset = fileDescriptor.startOffset
val declaredLength = fileDescriptor.declaredLength
return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
}
// 加载词表
private fun loadVoc 安卓AI智能体开发实战:基于AndroidGen-GLM搭建手机端超级助理,支持离线运行
<pre markdown="1">
哈喽,各位安卓开发者和AI爱好者!最近是不是被各种AI智能体刷屏了?电脑端的Agent工具一大堆,但手机端能真正落地、还支持离线运行的实战教程少得可怜。今天就带大家手把手搞定------基于AndroidGen-GLM搭建专属手机AI超级助理,全程低代码+详细步骤,新手也能跟着做,做完直接能用还能二次开发!
先给大家划重点:这款手机AI智能体支持离线语音交互、本地文档问答、日常助手功能(日程管理、翻译、计算),不用依赖网络,隐私性拉满。核心用到的AndroidGen-GLM是专为安卓端优化的轻量大模型,占用内存小、响应速度快,比直接移植PC端模型靠谱多了。话不多说,咱们直接开干!
## 一、开发前准备:环境+工具清单
做开发前先把"弹药"备足,我整理了一份新手友好的清单,照着装就行:
| 工具/环境 | 版本要求 | 推荐理由 | 下载地址 |
|----------|----------|----------|----------|
| Android Studio | 2023.1.1+ | 安卓开发官方工具,兼容性最好 | 官网直接下载 |
| AndroidGen-GLM模型 | v1.3轻量版 | 离线运行核心,支持中文优化 | 文末留言获取 |
| TensorFlow Lite | 2.15.0+ | 模型轻量化部署核心框架 | 集成在Android Studio中 |
| 测试设备 | Android 10.0+ | 低版本系统可能不支持离线推理 | 真机/模拟器均可 |
| 辅助工具 | Postman(可选) | 调试接口用,新手可跳过 | 官网下载 |
这里要提醒下:如果是第一次做安卓+AI开发,不用慌!Android Studio的安装和配置我就不赘述了,网上有很多教程,跟着一步步来就行。模型文件我已经帮大家整理好了轻量版,解压后直接导入项目,省得大家到处找资源。
## 二、核心原理:手机端AI智能体怎么跑起来?
很多朋友好奇:为啥PC端的AI模型放到手机上就卡得不行,还不能离线?其实关键就3点:
1. 模型轻量化:AndroidGen-GLM通过量化、剪枝技术,把原本几十GB的模型压缩到2GB以内,手机内存完全能扛住;
2. 硬件适配:专门针对手机CPU/GPU优化,不用依赖高端配置,千元机也能流畅运行;
3. 离线推理:把模型权重文件直接打包进APK,运行时不用调用云端接口,响应速度毫秒级。
用个通俗的比喻:PC端大模型是"超级计算机",手机端轻量模型是"便携式笔记本",虽然算力有差距,但满足日常需求完全足够,还能随时用、不用联网------这就是手机AI智能体的核心优势!
## 三、实战开发:3步搭建手机AI超级助理
### 第一步:创建项目+导入模型
1. 打开Android Studio,新建Empty Views Activity项目,包名建议设为"com.ai.mobileassistant"(方便后续调试);
2. 解压下载的AndroidGen-GLM模型文件,得到"model.tflite"和"vocab.txt"两个核心文件;
3. 在项目的"app/src/main/assets"目录下创建"model"文件夹,把两个核心文件复制进去(没有assets目录就手动创建)。
### 第二步:集成核心依赖+权限配置
首先在app/build.gradle中添加依赖(直接复制粘贴就行):
```gradle
dependencies {
// 基础依赖
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.11.0'
// TensorFlow Lite依赖
implementation 'org.tensorflow:tensorflow-lite:2.15.0'
implementation 'org.tensorflow:tensorflow-lite-support:0.4.4'
// 语音识别依赖(离线版)
implementation 'com.google.android.gms:play-services-speech:16.0.0'
// 文档解析依赖
implementation 'com.itextpdf:itextg:5.5.10'
}
然后在AndroidManifest.xml中添加必要权限(离线运行+功能所需):
xml
<!-- 存储权限:读取本地文档 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 麦克风权限:语音交互 -->
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- 网络权限:可选,用于在线更新模型(关闭也能离线运行) -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 硬件加速权限:提升推理速度 -->
<uses-feature android:name="android.hardware.camera.autofocus" />
<uses-feature android:name="android.hardware.audio.low_latency" />
第三步:核心代码实现(离线交互+功能模块)
1. 模型加载工具类(ModelLoader.kt)
负责加载TFLite模型,初始化推理环境:
kotlin
import android.content.Context
import org.tensorflow.lite.Interpreter
import org.tensorflow.lite.support.common.FileUtil
import java.io.FileInputStream
import java.nio.MappedByteBuffer
import java.nio.channels.FileChannel
class ModelLoader(private val context: Context) {
private lateinit var interpreter: Interpreter
private lateinit var vocab: Map<String, Int>
// 初始化模型和词表
fun init() {
// 加载模型文件
val modelBuffer = loadModelFile("model/model.tflite")
val options = Interpreter.Options().apply {
setNumThreads(4) // 开启4线程加速(根据手机配置调整)
setUseNNAPI(true) // 启用手机NNAPI硬件加速
}
interpreter = Interpreter(modelBuffer, options)
// 加载词表
vocab = loadVocab("model/vocab.txt")
}
// 加载模型文件
private fun loadModelFile(modelPath: String): MappedByteBuffer {
val fileDescriptor = context.assets.openFd(modelPath)
val inputStream = FileInputStream(fileDescriptor.fileDescriptor)
val fileChannel = inputStream.channel
val startOffset = fileDescriptor.startOffset
val declaredLength = fileDescriptor.declaredLength
return fileChannel.map(FileChannel.MapMode.READ_ONLY, startOffset, declaredLength)
}
// 加载词表
private fun loadVocab(vocabPath: String): Map<String, Int> {
val vocabList = FileUtil.loadLabels(context, vocabPath)
return vocabList.withIndex().associateBy({ it.value }, { it.index })
}
// 核心推理方法:输入文本,返回AI回复
fun infer(text: String): String {
// 文本编码(将输入文本转为模型可识别的格式)
val inputIds = text.split(" ").map { vocab[it] ?: 0 }.toIntArray()
// 构建输入张量
val input = arrayOf(inputIds)
// 构建输出张量(预设输出长度为128)
val output = Array(1) { IntArray(128) }
// 执行推理
interpreter.run(input, output)
// 解码输出结果
return decodeOutput(output[0])
}
// 解码模型输出,转为中文文本
private fun decodeOutput(outputIds: IntArray): String {
val vocabReverse = vocab.entries.associateBy({ it.value }, { it.key })
return outputIds.filter { it != 0 && it != 1 && it != 2 } // 过滤特殊标记
.joinToString("") { vocabReverse[it] ?: "" }
}
// 释放资源
fun close() {
interpreter.close()
}
}
2. 语音交互模块(VoiceAssistant.kt)
实现离线语音识别,把语音转为文本输入模型:
kotlin
import android.content.Context
import android.speech.RecognitionListener
import android.speech.SpeechRecognizer
import android.speech.tts.TextToSpeech
import java.util.Locale
class VoiceAssistant(private val context: Context, private val onResult: (String) -> Unit) {
private lateinit var speechRecognizer: SpeechRecognizer
private lateinit var textToSpeech: TextToSpeech
// 初始化语音模块
fun init() {
// 初始化语音识别(离线模式)
speechRecognizer = SpeechRecognizer.createSpeechRecognizer(context)
speechRecognizer.setRecognitionListener(object : RecognitionListener {
override fun onResults(results: android.os.Bundle?) {
val texts = results?.getStringArrayList(SpeechRecognizer.RESULTS_RECOGNITION)
texts?.get(0)?.let { onResult(it) }
}
override fun onError(error: Int) {
// 错误处理:可以提示用户"请再说一遍"
}
// 其他重写方法省略,保持默认实现
override fun onReadyForSpeech(params: android.os.Bundle?) {}
override fun onBeginningOfSpeech() {}
override fun onRmsChanged(rmsdB: Float) {}
override fun onBufferReceived(buffer: ByteArray?) {}
override fun onEndOfSpeech() {}
override fun onPartialResults(partialResults: android.os.Bundle?) {}
override fun onEvent(eventType: Int, params: android.os.Bundle?) {}
})
// 初始化语音合成(TTS)
textToSpeech = TextToSpeech(context) { status ->
if (status == TextToSpeech.SUCCESS) {
textToSpeech.language = Locale.CHINA
textToSpeech.setSpeechRate(0.9f) // 语速调整
}
}
}
// 开始语音识别
fun startListening() {
val intent = android.content.Intent(android.speech.RecognizerIntent.ACTION_RECOGNIZE_SPEECH)
intent.putExtra(android.speech.RecognizerIntent.EXTRA_LANGUAGE, Locale.CHINA)
intent.putExtra(android.speech.RecognizerIntent.EXTRA_PARTIAL_RESULTS, true)
speechRecognizer.startListening(intent)
}
// 语音合成:播报AI回复
fun speak(text: String) {
if (textToSpeech.isSpeaking) {
textToSpeech.stop()
}
textToSpeech.speak(text, TextToSpeech.QUEUE_FLUSH, null, null)
}
// 释放资源
fun release() {
speechRecognizer.destroy()
textToSpeech.shutdown()
}
}
3. 主Activity整合(MainActivity.kt)
把模型加载、语音交互、UI展示整合到一起:
kotlin
import android.Manifest
import android.content.pm.PackageManager
import android.os.Bundle
import android.widget.Button
import android.widget.EditText
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
class MainActivity : AppCompatActivity() {
private lateinit var modelLoader: ModelLoader
private lateinit var voiceAssistant: VoiceAssistant
private lateinit var tvResult: TextView
private lateinit var etInput: EditText
private lateinit var btnSend: Button
private lateinit var btnVoice: Button
// 权限请求码
private val PERMISSION_REQUEST_CODE = 1001
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化UI组件
tvResult = findViewById(R.id.tv_result)
etInput = findViewById(R.id.et_input)
btnSend = findViewById(R.id.btn_send)
btnVoice = findViewById(R.id.btn_voice)
// 检查并申请权限
if (checkPermissions()) {
initAI()
} else {
requestPermissions()
}
// 文本输入发送
btnSend.setOnClickListener {
val input = etInput.text.toString().trim()
if (input.isNotEmpty()) {
val result = modelLoader.infer(input)
tvResult.text = "AI回复:$result"
voiceAssistant.speak(result) // 语音播报回复
etInput.setText("")
}
}
// 语音输入发送
btnVoice.setOnClickListener {
voiceAssistant.startListening()
tvResult.text = "正在聆听..."
}
}
// 初始化AI模块
private fun initAI() {
// 初始化模型
modelLoader = ModelLoader(this)
modelLoader.init()
// 初始化语音助手
voiceAssistant = VoiceAssistant(this) { text ->
etInput.setText(text)
val result = modelLoader.infer(text)
tvResult.text = "AI回复:$result"
voiceAssistant.speak(result)
}
voiceAssistant.init()
}
// 检查权限
private fun checkPermissions(): Boolean {
val storagePermission = ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
val micPermission = ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO)
return storagePermission == PackageManager.PERMISSION_GRANTED && micPermission == PackageManager.PERMISSION_GRANTED
}
// 申请权限
private fun requestPermissions() {
ActivityCompat.requestPermissions(
this,
arrayOf(Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.RECORD_AUDIO),
PERMISSION_REQUEST_CODE
)
}
// 权限申请结果回调
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (requestCode == PERMISSION_REQUEST_CODE) {
if (grantResults.all { it == PackageManager.PERMISSION_GRANTED }) {
initAI()
} else {
tvResult.text = "需要存储和麦克风权限才能使用AI助手"
}
}
}
// 释放资源
override fun onDestroy() {
super.onDestroy()
modelLoader.close()
voiceAssistant.release()
}
}
第四步:UI布局(activity_main.xml)
简单做个交互界面,新手直接复制用:
xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:id="@+id/tv_result"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:background="#f5f5f5"
android:padding="16dp"
android:text="AI回复将显示在这里..."
android:textSize="18sp" />
<EditText
android:id="@+id/et_input"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="请输入文本或点击语音按钮"
android:layout_marginTop="16dp"
android:padding="12dp"
android:textSize="16sp" />
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="8dp">
<Button
android:id="@+id/btn_send"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:text="发送"
android:textSize="16sp" />
<Button
android:id="@+id/btn_voice"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_marginStart="8dp"
android:text="语音输入"
android:textSize="16sp" />
</LinearLayout>
</LinearLayout>
四、运行测试+优化技巧
1. 测试步骤
- 连接测试设备(真机或模拟器),确保设备开启USB调试;
- 点击Android Studio的"Run"按钮,等待项目编译安装;
- 打开APP后,先授予存储和麦克风权限;
- 可以输入文本(比如"帮我制定一个周末计划")或点击语音按钮说话,测试AI回复和语音播报。
2. 常见问题解决
- 编译报错:检查依赖版本是否匹配,模型文件是否放在正确目录;
- 运行卡顿:在ModelLoader中调整线程数(比如改为2线程),关闭不必要的后台应用;
- 语音识别不准:尽量在安静环境测试,或更换手机麦克风;
- 模型加载失败:确认模型文件完整,没有损坏。
3. 功能扩展建议
这个基础版本已经能实现离线交互,大家可以根据需求扩展功能:
- 本地文档问答:添加PDF/TXT文件解析功能,让AI读取本地文档并解答;
- 日程管理:集成系统日历API,实现语音创建日程、提醒;
- 翻译功能:添加多语言词表,支持中英文互译;
- 界面美化:用Jetpack Compose重构UI,提升视觉效果。
五、总结
今天这套基于AndroidGen-GLM的安卓AI智能体开发教程,核心就是"轻量化+离线化",让普通开发者也能在手机端落地AI应用。整个过程不用复杂的AI算法知识,跟着代码一步步复制粘贴就能跑通,还能根据自己的需求二次开发。
现在手机AI是风口,不管是做个人工具还是创业项目,都有很大的潜力。比如可以扩展成离线AI办公助手、儿童教育助手、老人陪伴助手等,甚至可以打包上架应用市场赚钱。
如果在开发过程中遇到问题(比如模型加载失败、语音交互异常),可以在评论区留言,我会一一回复解答。也欢迎大家分享自己的扩展功能和落地案例,咱们一起交流进步!
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步。想要系统学习AI知识的朋友可以看看我的教程http://blog.csdn.net/jiangjunshow,从深度学习基础原理到各领域实战应用都有讲解。
最后,别忘了点赞收藏本文,后续还会分享更多手机AI、端侧AI的实战教程,关注我不迷路~
