Skip to content
Back to skills

Android Development

ASecurity

Android development patterns for Kotlin/Java including MediaProjection, Accessibility Service, Socket.IO, and foreground services. Use when working on TitanMirror or other Android projects.

  • 33 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added February 10, 2026
developmentjavakotlin

Works with

  • cli

Security analysis

A100/100

Scanned February 12, 2026

npx -y skills add lovedragonball/power-ranger-toolkit --skill android-development --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Android Development?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Android Development
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/lovedragonball-android-development/badge)](https://www.skillsdirectory.com/skills/lovedragonball-android-development)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: android-development
description: Android development patterns for Kotlin/Java including MediaProjection, Accessibility Service, Socket.IO, and foreground services. Use when working on TitanMirror or other Android projects.
---

# 📱 Android Development Skill

## Use Cases
- Screen mirroring (MediaProjection)
- Remote control (Accessibility Service)
- Real-time communication (Socket.IO)
- Background services

---

## MediaProjection Setup

### 1. Request Permission
```kotlin
val mediaProjectionManager = getSystemService(MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
startActivityForResult(mediaProjectionManager.createScreenCaptureIntent(), REQUEST_CODE)
```

### 2. Create Projection
```kotlin
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
    if (requestCode == REQUEST_CODE && resultCode == RESULT_OK) {
        mediaProjection = mediaProjectionManager.getMediaProjection(resultCode, data!!)
        startCapture()
    }
}
```

### 3. ImageReader for Frames
```kotlin
val imageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 5)
imageReader.setOnImageAvailableListener({ reader ->
    val image = reader.acquireLatestImage()
    // Process frame...
    image?.close()
}, handler)
```

---

## Foreground Service (Android 14+)

> ⚠️ **CRITICAL**: Must call `startForeground()` immediately in `onStartCommand()`

```kotlin
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
    // FIRST: Start foreground immediately!
    val notification = createNotification()
    startForeground(NOTIFICATION_ID, notification, ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION)
    
    // THEN: Extract intent and start work
    val resultCode = intent?.getIntExtra("resultCode", -1) ?: -1
    val data = intent?.getParcelableExtra("data", Intent::class.java)
    
    // Add delay before capture
    Handler(Looper.getMainLooper()).postDelayed({
        startCapture(resultCode, data)
    }, 1500)
    
    return START_NOT_STICKY
}
```

---

## Socket.IO Connection

```kotlin
val socket = IO.socket("http://192.168.1.x:3000")

socket.on(Socket.EVENT_CONNECT) {
    Log.d("Socket", "Connected!")
    socket.emit("register", deviceInfo)
}

socket.on("command") { args ->
    val command = args[0] as JSONObject
    handleCommand(command)
}

socket.connect()
```

---

## Accessibility Service

```kotlin
class RemoteControlService : AccessibilityService() {
    
    override fun onAccessibilityEvent(event: AccessibilityEvent?) {
        // Handle accessibility events
    }
    
    fun performClick(x: Int, y: Int) {
        val path = Path().apply { moveTo(x.toFloat(), y.toFloat()) }
        val gesture = GestureDescription.Builder()
            .addStroke(GestureDescription.StrokeDescription(path, 0, 100))
            .build()
        dispatchGesture(gesture, null, null)
    }
    
    fun performSwipe(startX: Int, startY: Int, endX: Int, endY: Int) {
        val path = Path().apply {
            moveTo(startX.toFloat(), startY.toFloat())
            lineTo(endX.toFloat(), endY.toFloat())
        }
        val gesture = GestureDescription.Builder()
            .addStroke(GestureDescription.StrokeDescription(path, 0, 300))
            .build()
        dispatchGesture(gesture, null, null)
    }
}
```

---

## Decision Tree

```
Android task?
├── Screen capture? → MediaProjection + ImageReader
├── Background work? → Foreground Service (Android 14 rules!)
├── Remote control? → Accessibility Service
├── Network comm? → Socket.IO
└── Permissions? → Runtime request + Manifest
```

---

## Common Pitfalls

| ปัญหา | สาเหตุ | แก้ไข |
|-------|--------|-------|
| Black screen | startForeground timing | Call immediately in onStartCommand |
| Crash on Android 14 | Wrong intent extraction | Use `getParcelableExtra(key, Class)` |
| Low FPS | Buffer too small | Increase ImageReader buffer to 5 |
| Service killed | Not foreground | Add FOREGROUND_SERVICE permission |

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…