You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何集成Kotlin应用与终端?Android应用执行终端命令可行吗?

问题1:Kotlin应用与控制台/终端集成

这里分两种常见场景实现集成:

1.1 基础控制台交互(读取输入/输出)

Kotlin JVM程序可直接通过标准IO API和控制台交互:

  • 输出内容到控制台:使用println()或print()函数
  • 读取控制台输入:使用readLine()函数,返回String?类型,需处理空值情况

示例代码:

fun main() {
    print("请输入你的名字:")
    val name = readLine() ?: "匿名用户"
    println("你好,$name!")
}

1.2 调用系统终端执行命令

若需在Kotlin程序中调用系统终端执行命令(如Windows的cmd、Linux/macOS的bash),推荐用ProcessBuilder实现,比Runtime.getRuntime().exec()更灵活:

Windows系统调用cmd命令示例

fun main() {
    val command = listOf("cmd.exe", "/c", "dir") // /c参数表示执行后关闭cmd窗口
    val process = ProcessBuilder(command)
        .redirectErrorStream(true) // 合并错误输出与标准输出
        .start()

    // 读取命令执行结果
    val result = process.inputStream.bufferedReader().readText()
    println("命令执行结果:\n$result")

    // 等待命令执行完成,获取退出码
    val exitCode = process.waitFor()
    println("命令退出码:$exitCode")
}

Linux/macOS系统调用bash命令示例

fun main() {
    val command = listOf("/bin/bash", "-c", "ls -l")
    val process = ProcessBuilder(command)
        .redirectErrorStream(true)
        .start()

    val result = process.inputStream.bufferedReader().readText()
    println("命令执行结果:\n$result")

    val exitCode = process.waitFor()
    println("命令退出码:$exitCode")
}

问题2:Android应用中执行终端命令(替代cmd/powershell)

首先明确:Android基于Linux内核,没有Windows的cmd或PowerShell,但可执行Linux Shell命令(如mkdir、ls等)。只要应用具备足够权限,就能通过应用传递命令执行操作,具体步骤如下:

步骤1:添加必要权限

根据操作需求,在AndroidManifest.xml中添加对应权限:

<!-- Android 10及以下需存储权限 -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<!-- Android 11+ 访问公共目录需MANAGE_EXTERNAL_STORAGE权限,需用户手动授权 -->
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
    tools:ignore="ScopedStorage" />

注:Android 6.0及以上,危险权限需动态申请(如存储权限)。

步骤2:实现Shell命令执行工具类

创建工具类封装命令执行逻辑,处理输入输出:

object ShellCommandExecutor {
    // 执行普通Shell命令,返回结果与退出码
    fun executeCommand(command: String): Pair<String, Int> {
        val process = Runtime.getRuntime().exec(command)
        val output = process.inputStream.bufferedReader().readText()
        val errorOutput = process.errorStream.bufferedReader().readText()
        val exitCode = process.waitFor()
        val result = if (errorOutput.isNotEmpty()) "$output\n错误信息:$errorOutput" else output
        return Pair(result, exitCode)
    }

    // 执行需root权限的命令(设备需已root)
    fun executeRootCommand(command: String): Pair<String, Int> {
        val process = Runtime.getRuntime().exec(arrayOf("su", "-c", command))
        val output = process.inputStream.bufferedReader().readText()
        val errorOutput = process.errorStream.bufferedReader().readText()
        val exitCode = process.waitFor()
        val result = if (errorOutput.isNotEmpty()) "$output\n错误信息:$errorOutput" else output
        return Pair(result, exitCode)
    }
}

步骤3:在Activity中调用工具类执行命令

以创建目录为例,在Activity中处理权限并调用工具类:

class MainActivity : AppCompatActivity() {
    private val REQUEST_STORAGE_PERMISSION = 1001

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        findViewById<Button>(R.id.btn_create_dir).setOnClickListener {
            if (checkStoragePermission()) {
                createDirectory()
            } else {
                requestStoragePermission()
            }
        }
    }

    private fun checkStoragePermission(): Boolean {
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            Environment.isExternalStorageManager()
        } else {
            ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
        }
    }

    private fun requestStoragePermission() {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            val intent = Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION)
            intent.data = Uri.parse("package:$packageName")
            startActivityForResult(intent, REQUEST_STORAGE_PERMISSION)
        } else {
            ActivityCompat.requestPermissions(
                this,
                arrayOf(Manifest.permission.WRITE_EXTERNAL_STORAGE),
                REQUEST_STORAGE_PERMISSION
            )
        }
    }

    private fun createDirectory() {
        // 在外部存储根目录创建TestDir文件夹
        val command = "mkdir ${Environment.getExternalStorageDirectory().absolutePath}/TestDir"
        val (result, exitCode) = ShellCommandExecutor.executeCommand(command)
        Toast.makeText(this, "退出码:$exitCode\n结果:$result", Toast.LENGTH_LONG).show()
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_STORAGE_PERMISSION && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
            if (Environment.isExternalStorageManager()) {
                createDirectory()
            } else {
                Toast.makeText(this, "需授权存储权限才能执行操作", Toast.LENGTH_SHORT).show()
            }
        }
    }

    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        super.onRequestPermissionsResult(requestCode, permissions, grantResults)
        if (requestCode == REQUEST_STORAGE_PERMISSION) {
            if (grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                createDirectory()
            } else {
                Toast.makeText(this, "需授权存储权限才能执行操作", Toast.LENGTH_SHORT).show()
            }
        }
    }
}

注意事项

  1. Android 10及以上启用分区存储,默认仅允许访问应用私有目录,访问公共目录需申请MANAGE_EXTERNAL_STORAGE权限并引导用户手动开启。
  2. 修改系统目录等操作需root权限,且设备必须已root。
  3. 执行命令时需验证输入,避免注入风险,建议用数组形式传递命令与参数(如exec(arrayOf("mkdir", path)))。

内容的提问来源于stack exchange,提问作者ivar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 10:44:52