3

我正在尝试在新的 BlackBerry 10 设备 (Z10) 中运行 phonegap 应用程序,但遇到了问题。基本上,我拍了一张照片,我想通过 FileTransfer 将它上传到我的服务器,但是 FileTransfer 失败并出现 FileTransferError.FILE_NOT_FOUND_ERR。

然后我尝试使用 window.resolveLocalFileSystemURI 方法,现在我得到一个 FileError.NOT_FOUND_ERR。我假设这两个错误是相关的。

我传递给这两个的 fileURI 是我从 navigator.camera.getPicture 成功回调中返回的 fileURI,看起来像:

file:///accounts/1000/shared/camera/IMG_00000037.jpg

我从 phonegap 2.5.0 下载中获取了示例 blackberry 应用程序,并稍微修改了 index.html 以重现该问题,我将包括以下内容:

<!DOCTYPE html>
<!--
    Licensed to the Apache Software Foundation (ASF) under one
    or more contributor license agreements.  See the NOTICE file
    distributed with this work for additional information
    regarding copyright ownership.  The ASF licenses this file
    to you under the Apache License, Version 2.0 (the
    "License"); you may not use this file except in compliance
    with the License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

    Unless required by applicable law or agreed to in writing,
    software distributed under the License is distributed on an
    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
     KIND, either express or implied.  See the License for the
    specific language governing permissions and limitations
    under the License.
-->
<html>
    <head>      
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
        <meta name="format-detection" content="telephone=no" />
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width, height=device-height, target-densitydpi=device-dpi" />
        <title>Hello World</title>

        <script type="text/javascript" charset="utf-8">

        // Called when a photo is successfully retrieved
        //
        function onPhotoURISuccess(imageURI, testFunction) {
            // Uncomment to view the image file URI 
            console.log(imageURI);

            // Get image handle
            //
            var image = document.getElementById('image');

            // Unhide image elements
            //
            image.style.display = 'block';

            // Show the captured photo
            // The inline CSS rules are used to resize the image
            //
            image.src = imageURI;

            // Run our test function
            testFunction(imageURI);
        }

        // Called if something bad happens.
        // 
        function onPhotoURIFail(message) {
            alert('Failed because: ' + message);
        }

        // A button will call this function
        //
        function getPhoto(source, testFunction) {
            // un-sandbox file system to access shared folder
            blackberry.io.sandbox = false;

            // Retrieve image file location from specified source
            navigator.camera.getPicture(
                function(imageURI) {
                    onPhotoURISuccess(imageURI, testFunction);
                },
                onPhotoURIFail,
                {
                    quality: 50,
                    destinationType: Camera.DestinationType.FILE_URI,
                    sourceType: source,
                    correctOrientation: true,
                    saveToPhotoAlbum: true
                }
            );
        }

        // Tests whether we can resolve the imageURI returned from navigator.camera.getPicture
        //
        function testResolveLocalFileSystemURI(imageURI) {
            window.resolveLocalFileSystemURI(
                imageURI,
                function (fileEntry) {
                    var message = "Resolved local file system URI: " + imageURI;
                    document.getElementById("span").innerHTML = message;
                    console.debug(message);
                    console.debug(fileInfo);
                },
                function (error) {
                    var message = "Unable to resolve local file system URI: " + imageURI + " error: " + error.code;
                    document.getElementById("span").innerHTML = message;
                    console.error(message);
                    console.debug(error);
                    console.debug("resolve error source " + error.source);
                    console.debug("resolve error target " + error.target);
                }
            );
        }

        // Tests whether we can upload the imageURI returned from navigator.camera.getPicture using a FileTransfer
        //
        function testFileTransferUpload(imageURI) {

            // Create =the file upload options
            var options = new FileUploadOptions();
            options.fileKey="file";
            options.fileName=imageURI.substr(imageURI.lastIndexOf('/')+1);
            options.mimeType="image/jpeg";

            // Create the file transfer and upload
            var ft = new FileTransfer();
            ft.upload(
                imageURI,
                encodeURI("http://some.server.com/upload.php"),
                function (r) {
                    var message = "Code: '" + r.responseCode + "'' Response: '" + r.response + "'' Sent: '" + r.bytesSent + "'";
                    document.getElementById("span").innerHTML = message;
                    console.debug(message);
                },
                function (error) {
                    var message = "Unable to upload: " + imageURI + " error: " + error.code;
                    document.getElementById("span").innerHTML = message;
                    console.error(message);
                    console.debug(error);
                    console.debug("upload error source " + error.source);
                    console.debug("upload error target " + error.target);
                },
                options
            );
        }

        // Tests whether we can upload the imageURI returned from navigator.camera.getPicture using a FileTransfer
        //
        function testFileSystemGetFile(imageURI) {
            window.requestFileSystem(
                LocalFileSystem.PERSISTENT,
                0,
                function (fileSystem) {
                    fileSystem.root.getFile(
                        imageURI,
                        {create: false},
                        function (fileEntry) {
                            var message = "Got file: " + imageURI;
                            document.getElementById("span").innerHTML = message;
                            console.debug(message);
                            console.debug(fileInfo);
                        },
                        function (error) {
                            var message = "Unable to get file: " + imageURI + " error: " + error.code;
                            document.getElementById("span").innerHTML = message;
                            console.error(message);
                            console.debug(error);
                            console.debug("get file error source " + error.source);
                            console.debug("get file error target " + error.target);
                        }
                    );
                },
                function (error) {
                    var message = "Unable to get file system. error: " + error.code;
                    document.getElementById("span").innerHTML = message;
                    console.error(message);
                    console.debug(error);
                    console.debug("file system error source " + error.source);
                    console.debug("file system error target " + error.target);
                }
            );
        }
        </script>

    </head>
    <body>
        <script type="text/javascript" src="cordova-2.5.0.js"></script>
        <button onclick="getPhoto(Camera.PictureSourceType.CAMERA, testResolveLocalFileSystemURI);">Capture Photo, Test Resolve Local File System URI</button> <br>
        <button onclick="getPhoto(Camera.PictureSourceType.CAMERA, testFileTransferUpload);">Capture Photo, Test File Transfer Upload</button> <br>
        <button onclick="getPhoto(Camera.PictureSourceType.CAMERA, testFileSystemGetFile);">Capture Photo, Test File System Get File</button> <br>
        <img style="display:none;" id="image" width="100" height="100" src="" />
        <span id="span"></span>
    </body>
