AI眼鏡Rokid記賬本實戰開發 - 每日花費智能彙總應用
作者:kevin賀老師
一、實戰應用思路
1.1應用概述
基於Rokid AI眼鏡的智能記賬本應用是一個革命性的財務管理系統,通過語音識別、圖像識別和AI智能分析,實現每日花費的自動記錄、智能分類和晚間彙總分析。該應用充分利用了rokid眼鏡的攝像頭、麥克風、觸控板和揚聲器等硬件特性,打造了全新的免手操作的記賬體驗。
1.2 核心功能架構
- 實時消費記錄 - 通過語音或拍照快速記錄消費
- 智能識別分類 - AI自動識別商户、商品並進行分類
- 晚間財務彙總 - 每日消費統計和分析報告
- 多端協同 - 手機端管理,眼鏡端快速操作
1.3 AI工作流設計
核心工作流程
graph TD
A[用户消費] --> B{記錄方式選擇}
B -->|語音| C[語音輸入]
B -->|拍照| D[拍照識別]
C --> E[ASR語音轉文字]
D --> F[OCR圖像識別]
E --> G[AI語義分析]
F --> G
G --> H[自動分類]
H --> I[存儲到本地]
I --> J[同步到雲端]
J --> K[晚間彙總分析]
二、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分析,打造了全新的免手操作記賬體驗。從日常消費的實時記錄到晚間的智能彙總,真正實現了"所見即所得,所説即所記"的智能財務管理理念。這個應用不僅提升了用户體驗,更為智能眼鏡在垂直領域的應用提供了有價值的探索。