# 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`:

```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)
    }
}
```

Set the current app as the boot target:

```kotlin
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.

```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")
            }
        }
    }
}
```

Register the receiver:

```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. Long press

For long press detection, schedule work on `ACTION_BUTTON_DOWN` and cancel it on `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. Notes

- Use `priority > 0` so 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_POWER` for screen on/off and cannot be intercepted by app code.
- Key behavior may vary by system version. Verify on the target system before release.