</html>

每当我运行应用程序并尝试拍照时,我都会得到:

Unable to resolve local file system URI...

为什么 FileTransfer 或 window.resolveLocalFileSystemURI 都找不到从 navigator.camera.getPicture 返回的文件?我有来自 phonegap 示例的标准 config.xml 具有所有必需的功能和权限(至少据我所知)

下面是我的 config.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
-->
<!--
  Widget Configuration Reference:
    http://docs.blackberry.com/en/developers/deliverables/15274/
-->

<widget xmlns="http://www.w3.org/ns/widgets"
        xmlns:rim="http://www.blackberry.com/ns/widgets"
    version="1.0.0.0" id="org.apache.cordova.example">

  <name>cordovaExample</name>

  <author>Your Name Here</author>

  <description>
       A sample Apache Cordova application that responds to the deviceready event.
  </description>

  <license href="http://opensource.org/licenses/alphabetical">
  </license>

  <!-- Cordova API -->
  <feature id="blackberry.system" required="true" version="1.0.0.0" />
  <feature id="org.apache.cordova" required="true" version="1.0.0" />
  <feature id="blackberry.find" required="true" version="1.0.0.0" />
  <feature id="blackberry.identity" required="true" version="1.0.0.0" />
  <feature id="blackberry.identity.phone" required="true" version="1.0.0.0" />
  <feature id="blackberry.pim.Address" required="true" version="1.0.0.0" />
  <feature id="blackberry.pim.Contact" required="true" version="1.0.0.0" />
  <feature id="blackberry.io.file" required="true" version="1.0.0.0" />
  <feature id="blackberry.utils" required="true" version="1.0.0.0" />
  <feature id="blackberry.io.dir" required="true" version="1.0.0.0" />
  <feature id="blackberry.app" required="true" version="1.0.0.0" />
  <feature id="blackberry.app.event" required="true" version="1.0.0.0" />
  <feature id="blackberry.system.event" required="true" version="1.0.0.0"/>
  <feature id="blackberry.widgetcache" required="true" version="1.0.0.0"/>
  <feature id="blackberry.media.camera" />
  <feature id="blackberry.ui.dialog" />
  <feature id="blackberry.connection" />
  <feature id="blackberry.bbm.platform" />
  <feature id="blackberry.invoke.card" />
  <feature id="blackberry.pim.contacts" />
  <feature id="blackberry.ui.contextmenu" />
  <feature id="blackberry.io.filetransfer" />
  <feature id="blackberry.io" />
  <feature id="blackberry.invoke" />
  <feature id="blackberry.invoked" />
  <feature id="blackberry.push" />
  <feature id="blackberry.media.microphone" required="true" version="1.0.0.0"/>

  <!-- Cordova API -->
  <access subdomains="true" uri="file:///store/home" />
  <access subdomains="true" uri="file:///SDCard" />
  <access subdomains="true" uri="file:///accounts" />

  <!-- Expose access to all URIs, including the file and http protocols -->
  <access subdomains="true" uri="*" />

  <icon rim:hover="false" src="res/icon/blackberry/icon-80.png" />
  <icon rim:hover="true" src="res/icon/blackberry/icon-80.png" />

  <rim:loadingScreen backgroundColor="#CFCFCF"
                     foregroundImage="res/screen/blackberry/screen-225.png"
             onFirstLaunch="true">
    <rim:transitionEffect type="fadeOut" />
  </rim:loadingScreen>

  <content src="index.html" />

  <rim:permissions>
    <rim:permit>use_camera</rim:permit>
    <rim:permit>read_device_identifying_information</rim:permit>
    <rim:permit>access_shared</rim:permit>
    <rim:permit>read_geolocation</rim:permit>
    <rim:permit>record_audio</rim:permit> 
    <rim:permit>access_pimdomain_contacts</rim:permit> 
  </rim:permissions>

