diff --git a/app/src/main/java/com/zhousl/aether/termux/TermuxBashTool.kt b/app/src/main/java/com/zhousl/aether/termux/TermuxBashTool.kt index e0fa62b3..ce1eb692 100644 --- a/app/src/main/java/com/zhousl/aether/termux/TermuxBashTool.kt +++ b/app/src/main/java/com/zhousl/aether/termux/TermuxBashTool.kt @@ -608,13 +608,14 @@ class TermuxBashTool( ): String { val executionId = TermuxPendingResults.nextExecutionId() val deferred = TermuxPendingResults.register(executionId) - val resultIntent = Intent(context, TermuxResultReceiver::class.java) + val appContext = context.applicationContext + val resultIntent = Intent(appContext, TermuxResultReceiver::class.java) .putExtra(TermuxContract.ExecutionIdExtra, executionId) val flags = PendingIntent.FLAG_ONE_SHOT or PendingIntent.FLAG_UPDATE_CURRENT or if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) PendingIntent.FLAG_MUTABLE else 0 val pendingIntent = PendingIntent.getBroadcast( - context, + appContext, executionId, resultIntent, flags, @@ -643,7 +644,7 @@ class TermuxBashTool( } return try { - val startResult = context.startService(request) + val startResult = startTermuxRunCommandService(request) if (startResult == null) { TermuxPendingResults.remove(executionId) logTermux( @@ -709,6 +710,15 @@ class TermuxBashTool( } } + private fun startTermuxRunCommandService(request: Intent): ComponentName? { + return try { + context.startForegroundService(request) + } catch (throwable: Throwable) { + logTermux("foreground service start failed message=${throwable.message.orEmpty()}") + context.startService(request) + } + } + @Suppress("DEPRECATION") private fun isTermuxInstalled(): Boolean = runCatching { context.packageManager.getPackageInfo(TermuxContract.PackageName, 0) diff --git a/app/src/main/java/com/zhousl/aether/termux/TermuxResultReceiver.kt b/app/src/main/java/com/zhousl/aether/termux/TermuxResultReceiver.kt index 4173e4c0..b64f1215 100644 --- a/app/src/main/java/com/zhousl/aether/termux/TermuxResultReceiver.kt +++ b/app/src/main/java/com/zhousl/aether/termux/TermuxResultReceiver.kt @@ -10,21 +10,26 @@ class TermuxResultReceiver : BroadcastReceiver() { context: Context, intent: Intent, ) { - val executionId = intent.getIntExtra(TermuxContract.ExecutionIdExtra, -1) - if (executionId < 0) return + val pendingResult = goAsync() + try { + val executionId = intent.getIntExtra(TermuxContract.ExecutionIdExtra, -1) + if (executionId < 0) return - val resultBundle = intent.extras?.getBundle(TermuxContract.ResultBundleExtra) - ?: intent.extras?.findFirstBundle() + val resultBundle = intent.extras?.getBundle(TermuxContract.ResultBundleExtra) + ?: intent.extras?.findFirstBundle() - val result = TermuxCommandResult( - stdout = resultBundle?.getString(TermuxContract.ResultStdoutExtra).orEmpty(), - stderr = resultBundle?.getString(TermuxContract.ResultStderrExtra).orEmpty(), - exitCode = resultBundle?.getInt(TermuxContract.ResultExitCodeExtra, -1) ?: -1, - err = resultBundle?.getInt(TermuxContract.ResultErrExtra, -1) ?: -1, - errmsg = resultBundle?.getString(TermuxContract.ResultErrmsgExtra).orEmpty(), - ) + val result = TermuxCommandResult( + stdout = resultBundle?.getString(TermuxContract.ResultStdoutExtra).orEmpty(), + stderr = resultBundle?.getString(TermuxContract.ResultStderrExtra).orEmpty(), + exitCode = resultBundle?.getInt(TermuxContract.ResultExitCodeExtra, -1) ?: -1, + err = resultBundle?.getInt(TermuxContract.ResultErrExtra, -1) ?: -1, + errmsg = resultBundle?.getString(TermuxContract.ResultErrmsgExtra).orEmpty(), + ) - TermuxPendingResults.complete(executionId, result) + TermuxPendingResults.complete(executionId, result) + } finally { + pendingResult.finish() + } } }