Compare commits

...
Author SHA1 Message Date
duffyduck 8b84ee3b9c release(agent): bump to 0.0.0.5 2026-09-24 21:44:05 +02:00
duffyduckandClaude Opus 4.8 c86cd59b5c fix(android-agent): Screenshot — Vordergrund-Dienst-Typ mediaProjection
Geraet (Android 12) meldete beim Projizieren:
'Media projections require a foreground service ...
FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION'. Der Dienst lief als reiner dataSync.
Fix: foregroundServiceType=dataSync|mediaProjection + Permissions
FOREGROUND_SERVICE_MEDIA_PROJECTION/-DATA_SYNC; beim Projektions-Start
startForeground(..., MEDIA_PROJECTION|DATA_SYNC) VOR getMediaProjection().
Normale Starts nutzen explizit nur dataSync (Android-14-konform). Version 0.0.0.5.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-24 21:42:23 +02:00
4 changed files with 37 additions and 8 deletions
+2 -2
View File
@@ -11,8 +11,8 @@ android {
applicationId 'de.hackersoft.ariaagent'
minSdk 26
targetSdk 33 // 33 vermeidet die Foreground-Service-Typ-Pflicht von 34
versionCode 4
versionName '0.0.0.4'
versionCode 5
versionName '0.0.0.5'
}
// Fester Signaturschlüssel: jeder Build signiert mit DEMSELBEN Key, damit
@@ -3,6 +3,8 @@
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MEDIA_PROJECTION" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_DATA_SYNC" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.CAMERA" />
@@ -30,7 +32,7 @@
<service
android:name=".AgentService"
android:exported="false"
android:foregroundServiceType="dataSync" />
android:foregroundServiceType="dataSync|mediaProjection" />
<receiver
android:name=".BootReceiver"
@@ -7,6 +7,7 @@ import android.app.PendingIntent
import android.app.Service
import android.content.Context
import android.content.Intent
import android.content.pm.ServiceInfo
import android.os.Build
import android.os.IBinder
import androidx.core.app.NotificationCompat
@@ -43,7 +44,19 @@ class AgentService : Service() {
override fun onCreate() {
super.onCreate()
createChannel()
startForeground(NOTIF_ID, buildNotification("startet …"))
startForegroundDataSync("startet …")
}
/** Normaler Vordergrund-Start (Typ dataSync). mediaProjection wird NUR beim
* Projizieren gesetzt — auf Android 14 darf man diesen Typ sonst nicht ohne
* Projection-Token verwenden. */
private fun startForegroundDataSync(text: String) {
if (Build.VERSION.SDK_INT >= 29) {
startForeground(NOTIF_ID, buildNotification(text),
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC)
} else {
startForeground(NOTIF_ID, buildNotification(text))
}
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
@@ -52,7 +65,7 @@ class AgentService : Service() {
// (ForegroundServiceDidNotStartInTimeException). Der Projection-Intent kommt
// per startForegroundService, obwohl der Dienst schon laeuft -> hier IMMER
// zuerst startForeground aufrufen (idempotent).
startForeground(NOTIF_ID, buildNotification(status))
startForegroundDataSync(status)
if (intent?.action == ACTION_PROJECTION) {
val code = intent.getIntExtra(EXTRA_RESULT_CODE, 0)
@@ -60,10 +73,24 @@ class AgentService : Service() {
val data = intent.getParcelableExtra<Intent>(EXTRA_RESULT_DATA)
if (code != 0 && data != null) {
try {
// Android verlangt beim Projizieren einen Vordergrund-Dienst vom
// Typ mediaProjection — VOR getMediaProjection() setzen, sonst
// SecurityException (FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION).
if (Build.VERSION.SDK_INT >= 29) {
startForeground(
NOTIF_ID, buildNotification("Bildschirm-Zugriff aktiv"),
ServiceInfo.FOREGROUND_SERVICE_TYPE_MEDIA_PROJECTION or
ServiceInfo.FOREGROUND_SERVICE_TYPE_DATA_SYNC,
)
}
ScreenCapturer.start(applicationContext, code, data)
updateNotification("$status · Bildschirm-Zugriff aktiv")
if (ScreenCapturer.active) {
updateNotification("$status · Bildschirm-Zugriff aktiv")
} else {
updateNotification("Bildschirm-Fehler: ${ScreenCapturer.lastError}")
}
} catch (e: Throwable) {
ScreenCapturer.lastError = e.message ?: e.javaClass.simpleName
ScreenCapturer.lastError = "${e.javaClass.simpleName}: ${e.message}"
updateNotification("Bildschirm-Fehler: ${ScreenCapturer.lastError}")
}
}
+1 -1
View File
@@ -162,7 +162,7 @@ OUT_MAX_CHARS_HARD = int(os.environ.get("OUT_MAX_CHARS_HARD", "200000") or "2000
FILE_MAX_BYTES = int(os.environ.get("FILE_MAX_BYTES", str(10 * 1024 * 1024)) or str(10 * 1024 * 1024))
# Version (wird von release_agent.sh beim Release gesetzt).
AGENT_VERSION = "0.0.0.4"
AGENT_VERSION = "0.0.0.5"
HEARTBEAT_SEC = 25
CAPS = ["exec", "read", "write", "info", "screenshot"]