</widget>

下面是我的 plugins.xml:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
       Licensed to the Apache Software Foundation (ASF) under one
       or more contributor license agreements.  See the NOTICE file
       distributed with this work for additional information
       regarding copyright ownership.  The ASF licenses this file
       to you under the Apache License, Version 2.0 (the
       "License"); you may not use this file except in compliance
       with the License.  You may obtain a copy of the License at

         http://www.apache.org/licenses/LICENSE-2.0

       Unless required by applicable law or agreed to in writing,
       software distributed under the License is distributed on an
       "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
       KIND, either express or implied.  See the License for the
       specific language governing permissions and limitations
       under the License.
-->
<plugins>
  <plugin name="App"            value="org.apache.cordova.app.App"/>
  <plugin name="Device"         value="org.apache.cordova.device.Device"/>
  <plugin name="Camera"         value="org.apache.cordova.camera.Camera"/>
  <plugin name="NetworkStatus"  value="org.apache.cordova.network.Network"/>
  <plugin name="Notification"   value="org.apache.cordova.notification.Notification"/>
  <plugin name="Accelerometer"  value="org.apache.cordova.accelerometer.Accelerometer"/>
  <plugin name="Geolocation"    value="org.apache.cordova.geolocation.Geolocation"/>
  <plugin name="File"           value="org.apache.cordova.file.FileManager"/>
  <plugin name="FileTransfer"   value="org.apache.cordova.http.FileTransfer"/>
  <plugin name="Contacts"       value="org.apache.cordova.pim.Contact"/>
  <plugin name="Capture"        value="org.apache.cordova.capture.MediaCapture"/>
  <plugin name="Battery"        value="org.apache.cordova.battery.Battery"/>
  <plugin name="Media"          value="org.apache.cordova.media.Media"/>
  <plugin name="Globalization"  value="org.apache.cordova.globalization.Globalization"/>
</plugins>

