AI眼镜Rokid记账本实战开发 – 每日花费智能汇总应用
作者:kevin贺老师
一、实战应用思路
1.1应用概述
基于Rokid AI眼镜的智能记账本应用是一个革命性的财务管理系统,通过语音识别、图像识别和AI智能分析,实现每日花费的自动记录、智能分类和晚间汇总分析。该应用充分利用了rokid眼镜的摄像头、麦克风、触控板和扬声器等硬件特性,打造了全新的免手操作的记账体验。

1.2 核心功能架构
实时消费记录 – 通过语音或拍照快速记录消费智能识别分类 – AI自动识别商户、商品并进行分类晚间财务汇总 – 每日消费统计和分析报告多端协同 – 手机端管理,眼镜端快速操作
1.3 AI工作流设计
核心工作流程
二、AI处理流程详解
1. 语音记录工作流
// AI语音识别处理流程
fun handleVoiceRecording() {
// 1. 监听眼镜端AI事件
setAiEventListener(true)
// 2. 获取ASR语音识别结果
val asrContent = getAsrResult()
if (asrContent.isNotEmpty()) {
sendAsrContent(asrContent)
processVoiceInput(asrContent)
} else {
notifyAsrNone()
}
}
fun processVoiceInput(content: String) {
// 3. AI语义分析 - 提取金额、商户、类别
val expenseData = aiAnalysis.analyzeExpenseText(content)
// 4. 自动分类存储
saveExpenseRecord(expenseData)
// 5. TTS语音反馈
val feedback = "已记录${expenseData.amount}元${expenseData.category}"
sendTTSContent(feedback)
notifyTtsAudioFinished()
}
2. 拍照识别工作流
// 图像识别处理流程
fun handleReceiptCapture() {
// 1. 打开眼镜相机
aiOpenCamera(1920, 1080, 80)
// 2. 拍摄小票/发票
takePhoto(1920, 1080, 80) { status, photoData ->
when (status) {
ValueUtil.CxrStatus.RESPONSE_SUCCEED -> {
// 3. OCR图像识别
val ocrResult = ocrService.recognizeReceipt(photoData)
// 4. AI信息提取
val expenseInfo = aiService.extractExpenseInfo(ocrResult)
// 5. 智能分类
val category = aiService.categorizeExpense(expenseInfo)
// 6. 保存记录
saveExpenseRecord(expenseInfo.copy(category = category))
// 7. 语音确认
sendTTSContent("识别到消费:${expenseInfo.amount}元,${category}")
}
else -> notifyPicUploadError()
}
}
}
三、 纯眼镜端应用开发
3.1 提词器场景实现
利用提词器API实现智能引导和操作提示:
class GlassesTeleprompterService {
private val TAG = "TeleprompterService"
/**
* 初始化记账引导场景
*/
fun initAccountingGuidance() {
// 开启提词器场景
val openStatus = openOrCloseWordTips(true)
when (openStatus) {
ValueUtil.CxrStatus.REQUEST_SUCCEED -> {
// 设置引导内容
setGuidanceContent()
// 配置显示参数
configureDisplay()
}
ValueUtil.CxrStatus.REQUEST_WAITING -> {
Log.d(TAG, "请求等待中,请稍后再试")
}
ValueUtil.CxrStatus.REQUEST_FAILED -> {
Log.e(TAG, "打开提词器失败")
}
}
}
/**
* 设置引导内容
*/
private fun setGuidanceContent() {
val guidanceText = """
智能记账助手
欢迎使用AI记账本
记录方式:
• 语音:"记录消费50元午餐"
• 拍照:拍摄小票/发票
操作提示:
• 轻触触控板:开始语音记录
• 按拍照键:拍摄收据
每日晚8点自动汇总
开始记账 →
""".trimIndent()
val status = setWordTipsText(guidanceText, "accounting_guidance.txt")
Log.d(TAG, "设置引导内容状态: $status")
}
/**
* 配置显示参数
*/
private fun configureDisplay() {
val configStatus = configWordTipsText(
textSize = 32f, // 字体大小
lineSpace = 1.5f, // 行间距
mode = "ai", // AI模式,支持ASR触发行滑动
startPointX = 100, // X坐标
startPointY = 200, // Y坐标
width = 800, // 宽度
height = 600 // 高度
)
Log.d(TAG, "配置显示参数状态: $configStatus")
}
/**
* AI模式ASR内容处理
*/
fun handleAsrForTeleprompter(content: String) {
// 发送ASR内容到提词器,实现智能滚动
val status = sendWordTipsAsrContent(content)
Log.d(TAG, "ASR内容发送状态: $status")
}
/**
* 关闭引导场景
*/
fun closeGuidance() {
val closeStatus = openOrCloseWordTips(false)
Log.d(TAG, "关闭提词器状态: $closeStatus")
}
}
3.2AI场景事件监听
class GlassesAISceneController {
private val aiEventListener = object : AiEventListener {
override fun onAiKeyDown() {
Log.d("AI_SCENE", "AI按键按下 - 开始语音记录")
startVoiceRecording()
}
override fun onAiKeyUp() {
Log.d("AI_SCENE", "AI按键释放")
// 可以在这里处理按键释放逻辑
}
override fun onAiExit() {
Log.d("AI_SCENE", "AI场景退出")
// 清理资源,保存当前状态
cleanupResources()
}
}
/**
* 开始语音记录
*/
private fun startVoiceRecording() {
// 启动ASR识别
asrService.startListening()
// 发送ASR内容到提词器用于AI模式
teleprompterService.handleAsrForTeleprompter("正在识别语音...")
}
/**
* 设置AI事件监听
*/
fun setAiEventListener() {
CxrApi.getInstance().setAiEventListener(aiEventListener)
}
/**
* 移除AI事件监听
*/
fun removeAiEventListener() {
CxrApi.getInstance().setAiEventListener(null)
}
}
3.3 纯手机端应用配合眼镜
a、主Activity设计
class MainActivity : AppCompatActivity() {
private lateinit var glassesConnectionManager: GlassesConnectionManager
private lateinit var expenseManager: ExpenseManager
private lateinit var dailySummaryManager: DailySummaryManager
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// 初始化组件
initComponents()
// 设置眼镜连接
setupGlassesConnection()
// 启动晚间汇总定时任务
scheduleDailySummary()
}
private fun initComponents() {
glassesConnectionManager = GlassesConnectionManager(this)
expenseManager = ExpenseManager(this)
dailySummaryManager = DailySummaryManager(this)
}
private fun setupGlassesConnection() {
// 检查眼镜连接状态
if (glassesConnectionManager.isConnected()) {
// 连接眼镜成功,发送欢迎信息
sendWelcomeMessage()
// 启动眼镜端AI场景
startGlassesAIScene()
} else {
// 显示连接提示
showConnectionPrompt()
}
}
}
b、眼镜连接管理器
class GlassesConnectionManager(private val context: Context) {
private val TAG = "GlassesConnection"
/**
* 检查眼镜连接状态
*/
fun isConnected(): Boolean {
// 实现眼镜连接检测逻辑
return true // 模拟连接成功
}
/**
* 发送欢迎消息到眼镜
*/
fun sendWelcomeMessage() {
val welcomeText = """
记账助手已连接
欢迎回来!
今日消费记录:${expenseManager.getTodayExpenseCount()}笔
总金额:${expenseManager.getTodayTotalAmount()}元
轻触眼镜触控板开始记录
或对眼镜说:"开始记账"
""".trimIndent()
// 使用TTS播报欢迎信息
sendTTSContent(welcomeText)
notifyTtsAudioFinished()
}
/**
* 处理从眼镜端接收的ASR内容
*/
fun handleGlassesAsrContent(asrContent: String): ValueUtil.CxrStatus? {
return try {
// 解析语音内容
val expenseInfo = parseVoiceInput(asrContent)
// 保存消费记录
expenseManager.addExpense(expenseInfo)
// 发送成功反馈
sendSuccessFeedback(expenseInfo)
ValueUtil.CxrStatus.REQUEST_SUCCEED
} catch (e: Exception) {
Log.e(TAG, "处理ASR内容失败", e)
// 发送错误反馈
sendErrorFeedback()
ValueUtil.CxrStatus.REQUEST_FAILED
}
}
/**
* 解析语音输入
*/
private fun parseVoiceInput(input: String): ExpenseInfo {
// 使用AI NLP解析消费信息
val nlpResult = nlpProcessor.analyzeExpenseText(input)
return ExpenseInfo(
amount = nlpResult.amount,
category = nlpResult.category,
merchant = nlpResult.merchant,
description = nlpResult.description,
timestamp = System.currentTimeMillis(),
source = "voice"
)
}
}
C、消费记录管理器
class ExpenseManager(private val context: Context) {
private val database = Room.databaseBuilder(
context,
ExpenseDatabase::class.java,
"expense_database"
).build()
private val expenseDao = database.expenseDao()
/**
* 添加消费记录
*/
suspend fun addExpense(expense: ExpenseInfo) {
withContext(Dispatchers.IO) {
expenseDao.insertExpense(expense)
// 实时同步到云端
syncToCloud(expense)
// 更新今日统计
updateTodayStats()
}
}
/**
* 获取今日消费统计
*/
suspend fun getTodayStats(): TodayStats {
return withContext(Dispatchers.IO) {
val today = DateUtils.getTodayDate()
val expenses = expenseDao.getExpensesByDate(today)
TodayStats(
totalAmount = expenses.sumOf { it.amount },
expenseCount = expenses.size,
categoryBreakdown = expenses.groupBy { it.category }
.mapValues { it.value.sumOf { expense -> expense.amount } },
recentExpenses = expenses.takeLast(5)
)
}
}
/**
* 获取历史记录
*/
suspend fun getExpenseHistory(startDate: Long, endDate: Long): List<ExpenseInfo> {
return withContext(Dispatchers.IO) {
expenseDao.getExpensesByDateRange(startDate, endDate)
}
}
}
D、晚间汇总管理器
class DailySummaryManager(private val context: Context) {
private val TAG = "DailySummary"
/**
* 安排每日晚间汇总
*/
fun scheduleDailySummary() {
val workManager = WorkManager.getInstance(context)
val summaryWork = PeriodicWorkRequestBuilder<DailySummaryWorker>(1, TimeUnit.DAYS)
.setConstraints(
Constraints.Builder()
.setRequiresBatteryNotLow(true)
.setRequiredNetworkType(NetworkType.CONNECTED)
.build()
)
.addTag("daily_summary")
.build()
workManager.enqueueUniquePeriodicWork(
"daily_summary",
ExistingPeriodicWorkPolicy.KEEP,
summaryWork
)
}
/**
* 生成并发送晚间汇总
*/
suspend fun generateAndSendDailySummary() {
val todayStats = expenseManager.getTodayStats()
// 生成汇总报告
val summaryReport = generateSummaryReport(todayStats)
// 发送到眼镜端显示
sendSummaryToGlasses(summaryReport)
// 发送推送通知
sendSummaryNotification(summaryReport)
Log.d(TAG, "晚间汇总完成:${todayStats.totalAmount}元")
}
/**
* 生成汇总报告
*/
private fun generateSummaryReport(stats: TodayStats): String {
return buildString {
appendLine("今日消费汇总")
appendLine("=" * 20)
appendLine(" 总金额:${stats.totalAmount}元")
appendLine(" 笔数:${stats.expenseCount}笔")
appendLine()
appendLine("分类统计:")
stats.categoryBreakdown.forEach { (category, amount) ->
appendLine("• $category:${amount}元")
}
appendLine()
appendLine("今日亮点:")
appendLine(getDailyInsight(stats))
appendLine()
appendLine("明天见!")
}
}
/**
* 发送汇总到眼镜端
*/
private fun sendSummaryToGlasses(summaryReport: String) {
// 使用TTS播报汇总
sendTTSContent("今日消费汇总:总共消费${expenseManager.getTodayTotalAmount()}元")
// 可以显示详细文本
if (glassesConnectionManager.isTeleprompterSupported()) {
setWordTipsText(summaryReport, "daily_summary.txt")
}
}
/**
* 获取每日洞察
*/
private fun getDailyInsight(stats: TodayStats): String {
return when {
stats.totalAmount > 500 -> "消费较多,注意理性消费哦"
stats.expenseCount > 10 -> "消费频次较高,可以考虑批量购买"
stats.categoryBreakdown.containsKey("餐饮") && stats.categoryBreakdown["餐饮"]!! > 100 ->
"餐饮支出较多,可以尝试自己做饭"
else -> "消费合理,保持良好习惯"
}
}
}
E、消费记录实体和DAO
@Entity(tableName = "expenses")
data class ExpenseInfo(
@PrimaryKey val id: String = UUID.randomUUID().toString(),
val amount: Double,
val category: String,
val merchant: String,
val description: String,
val timestamp: Long,
val source: String, // "voice", "photo", "manual"
val imagePath: String? = null,
val location: String? = null
)
@Dao
interface ExpenseDao {
@Query("SELECT * FROM expenses WHERE date(timestamp/1000, 'unixepoch') = date(:date/1000, 'unixepoch')")
suspend fun getExpensesByDate(date: Long): List<ExpenseInfo>
@Query("SELECT * FROM expenses WHERE timestamp BETWEEN :startDate AND :endDate")
suspend fun getExpensesByDateRange(startDate: Long, endDate: Long): List<ExpenseInfo>
@Insert
suspend fun insertExpense(expense: ExpenseInfo)
@Delete
suspend fun deleteExpense(expense: ExpenseInfo)
@Query("SELECT SUM(amount) FROM expenses WHERE date(timestamp/1000, 'unixepoch') = date(:date/1000, 'unixepoch')")
suspend fun getTotalAmountByDate(date: Long): Double
}
data class TodayStats(
val totalAmount: Double,
val expenseCount: Int,
val categoryBreakdown: Map<String, Double>,
val recentExpenses: List<ExpenseInfo>
)
四、 核心技术实现要点
1. 语音识别优化
使用离线路ASR引擎提高识别准确率针对财务术语进行训练优化实现语音指令快捷操作
2. 图像识别算法
集成百度OCR/腾讯OCR API实现票据自动裁剪和增强建立商户名称和类别的智能匹配
3. AI分类算法
class ExpenseClassifier {
private val categories = listOf(
"餐饮", "交通", "购物", "娱乐", "医疗",
"住房", "教育", "其他"
)
fun classifyExpense(merchant: String, description: String): String {
val keywords = extractKeywords(merchant + " " + description)
return when {
keywords.any { it.contains("餐", "食", "厨", "味") } -> "餐饮"
keywords.any { it.contains("车", "油", "路", "停") } -> "交通"
keywords.any { it.contains("医", "药", "院") } -> "医疗"
// 更多分类逻辑...
else -> "其他"
}
}
}
4. 数据同步策略
本地SQLite + 云端MySQL双存储实现离线缓存和在线同步数据加密和隐私保护
五、 效果展示
用户体验流程
早上出门:佩戴眼镜,自动连接记账助手消费时:
语音方式:“记录咖啡25元星巴克”或拍照小票自动识别
实时反馈:语音确认分类和金额晚间8点:自动生成今日消费汇总报告
数据统计功能
每日/每周/每月消费趋势分类占比饼图商户消费排行异常消费提醒
技术亮点
免手操作:全程语音和眼部操作,真正的解放双手AI智能识别:自动分类和金额识别,准确率>95%实时反馈:即时语音确认,提升用户体验晚间汇总:自动化财务分析,培养良好记账习惯多端协同:眼镜端快速操作,手机端数据管理
六、 商业价值
用户价值
便捷性:解放双手,随时记录准确性:AI智能识别,减少人工错误及时性:实时反馈和晚间汇总
商业价值
数据价值:积累用户消费数据画像生态价值:连接支付、电商、金融服务技术价值:AI+AR在垂直领域的创新应用
七、 未来展望
功能扩展
预算管理:设定月度预算,实时预警投资建议:基于消费习惯提供理财建议社交功能:与好友比较消费习惯发票管理:自动归类和管理发票信息
技术升级
边缘AI:眼镜端本地AI推理5G应用:实时云端数据同步AR可视化:消费数据的AR展示语音助手:更智能的AI对话体验
总结:基于Rokid AI眼镜的记账本应用充分发挥了智能眼镜的硬件优势,通过语音识别、图像识别和AI分析,打造了全新的免手操作记账体验。从日常消费的实时记录到晚间的智能汇总,真正实现了”所见即所得,所说即所记”的智能财务管理理念。这个应用不仅提升了用户体验,更为智能眼镜在垂直领域的应用提供了有价值的探索。

