Auto-start and Key Customization
This page explains common approaches for app auto-start after boot, hardware key listening, and key event interception on Glass3.
1. Auto-start after boot
What it does
An app can set a system property so the device launches a specific package after reboot.
Typical scenarios:
- Inspection, security, or industrial single-purpose apps.
- The device should enter the business page immediately after boot.
- Users should not manually start the app from the launcher.
Configuration
Use reflection to call android.os.SystemProperties:
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)
}
}Set the current app as the boot target:
setSystemProp("persist.vendor.boot.pkg", packageName)After reboot, the system reads this property and starts the target app.
Recommendations
- Delay SDK initialization by 1–2 seconds after boot to avoid system services not being ready.
- Make sure the app has a clear launcher activity.
- If multiple apps set auto-start, the last written package name takes effect.
- This capability depends on system support. Verify it on the target system version.
2. Hardware key events
Supported events
Common broadcasts:
| Event | Action |
|---|---|
| Single click | com.rokid.glass3.action.button.CLICK |
| Double click | com.rokid.glass3.action.button.DOUBLE_CLICK |
| Button down | Use the current system ACTION_BUTTON_DOWN |
| Button up | Use the current system ACTION_BUTTON_UP |
Different system versions may expose additional actions. Use the definitions in the Demo MyApplication as the source of truth.
3. Intercept key events
Register a high-priority broadcast receiver, and call abortBroadcast() when the app needs to consume the event.
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")
}
}
}
}Register the receiver:
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. Long press
For long press detection, schedule work on ACTION_BUTTON_DOWN and cancel it on ACTION_BUTTON_UP.
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. Notes
- Use
priority > 0so the business receiver runs earlier. - Only ordered broadcasts can be intercepted with
abortBroadcast(). - Some system-reserved keys cannot be intercepted by apps.
- Long-pressing the middle ring button usually triggers
KEY_POWERfor screen on/off and cannot be intercepted by app code. - Key behavior may vary by system version. Verify on the target system before release.