Search code examples
androidjvmbroadcastreceiveradbprocessbuilder

ProcessBuilder produces different output compared to terminal with the same command


I’m trying to send a broadcast command with ProcessBuilder. It “works”, but the output is different if I run the same command via terminal:

adb shell am broadcast -p com.sample -a sample.action -e "extra" "bla bla"

produces (correctly):

Broadcasting: Intent { act=sample.action flg=0x400000 pkg=com.sample (has extras) }
Broadcast completed: result=0

but the same command via ProcessBuilder produces:

Broadcasting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x400000 pkg= -p }
Broadcast completed: result=0

any idea why?

private fun String.runCommand(workingDir: File = File("."), timeoutAmount: Long = 60, timeoutUnit: TimeUnit = TimeUnit.SECONDS): String? {
    return try {
        runCatching {
            ProcessBuilder("\\s".toRegex().split(this))
                .directory(workingDir)
                .redirectOutput(ProcessBuilder.Redirect.PIPE)
                .redirectError(ProcessBuilder.Redirect.PIPE)
                .start()
                .also { it.waitFor(timeoutAmount, timeoutUnit) }
                .inputStream.bufferedReader().readText()
        }.onFailure { it.printStackTrace() }.getOrThrow()
    } catch (e: Exception) {
        e.message
    }
}

...  

val cmd = """
    adb shell am broadcast \
    -p $applicationId \
    -a $action \
    -${if (emulator) "e" else "d"} "extra" "'${payload.replace("\\s".toRegex(), "")}'"
""".trimIndent()

cmd.runCommand()

Solution

  • Replaced:

    val cmd = """
        adb shell am broadcast \
        -p $applicationId \
        -a $action \
        -${if (emulator) "e" else "d"} "extra" "'${payload.replace("\\s".toRegex(), "")}'"
    """.trimIndent()
    

    with:

    val cm "adb shell am broadcast -p $applicationId " +
            "-a $action +
            "-${if (emulator) "e" else "d"} " +
            "extra '${payload.replace("\\s".toRegex(), "")}'"