android - 来自具有特殊字符的 macOS 应用程序的 ADB 命令

标签 android swift macos shell adb

我想通过我的 macOS 应用程序中的 adb 命令从我的 android 设备中提取文件。

以下代码一切正常,除非我要提取的文件的名称包含特殊字符,如德语变音符号 (äöüÄÖÜ)。

我得到这个错误: adb:错误:无法统计远程对象“/storage/emulated/0/Download/Böse”:没有这样的文件或目录

但是当我在 Terminal.app 中使用命令 adb pull/storage/emulated/0/Download/Böse ~/Desktop 时,文件将被拉取到我的电脑。

奇怪的是,如果我从 Xcode 控制台输出中复制子字符串 /storage/emulated/0/Download/Böse,该命令在 终端内也不起作用。 app,直到我从键盘输入中删除 ö 并将其替换为 ö

我尝试将 ö 替换为 unicode 表示 \u{00f6},但这没有任何效果(但控制台输出仍然显示 ö 但是“错误的”编码。

// Configure task.
let task = Process()
task.launchPath = "~/Library/Android/sdk/platform-tools/adb"
task.arguments = ["pull", "/storage/emulated/0/Download/Böse", "~/Desktop"]

// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
task.launch()

// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()

// adb: error: failed to stat remote object '/storage/emulated/0/Download/Böse': No such file or directory
print(output)

我在文档中找到以下内容,Process 如何处理我提供的参数:

The NSTask object converts both path and the strings in arguments to appropriate C-style strings (using fileSystemRepresentation) before passing them to the task via argv[] . The strings in arguments do not undergo shell expansion, so you do not need to do special quoting, and shell variables, such as $PWD, are not resolved.

看来我不是唯一遇到这个问题的人,我找到了这个解决方法: How to work around NSTask calling -[NSString fileSystemRepresentation] for arguments , 但我无法让它与 Swift 一起工作。

最佳答案

作为解决方法,我现在将我的 adb 命令写入一个文件并从我的应用程序中的 bash 命令执行它。

let source = "/storage/emulated/0/Download/Böse"
let destination = "~/Desktop"
guard let uniqueURL = URL(string: destination + "/" + ProcessInfo.processInfo.globallyUniqueString) else { return }

// Write command to file
let scriptContent = "#!/bin/bash\n~/Library/Android/sdk/platform-tools/adb pull -a \"" + source + "\" \"" + destination + "\""
try? scriptContent.write(to: uniqueURL, atomically: false, encoding: .utf8)

// Configure task.
let task = Process()
task.environment = ["LC_ALL": "de_DE.UTF-8", "LANG": "de_DE.UTF-8"]
task.launchPath = "/bin/bash"
task.arguments = [uniqueURL.path]

// Configure pipe.
let pipe = Pipe()
task.standardOutput = pipe
task.standardError = pipe
try? task.run()

// Run task.
let data = pipe.fileHandleForReading.readDataToEndOfFile()
let output = String(data: data, encoding: .utf8)
task.waitUntilExit()

print(output)

尽管目前可行,但它不是一个令人满意的解决方案,因为它不是很优雅且效率也不高,因此欢迎任何改进或更好的答案。

关于android - 来自具有特殊字符的 macOS 应用程序的 ADB 命令,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53049738/

相关文章:

c++ - Mac/IOS 是否使用与 Linux 内核相同的 sys/socket.h?

macos - Mac:在程序之间单击需要2次单击

objective-c - 向 NSTableView 添加行不会更改其框架

android - 带有 ExpandableListActivity 的窗口功能 FEATURE_LEFT_ICON 不起作用

安卓 WebView : CSS scale doesn't hide original

android - 如何清除URLSpan点击效果?

java - 尝试在空对象引用上调用虚拟方法 'boolean java.util.ArrayList.add(java.lang.Object)'

swift - 约束不断变化但布局没有更新?

swift - 如何删除 PDFDocument 边距

ios - 调用在类中初始化的字典数组