Skip to content

自启动与按键自定义

本页说明 Glass3 上应用开机自启动、物理按键监听和按键事件拦截的常见实现方式。

1. 开机自启动

功能说明

应用可以通过设置系统属性,让设备重启后自动拉起指定包名的应用。

适用场景:

  • 巡检、安防、工业作业等专用应用。
  • 设备开机后需要直接进入业务页面。
  • 不希望用户手动从应用列表启动。

配置方式

通过反射调用 android.os.SystemProperties 设置系统属性:

kotlin
fun setSystemProp(key: String?, value: String?) {
    try {
        val clazz = Class.forName("android.os.SystemProperties")
        val set = clazz.getMethod("set", String::class.java, String::class.java)
        set.invoke(clazz, key, value)
    } catch (e: Exception) {
        Log.e("SystemProp", "set system prop failed", e)
    }
}

将当前应用设置为开机自启动:

kotlin
setSystemProp("persist.vendor.boot.pkg", packageName)

设备重启后,系统会读取该属性并拉起对应应用。

使用建议

  • 建议在应用初始化时延迟 1–2 秒再初始化 SDK,避免系统服务尚未完全就绪。
  • 请确认应用有明确的启动页。
  • 若多个应用都设置自启动,以系统最终写入的包名为准。
  • 该能力依赖系统支持,建议在目标系统版本上验证。

2. 物理按键监听

支持的事件

常见按键广播包括:

事件Action
单击com.rokid.glass3.action.button.CLICK
双击com.rokid.glass3.action.button.DOUBLE_CLICK
按下以当前系统提供的 ACTION_BUTTON_DOWN 为准
抬起以当前系统提供的 ACTION_BUTTON_UP 为准

不同系统版本可能会有扩展 action,建议以 Demo 中 MyApplication 定义为准。

3. 拦截按键事件

应用可以注册高优先级广播接收器,并在需要消费事件时调用 abortBroadcast()

kotlin
private val buttonReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context?, intent: Intent?) {
        when (intent?.action) {
            MyApplication.ORDER_ACTION_BUTTON_CLICK -> {
                Log.d(TAG, "single click")
                abortBroadcast()
                screenShot()
            }

            MyApplication.ORDER_ACTION_BUTTON_DOUBLE_CLICK -> {
                Log.d(TAG, "double click")
            }

            MyApplication.ACTION_BUTTON_DOWN -> {
                Log.d(TAG, "button down")
            }

            MyApplication.ACTION_BUTTON_UP -> {
                Log.d(TAG, "button up")
            }
        }
    }
}

注册广播:

kotlin
private val intentFilter = IntentFilter().apply {
    addAction(MyApplication.ORDER_ACTION_BUTTON_CLICK)
    addAction(MyApplication.ORDER_ACTION_BUTTON_DOUBLE_CLICK)
    addAction(MyApplication.ACTION_BUTTON_DOWN)
    addAction(MyApplication.ACTION_BUTTON_UP)
    priority = 100
}

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
        registerReceiver(buttonReceiver, intentFilter, RECEIVER_EXPORTED)
    } else {
        registerReceiver(buttonReceiver, intentFilter)
    }
}

override fun onDestroy() {
    super.onDestroy()
    unregisterReceiver(buttonReceiver)
}

4. 长按处理

如果业务需要识别长按,可以在 ACTION_BUTTON_DOWN 时延迟执行,在 ACTION_BUTTON_UP 时取消。

kotlin
private val handler = Handler(Looper.getMainLooper())
private val longPressRunnable = Runnable {
    Log.d(TAG, "long press")
}

private fun onButtonDown() {
    handler.postDelayed(longPressRunnable, 1200)
}

private fun onButtonUp() {
    handler.removeCallbacks(longPressRunnable)
}

5. 注意事项

  • 建议设置 priority > 0,确保业务接收器优先处理。
  • 只有有序广播才能被 abortBroadcast() 拦截。
  • 系统保留按键不一定允许应用拦截。
  • 指环中间键长按通常会触发 KEY_POWER,用于亮屏/灭屏,应用层无法拦截。
  • 按键行为可能随系统版本变化,正式交付前请在目标系统版本上验证。