首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >SmartCabinet:基于 Android 的智能储物柜管理系统技术解析

SmartCabinet:基于 Android 的智能储物柜管理系统技术解析

作者头像
Harry技术
发布2025-11-14 12:49:33
发布2025-11-14 12:49:33
910
举报

项目背景

在实验室、工厂车间、医疗机构等场景中,贵重仪器设备和工具的管理一直是个难题。传统的人工登记方式效率低下,责任追溯困难。SmartCabinet 应运而生,这是一个基于 Android 平台开发的智能储物柜管理系统,采用现代化的技术架构,为物品存取管理提供了完整的数字化解决方案。

image-20251022153154983
image-20251022153154983
image-20251022153616152
image-20251022153616152

技术架构亮点

1. MVVM 架构 + Repository 模式

系统采用经典的 MVVM(Model-View-ViewModel)架构模式,配合 Repository 模式实现数据访问层抽象:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
// ViewModel 层处理业务逻辑
class UserViewModel(application: Application) : AndroidViewModel(application) {
    private val repository = UserRepository(application)
    val users: LiveData<List<User>> = repository.getAllUsers()

    fun addUser(user: User) = viewModelScope.launch {
        repository.insert(user)
    }
}

// Repository 层统一数据访问
class UserRepository(context: Context) {
    private val userDao = AppDatabase.getDatabase(context).userDao()

    fun getAllUsers(): LiveData<List<User>> = userDao.getAllUsers()

    suspend fun insert(user: User) {
        userDao.insert(user)
    }
}

优势

  • 清晰的职责分离,代码可维护性强
  • LiveData 实现响应式数据绑定,UI 自动更新
  • 便于单元测试和功能扩展

2. 内置 Ktor HTTP 服务器

系统最大的技术亮点是在 Android 应用内嵌入了 Ktor HTTP 服务器,提供完整的 RESTful API 接口:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
class KtorServer(private val context: Context) {
    private var server: ApplicationEngine? = null

    fun start(port: Int, host: String) {
        server = embeddedServer(Netty, port = port, host = host) {
            install(ContentNegotiation) {
                json(Json {
                    prettyPrint = true
                    isLenient = true
                })
            }

            install(CORS) {
                anyHost()
                allowHeader(HttpHeaders.ContentType)
            }

            routing {
                userRoutes(context)
                configurationRoutes(context)
                hardwareDeviceRoutes(context)
            }
        }.start(wait = false)
    }
}

技术特性

  • 支持动态配置端口和主机地址
  • 自动重启机制,配置变更立即生效
  • CORS 跨域支持,便于前端集成
  • 标准 JSON 数据交换格式

3. 多重身份认证系统

系统支持三种认证方式,满足不同场景需求:

人脸识别
  • 集成 ArcSoft 人脸识别 SDK
  • 支持在线激活和离线识别
  • 特征码存储在本地数据库
  • 识别准确率高达 95%+
代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
// 人脸识别配置自动从数据库读取
private fun checkFaceEngineActivation(): Boolean {
    val appId = configDao.getConfigurationByTypeAndKey("face_recognition", "app_id")?.value
    val sdkKey = configDao.getConfigurationByTypeAndKey("face_recognition", "sdk_key")?.value

    val activeCode = FaceEngine.activeOnline(this, appId, sdkKey)
    return activeCode == ErrorInfo.MOK || 
           activeCode == ErrorInfo.MERR_ASF_ALREADY_ACTIVATED
}
刷卡认证
  • 支持多种刷卡器硬件
  • 串口通信,可配置波特率、数据位等参数
  • 卡号与用户绑定,快速验证
密码认证
  • 密码加密存储
  • 支持密码修改和重置
  • 可设置密码复杂度规则
image-20251022153223871
image-20251022153223871
image-20251022153646194
image-20251022153646194

4. 硬件设备管理