重现我的问题的步骤:

  1. 遵循指南(使用 BlackBerry 10(QNX) 步骤)
  2. 用我提供的文件替换给定的 index.html 文件
  3. 用我提供的文件替换给定的 config.xml 文件(更改应该是最小的)
  4. 在 BB10 设备上调试它(我使用的是 Z10)
  5. 单击“捕获照片”按钮,如果您连接了远程 Web 检查器,您应该会看到错误
4

6 回答 6

2

您需要同时blackberry.io.sandbox = false;删除 file:// 协议,至少根据我从文件系统访问文件的经验。此外,您不应该直接访问共享路径。使用 blackberry.io.sharedFolder 属性,如本页示例所示:https ://developer.blackberry.com/html5/apis/blackberry.io.html

您的文件系统路径应该是 blackberry.io.sharedFolder + 'camera/IMG_00000037.jpg'

BB10 的安全沙盒设计意味着每个应用程序都有自己的文件路径到共享文件系统区域。

于 2013-04-08T16:09:23.053 回答
1

听起来很像我在这里看到的问题:https ://github.com/blackberry/BB10-WebWorks-Framework/issues/536

尝试删除file://协议以获取:/accounts/1000/shared/camera/IMG_00000037.jpg

于 2013-04-03T22:07:22.580 回答
0

您可能想尝试添加,<access uri="file://accounts/" subdomains="ture"/>以代替“商店/家”。

编辑:此外,在处理文件系统时,您需要将沙盒模式设置为 false,否则您可能无法访问所述文件。

blackberry.io.sandbox = false;

除此之外,看起来你几乎所有的设置都很好。

于 2013-04-02T14:26:02.527 回答
0

相信我这个来源解决的问题:

<html>
<head>
<script type="text/javascript" src="local:///chrome/webworks.js"></script>
<script type="text/javascript">

function log(e) {
    console.log(e);
}

function takePicture(success) {
    blackberry.invoke.card.invokeCamera('photo', function (path) {
        success(path);
    }, log, log);
}

function openFile (filePath, success) {
    window.webkitRequestFileSystem(window.PERSISTENT, 1024*1024*1024, function (fs) {
        fs.root.getFile(filePath, {}, function (entry) {
            success(entry);
        }, log);
    }, log);
}

function uploadFile (entry, server, success) {
    entry.file(function (file) {
        var fd = new FormData(),
            xhr;
        fd.append("picture", file);
        xhr = new XMLHttpRequest();
        xhr.open("POST", server);
        xhr.onload = function (evt) {
            if (xhr.status == 200) {
                success(xhr.response);
            } else {
                log(xhr);
            }
        };
        xhr.ontimeout = log;
        xhr.onerror = log;
        xhr.send(fd);
    }, log);
}

function start() {
    takePicture(function (filePath) {
        openFile(filePath, function (entry) {
            uploadFile(entry, "http://cordova-filetransfer.jitsu.com/upload", function () {
                alert("SUCCESS");
            });
        });
    });
}

document.addEventListener('webworksready', function () {
    blackberry.io.sandbox = false;
    document.getElementById("startButton").disabled = "";
});

</script>
</head>
<body>
<h1>Camera XHR Upload Sample</h1>
<button id="startButton" disabled="disabled"  onclick="start();">Start</button>
</body>
</html>
于 2013-09-06T13:00:00.887 回答
0

根据 2013 年 4 月 2 日的 chadtatro 回答:

请在 config.xml 中添加

<access uri="file:///accounts/1000/removable/sdcard/" subdomains="true"/>

我还添加到我的项目中:

webworks plugin add com.blackberry.io
于 2014-05-01T10:43:12.493 回答
0

几天以来我遇到了同样的问题。获取图像停止工作,并且我的代码中没有任何内容发生变化。

注意cordova-plugin-file,因为在它的3.0.1-dev版本中(可能还有其他版本),您开发的应用程序不会请求访问文件的权限,并且从相机或图库中获取图片将失败。

我使用2.1.0这个插件的版本解决了它:

cordova plugin add https://git-wip-us.apache.org/repos/asf/cordova-plugin-file.git#r2.1.0
于 2015-08-26T08:31:33.510 回答