通过 HTML5 在 Android 上使用二进制字符串保存文件

Save file using binary string on Android via HTML5

我正在与一个三人小团队合作开发我的应用程序,但我们遇到了困难。

我们正在使用 JSZip and FileSaver 为我们的代码编辑器应用程序保存文件。它在浏览器中运行良好,但当我将它与 PhoneGap 一起用作本机 Android 应用程序时,它不会写入。

zip.js library and even saving single files with the FileSaver.js 库仍然会出现此问题。

$('.savemd').click ->
  blob = new Blob([ mdEditor.getValue() ], type: 'text/x-markdown')
  saveAs blob, 'source.md'

我尝试使用 PhoneGap 的 FileWriter object, but later I found that it's currently impossible to write binary data with Phonegap's FileWriter - source - source

然而 post 已经有几年了。

我也试过让它与本机 WebView 一起使用并使用 Crosswalk Project 但仍然没有成功。

我们也试过...

function saveFile(fileName, fileData) {
  // Get access to the file system
  window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, function (fileSystem) {
    // Create the file.
    fileSystem.root.getFile(fileName, { create: true, exclusive: false }, function (entry) {
      // After you save the file, you can access it with this URL
      myFileUrl = entry.toURL()
      entry.createWriter(function(writer) {
        writer.onwriteend = function(evt) {
          alert("Successfully saved file to " + myFileUrl)
        }
        // Write to the file
        writer.write(fileData)
      }, function(error) {
        alert("Error: Could not create file writer, " + error.code)
      })
    }, function(error) {
      alert("Error: Could not create file, " + error.code)
    })
  }, function(evt) {
    alert("Error: Could not access file system, " + evt.target.error.code)
  })
}

问题是它只保存到用户内存(无论是否插入 SD 卡,我们已经在所有 android 设备上进行了测试,但仍然无法正常工作,但请注意,我们不是使用任何已获得 root 权限的设备),并且不适用于 JSZip。

我们的团队在许多不同的操作系统(Mac、Android、Chromebook 的)上进行开发,因此目前需要 PhoneGap Build。

有谁知道有什么方法可以做到这一点?这被称为通过 HTML5 在 Android 上使用二进制字符串保存文件? (首选 PhoneGap 或 PhoneGap 构建答案)。

这是我们当前的 PhoneGap Build XML:

<?xml version="1.0" encoding="utf-8"?>
<widget xmlns = "http://www.w3.org/ns/widgets"
  xmlns:gap   = "http://phonegap.com/ns/1.0"
  id          = "com.save.test"
  version     = "1.0.0"
  versionCode = "1">
  <name>SaveTest</name>
  <description>
      Save file using a Binary string test on Android
  </description>
  <author email="mikethedj4@yahoo.com" href="http://mikethedj4.github.io/">
      Michael Schwartz
  </author>

  <content src="index.html" />

  <icon src="icon.png" gap:role="default" />
  <icon gap:platform="android" gap:qualifier="ldpi" src="res/icon/android/icon-36-ldpi.png" />
  <icon gap:platform="android" gap:qualifier="mdpi" src="res/icon/android/icon-48-mdpi.png" />
  <icon gap:platform="android" gap:qualifier="hdpi" src="res/icon/android/icon-72-hdpi.png" />
  <icon gap:platform="android" gap:qualifier="xhdpi" src="res/icon/android/icon-96-xhdpi.png" />
  <icon gap:platform="android" src="res/icon/android/icon-96-xhdpi.png" />
  <icon gap:platform="ios" height="57" src="res/icon/ios/icon-57.png" width="57" />
  <icon gap:platform="ios" height="72" src="res/icon/ios/icon-72.png" width="72" />
  <icon gap:platform="ios" height="114" src="res/icon/ios/icon-57-2x.png" width="114" />
  <icon gap:platform="ios" height="144" src="res/icon/ios/icon-72-2x.png" width="144" />
  <icon gap:platform="winphone" src="res/icon/windows-phone/icon-48.png" />
  <icon gap:platform="winphone" gap:role="background" src="res/icon/windows-phone/icon-173-tile.png" />

  <preference name="permissions" value="none"/>
  <!-- <plugin name="org.crosswalk.engine" spec="1.3.0" source="pgb" /> -->
  <!-- <plugin name="cordova-plugin-crosswalk-webview" source="npm" /> -->
  <plugin name="cordova-plugin-whitelist" source="npm" />
  <plugin name="cordova-plugin-device" source="npm" />
  <plugin name="cordova-plugin-file" source="npm" />
  <plugin name="cordova-plugin-file-transfer" source="npm" />
  <plugin name="cordova-plugin-chrome-apps-filesystem" source="npm" />
  <!-- <plugin name="cordova-connectivity-monitor" source="npm" /> -->
  <preference name="phonegap-version" value="cli-5.2.0" />

  <allow-intent href="http://*/*" />
  <allow-intent href="https://*/*" />
</widget>

$('.download').click(function () {
  eval($('#jszipdemo').val())
})
.fill {
  width: 100%;
  display: block;
}
<link rel='stylesheet prefetch' href='http://treehouse-code-samples.s3.amazonaws.com/poly/css/application.css'>

<div class='grid'>
  <div class='grid__col--12'>
    <p></p>
    <button class='btn--default download fill'>Run</button>
    <textarea class='form__input' id='jszipdemo' placeholder='Demo code here...' rows='7'>var zip = new JSZip();&#x000A;zip.file("Hello.txt", "Hello World");&#x000A;var folder = zip.folder("images");&#x000A;folder.file("folder.txt", "I'm a file in a new folder");&#x000A;var content = zip.generate({type:"blob"});&#x000A;// see FileSaver.js&#x000A;saveAs(content, "example.zip");</textarea>
  </div>
</div>

<script src='https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js'></script>
<script src='https://stuk.github.io/jszip/dist/jszip.js'></script>
<script src='https://stuk.github.io/jszip-utils/dist/jszip-utils.js'></script>
<script src='https://stuk.github.io/jszip/vendor/FileSaver.js'></script>

可以用FileWriter保存二进制数据,以前是不可能的,现在可以了。

以这种方式创建你的 blob :

var byteArray = new Uint8Array(fileContent.length);
for (var x = 0; x < byteArray.length; x++) {
    byteArray[x] = fileContent.charCodeAt(x) & 0xff
}

var blob = new Blob([byteArray], {
    type: 'application/octet-stream'
});

然后保存

fileWriter.write(blob);