系统提供完整的硬件设备管理功能,支持锁控板和刷卡器的配置:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
@Entity(tableName = "hardware_devices")
data class HardwareDevice(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val deviceId: String,           // 设备ID(如 0x01)
    val deviceName: String,         // 设备名称
    val deviceType: DeviceType,     // LOCK_CONTROLLER 或 CARD_READER
    val serialPort: String,         // 串口路径
    val baudRate: Int,              // 波特率
    val dataBits: Int = 8,          // 数据位
    val stopBits: Int = 1,          // 停止位
    val parity: Int = 0,            // 校验位
    val enabled: Boolean = true     // 是否启用
)

特性

  • 支持多设备管理
  • 串口参数灵活配置
  • 设备状态实时监控
  • 提供完整的 REST API
image-20251022153253153
image-20251022153253153

image-20251022153253153

5. 外部接口集成

系统支持与外部系统对接,实现数据同步和业务协同:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
class ExternalApiService(context: Context) {
    // 用户操作同步
    suspend fun addUser(user: User): Result<ExternalApiResponse<String>>
    suspend fun updateUser(user: User): Result<ExternalApiResponse<String>>
    suspend fun deleteUser(userId: Long): Result<ExternalApiResponse<String>>

    // 识别记录上报
    suspend fun reportFaceRecognition(userId: Long, userName: String, 
                                     result: String, confidence: Float)
    suspend fun reportCardSwipe(userId: Long, userName: String, 
                               cardNumber: String, result: String)

    // 操作记录上报
    suspend fun reportTakeItem(userId: Long, userName: String, 
                              itemInfo: String?, remark: String?)
    suspend fun reportReturnItem(userId: Long, userName: String, 
                                itemInfo: String?, remark: String?)
}

接口特性

  • 标准化的请求/响应格式
  • Token 认证机制
  • 自动重试和错误处理
  • 可配置启用/禁用
image-20251022153308957
image-20251022153308957

image-20251022153308957

6. Room 数据库设计

系统采用 Room 持久化框架,数据库设计合理,支持复杂查询:

核心数据表

  • users - 用户信息表
  • cabinets - 储物柜信息表
  • user_cabinets - 用户权限关联表
  • operation_logs - 操作日志表
  • usage_records - 使用记录表
  • configurations - 系统配置表
  • hardware_devices - 硬件设备表
代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
@Dao
interface UserDao {
    @Query("SELECT * FROM users ORDER BY id DESC")
    fun getAllUsers(): LiveData<List<User>>

