feat: 小趣手表APP Android原生重构 - 基础框架搭建

已完成的模块:
1. 项目脚手架 - Gradle配置、28个包目录、核心基类
2. 权限管理 - 确认定制ROM已预授权所有权限
3. 工具类 - DateUtil/DeviceUtil/NetworkUtil/Md5Util
4. 设备信息 - DevicePrefs/UserPrefs (SharedPreferences)
5. 网络层 - OkHttp+Retrofit+MD5签名拦截器+解绑拦截器
6. 基础UI组件 - NavBarView/QuTipDialog/QuConfirmDialog/ActionButton/iconfont

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
dongliang
2026-04-27 11:26:50 +09:30
commit a397985954
89 changed files with 3211 additions and 0 deletions

View File

@@ -0,0 +1,89 @@
package com.xiaoqu.watch.data.prefs
import android.content.Context
import android.content.SharedPreferences
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
/**
* 设备信息存储(解绑时不清除)
* 对应旧版 uni.setStorage('watchInfo', {...})
*/
@Singleton
class DevicePrefs @Inject constructor(
@ApplicationContext context: Context
) {
private val sp: SharedPreferences =
context.getSharedPreferences("device_prefs", Context.MODE_PRIVATE)
var imei: String
get() = sp.getString(KEY_IMEI, "") ?: ""
set(value) = sp.edit().putString(KEY_IMEI, value).apply()
var serial: String
get() = sp.getString(KEY_SERIAL, "") ?: ""
set(value) = sp.edit().putString(KEY_SERIAL, value).apply()
var bluetoothName: String
get() = sp.getString(KEY_BT_NAME, "") ?: ""
set(value) = sp.edit().putString(KEY_BT_NAME, value).apply()
var bluetoothMac: String
get() = sp.getString(KEY_BT_MAC, "") ?: ""
set(value) = sp.edit().putString(KEY_BT_MAC, value).apply()
var brand: String
get() = sp.getString(KEY_BRAND, "") ?: ""
set(value) = sp.edit().putString(KEY_BRAND, value).apply()
var model: String
get() = sp.getString(KEY_MODEL, "") ?: ""
set(value) = sp.edit().putString(KEY_MODEL, value).apply()
var osVersion: String
get() = sp.getString(KEY_OS_VERSION, "") ?: ""
set(value) = sp.edit().putString(KEY_OS_VERSION, value).apply()
var totalMemory: Long
get() = sp.getLong(KEY_TOTAL_MEMORY, 0)
set(value) = sp.edit().putLong(KEY_TOTAL_MEMORY, value).apply()
/** 是否已初始化过设备信息 */
val isInitialized: Boolean
get() = imei.isNotEmpty()
/** 从 DeviceUtil 批量写入设备信息 */
fun saveDeviceInfo(
imei: String,
serial: String,
bluetoothName: String,
bluetoothMac: String,
brand: String,
model: String,
osVersion: String,
totalMemory: Long
) {
sp.edit()
.putString(KEY_IMEI, imei)
.putString(KEY_SERIAL, serial)
.putString(KEY_BT_NAME, bluetoothName)
.putString(KEY_BT_MAC, bluetoothMac)
.putString(KEY_BRAND, brand)
.putString(KEY_MODEL, model)
.putString(KEY_OS_VERSION, osVersion)
.putLong(KEY_TOTAL_MEMORY, totalMemory)
.apply()
}
companion object {
private const val KEY_IMEI = "imei"
private const val KEY_SERIAL = "serial"
private const val KEY_BT_NAME = "bluetooth_name"
private const val KEY_BT_MAC = "bluetooth_mac"
private const val KEY_BRAND = "brand"
private const val KEY_MODEL = "model"
private const val KEY_OS_VERSION = "os_version"
private const val KEY_TOTAL_MEMORY = "total_memory"
}
}

View File

@@ -0,0 +1,61 @@
package com.xiaoqu.watch.data.prefs
import android.content.Context
import android.content.SharedPreferences
import dagger.hilt.android.qualifiers.ApplicationContext
import javax.inject.Inject
import javax.inject.Singleton
/**
* 用户绑定信息存储(解绑时清除)
* 对应旧版 uni.setStorage('bondUser', {...})
*/
@Singleton
class UserPrefs @Inject constructor(
@ApplicationContext context: Context
) {
private val sp: SharedPreferences =
context.getSharedPreferences("user_prefs", Context.MODE_PRIVATE)
var userId: Long
get() = sp.getLong(KEY_USER_ID, 0)
set(value) = sp.edit().putLong(KEY_USER_ID, value).apply()
var mobile: String
get() = sp.getString(KEY_MOBILE, "") ?: ""
set(value) = sp.edit().putString(KEY_MOBILE, value).apply()
var userName: String
get() = sp.getString(KEY_USER_NAME, "") ?: ""
set(value) = sp.edit().putString(KEY_USER_NAME, value).apply()
var headUrl: String
get() = sp.getString(KEY_HEAD_URL, "") ?: ""
set(value) = sp.edit().putString(KEY_HEAD_URL, value).apply()
/** 是否已绑定用户 */
val isBound: Boolean
get() = userId > 0
/** 保存用户绑定信息 */
fun saveUser(userId: Long, mobile: String, userName: String, headUrl: String) {
sp.edit()
.putLong(KEY_USER_ID, userId)
.putString(KEY_MOBILE, mobile)
.putString(KEY_USER_NAME, userName)
.putString(KEY_HEAD_URL, headUrl)
.apply()
}
/** 解绑时清除所有用户数据 */
fun clear() {
sp.edit().clear().apply()
}
companion object {
private const val KEY_USER_ID = "user_id"
private const val KEY_MOBILE = "mobile"
private const val KEY_USER_NAME = "user_name"
private const val KEY_HEAD_URL = "head_url"
}
}