    @Query("SELECT * FROM users WHERE name LIKE '%' || :query || '%' 
            OR employeeId LIKE '%' || :query || '%' 
            LIMIT :limit OFFSET :offset")
    suspend fun searchUsers(query: String, limit: Int, offset: Int): List<User>

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insert(user: User): Long

    @Update
    suspend fun update(user: User)

    @Delete
    suspend fun delete(user: User)
}

7. 协程异步处理

全面使用 Kotlin 协程处理异步操作,避免回调地狱:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
// ViewModel 中使用协程
fun loadUsers() {
    viewModelScope.launch {
        try {
            _isLoading.value = true
            val users = withContext(Dispatchers.IO) {
                repository.getAllUsers()
            }
            _users.value = users
        } catch (e: Exception) {
            _error.value = e.message
        } finally {
            _isLoading.value = false
        }
    }
}

核心功能实现

1. 取仪器流程

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
suspend fun takeInstrument(userId: Long, cabinetId: Long): Result<String> {
    return withContext(Dispatchers.IO) {
        try {
            // 1. 验证用户权限
            val hasPermission = userCabinetRepository.checkPermission(userId, cabinetId)
            if (!hasPermission) {
                return@withContext Result.failure(Exception("无权限"))
            }

            // 2. 检查柜体状态
            val cabinet = cabinetRepository.getById(cabinetId)
            if (cabinet.status != CabinetStatus.AVAILABLE) {
                return@withContext Result.failure(Exception("柜体不可用"))
            }

            // 3. 开锁
            hardwareController.openLock(cabinet.boardId, cabinet.lockId)

            // 4. 记录操作日志
            val log = OperationLog(
                userId = userId,
                cabinetId = cabinetId,
                operation = "TAKE",
                timestamp = System.currentTimeMillis()
            )
            operationLogRepository.insert(log)

            // 5. 创建使用记录
            val record = UsageRecord(
                userId = userId,
                cabinetId = cabinetId,
                takeTime = System.currentTimeMillis()
            )
            usageRecordRepository.insert(record)

            // 6. 更新柜体状态
            cabinetRepository.updateStatus(cabinetId, CabinetStatus.IN_USE)

            // 7. 上报外部接口
            externalApiService.reportTakeItem(userId, userName)

            Result.success("取仪器成功")
        } catch (e: Exception) {
            Result.failure(e)
        }
    }
}

2. 网络配置自动重启

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
fun applyConfiguration(port: Int, host: String) {
    viewModelScope.launch {
        try {
            _isRestarting.value = true

            // 1. 保存配置到数据库
            configRepository.updateNetworkConfig(port, host)

            // 2. 停止当前服务器
            if (ktorServer.isRunning()) {
                ktorServer.stop()
                delay(1000) // 等待完全停止
            }

            // 3. 启动新配置的服务器
            ktorServer.start(port, host)
            delay(2000) // 等待启动完成

            // 4. 检查服务器状态
            val isRunning = ktorServer.checkStatus()

            if (isRunning) {
                _message.value = "配置应用成功,服务器已重启"
            } else {
                _message.value = "服务器重启失败"
            }
        } catch (e: Exception) {
            _message.value = "配置应用失败: ${e.message}"
        } finally {
            _isRestarting.value = false
        }
    }
}

API 接口示例

用户管理 API

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
# 获取所有用户
GET http://localhost:8080/api/users

# 搜索用户(支持分页)
GET http://localhost:8080/api/users/search?query=张三&page=1&size=20

# 创建用户
POST http://localhost:8080/api/users
Content-Type: application/json

{
  "employeeId": "E001",
  "name": "张三",
  "phoneNumber": "13800138000",
  "position": "工程师",
  "gender": "MALE",
  "status": "ENABLED",
  "cardNumber": "1234567890",
  "password": "1234"
}

# 更新用户
PUT http://localhost:8080/api/users/123
Content-Type: application/json

{
  "name": "张三",
  "phoneNumber": "13800138001",
  "position": "高级工程师"
}

# 删除用户
DELETE http://localhost:8080/api/users/123

硬件设备 API

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
# 获取所有硬件设备
GET http://localhost:8080/api/hardware-devices

# 创建硬件设备
POST http://localhost:8080/api/hardware-devices
Content-Type: application/json

{
  "deviceId": "0x01",
  "deviceName": "锁控板",
  "deviceType": "LOCK_CONTROLLER",
  "serialPort": "/dev/ttyS3",
  "baudRate": 9600,
  "dataBits": 8,
  "stopBits": 1,
  "parity": 0,
  "enabled": true
}

# 更新设备状态
PUT http://localhost:8080/api/hardware-devices/device/0x01/enabled
Content-Type: application/json

{
  "enabled": false
}

性能优化

1. 分页加载

用户列表、操作日志等数据支持分页加载,避免一次性加载大量数据:

代码语言:javascript
复制
ounter(lineounter(line
@Query("SELECT * FROM users ORDER BY id DESC LIMIT :limit OFFSET :offset")
suspend fun getUsersPaged(limit: Int, offset: Int): List<User>

2. 数据库索引

关键字段添加索引,提升查询性能:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
@Entity(
    tableName = "users",
    indices = [
        Index(value = ["employeeId"], unique = true),
        Index(value = ["cardNumber"]),
        Index(value = ["name"])
    ]
)
data class User(...)

3. 协程优化

使用 Dispatchers.IO 处理 IO 操作,避免阻塞主线程:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
viewModelScope.launch {
    val result = withContext(Dispatchers.IO) {
        // 数据库操作
        repository.getAllUsers()
    }
    // UI 更新在主线程
    _users.value = result
}

安全性设计

  1. 密码加密:用户密码使用哈希算法加密存储
  2. Token 认证:外部接口调用支持 Token 认证
  3. 权限控制:用户-储物柜权限关联,精细化权限管理
  4. 操作审计:所有操作记录日志,支持追溯
  5. 数据隔离:不同用户数据隔离,防止越权访问

扩展性设计

1. 插件化认证方式

认证方式采用策略模式,易于扩展:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
interface AuthenticationStrategy {
    suspend fun authenticate(credential: Any): Result<User>
}

class FaceAuthStrategy : AuthenticationStrategy {
    override suspend fun authenticate(credential: Any): Result<User> {
        // 人脸识别逻辑
    }
}

class CardAuthStrategy : AuthenticationStrategy {
    override suspend fun authenticate(credential: Any): Result<User> {
        // 刷卡验证逻辑
    }
}

2. 可配置的外部接口

外部接口支持动态配置,无需修改代码:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
enum class ExternalServiceType(
    val serviceName: String,
    val description: String
) {
    ADD_USER("AddUser", "新增用户"),
    UPDATE_USER("UpdateUser", "修改用户"),
    DELETE_USER("DeleteUser", "删除用户"),
    FACE_RECOGNITION_RECORD("FaceRecognitionRecord", "人脸识别记录"),
    CARD_SWIPE_RECORD("CardSwipeRecord", "刷卡记录"),
    TAKE_ITEM_RECORD("TakeItemRecord", "取物记录"),
    RETURN_ITEM_RECORD("ReturnItemRecord", "还物记录")
}

3. 主题系统

image-20251022153354415
image-20251022153354415
image-20251022153404198
image-20251022153404198
image-20251022153420987
image-20251022153420987

支持自定义主题,满足不同客户需求:

代码语言:javascript
复制
ounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(lineounter(line
@Entity(tableName = "theme_configurations")
data class ThemeConfiguration(
    @PrimaryKey(autoGenerate = true) val id: Long = 0,
    val themeType: String,          // 主题类型
    val primaryColor: String,       // 主色调
    val secondaryColor: String,     // 辅助色
    val backgroundColor: String,    // 背景色
    val textColor: String          // 文字颜色
)

技术栈总结

技术

版本

用途

Kotlin

1.9.0

主要开发语言

Android SDK

36

Android 平台

Room

2.6.0

本地数据库

Ktor Server

2.3.5

HTTP 服务器

Coroutines

1.7.3

异步处理

LiveData

2.6.2

响应式数据

Material Design

1.10.0

UI 组件

ArcSoft Face SDK

4.1

人脸识别

Kotlinx Serialization

1.6.0

JSON 序列化

部署与运行

环境要求

  • Android Studio Hedgehog | 2023.1.1+
  • Android SDK API Level 36
  • Kotlin 1.9.0+
  • Gradle 8.0+
  • 最低 Android 版本:API Level 22 (Android 5.1)

总结

SmartCabinet 是一个技术栈先进、架构清晰、功能完整的智能储物柜管理系统。它不仅提供了友好的用户界面,还通过内置的 HTTP 服务器提供了强大的 API 接口,能够很好地适应各种智能存储管理场景的需求。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-10-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 Harry技术 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 项目背景
    • 技术架构亮点
      • 1. MVVM 架构 + Repository 模式
      • 2. 内置 Ktor HTTP 服务器
      • 3. 多重身份认证系统
      • 4. 硬件设备管理
      • 5. 外部接口集成
      • 6. Room 数据库设计
      • 7. 协程异步处理
    • 核心功能实现
      • 1. 取仪器流程
      • 2. 网络配置自动重启
    • API 接口示例
      • 用户管理 API
      • 硬件设备 API
    • 性能优化
      • 1. 分页加载
      • 2. 数据库索引
      • 3. 协程优化
    • 安全性设计
    • 扩展性设计
      • 1. 插件化认证方式
      • 2. 可配置的外部接口
      • 3. 主题系统
    • 技术栈总结
    • 部署与运行
      • 环境要求
    • 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档