3

navigator.camera.getPicture 功能不起作用。它的回调函数永远不会在下面的代码中被触发。此功能来自科尔多瓦相机插件。

navigator.camera.getPicture(
                            uploadPhoto,
                            function(message) {
                                alert('Failed to get a picture. Please select one.');
                            }, {
                                quality         : 50,
                                destinationType : Camera.DestinationType.FILE_URI,
                                sourceType      : Camera.PictureSourceType.SAVEDPHOTOALBUM
                            });

在上面的代码中,uploadPhoto 回调函数永远不会被触发。调用上述函数时,chrome dev tools 控制台中没有它的痕迹,它打开文件选择窗口,选择要上传的图像后,它只是返回,然后屏幕刷新。

更新 6/26 经过更多测试后发现,这种行为在两种不同的 android 设备之间有所不同,一种是 Jelly bean 版本 4.4.2,另一种是 Jelly bean 版本 4.4.4。在运行 4.4.4 的设备中,navigator.camera.getPicture 被成功调用,但在文件传输中被击中。运行 Jelly bean 4.4.2 的设备刚刚在 navigator.camera.getPicture 失败,而没有调用它的成功或错误回调函数,这是我几天以来遇到的问题。看起来带有相机插件 2.2.0 的 cordova 5.1 不适用于 Jelly Bean 或其少数版本。也许我需要找到适用于果冻豆的科尔多瓦版本和科尔多瓦相机插件版本。

更新 6/25 将代码从 Telerik AppBuilder 迁移到 PhoneGap。PhoneGap 使用 Cordova 5.1 并配置了最新的 Camera Plugin 2.2.0,但问题仍然相同。不确定这个问题是否与这篇文章中的相同很有趣这个问题没有在发行说明中列出,我在不同的 android 版本中测试它没有工作。到目前为止,至少没有对 Telerik Premium 支持中提出的请求作出回应。

更新 6/23 1:28IST 正如 Devid 所建议的,按照这篇文章,我在调用 navigator.camera.getPicture 之前添加了以下推荐修复,问题仍然存在。

if (device.platform === 'Android') {
  setInterval(function () {
     cordova.exec(null, null, '', '', [])
  }, 200);
}

更新:6/23 我从 chrome://inspect 检查了控制台中的行为,在文件上传活动期间绝对没有任何痕迹。在网络选项卡中找不到此 http 请求。为了了解它在哪里停止运行,我在 uploadFile 函数中的每个阶段添加了 console.log,我注意到它没有触发 navigator.camera.getPicture 中的 uploadPhoto 回调函数,但是这个调用确实调用了文件选择器,但是在文件选择之后它的回调 uploadPhoto 函数没有触发。看起来该应用在设备上没有某些访问权限。

navigator.camera.getPicture(
    uploadPhoto,
    function(message) {
        rst.innerHTML = "Failed to get a picture. Please select one.";
    }, {
        quality         : 50,
        destinationType : navigator.camera.DestinationType.FILE_URI,
        sourceType      : navigator.camera.PictureSourceType.PHOTOLIBRARY
    });

如果有任何线索,这里是亚行的目录。

更新 2/24-9:15AMIST 下面是 Android 清单,我是否缺少任何权限?

<?xml version="1.0" encoding="utf-8"?>
<manifest android:versionCode="$AndroidVersionCode$"
          android:versionName="$BundleVersion$"
          package="$AppIdentifier$"
          android:windowSoftInputMode="adjustPan"
          android:hardwareAccelerated="$AndroidHardwareAcceleration$"
          xmlns:android="http://schemas.android.com/apk/res/android" >
    <supports-screens
        android:largeScreens="true"
        android:normalScreens="true"
        android:smallScreens="true"
        android:xlargeScreens="true"
        android:resizeable="true"
        android:anyDensity="true"
        />

    <application android:label="@string/app_name"
                 android:icon="@drawable/icon"
                 android:hardwareAccelerated="$AndroidHardwareAcceleration$"
                 android:debuggable="true" >
        <activity android:label="@string/app_name"
                  android:name=".TelerikCallbackActivity"
                  android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale"
                  android:launchMode="singleTop"
                  android:theme="@android:style/Theme.Black.NoTitleBar" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
    <uses-sdk android:minSdkVersion="14" android:targetSdkVersion="21"/>
    <uses-permission android:name="android.permission.INTERNET" />
</manifest>

下面的科尔多瓦文件上传代码在模拟器中完美运行,但在 Android 设备中部署时失败。

下面是config.xml

<widget xmlns     = "http://www.w3.org/ns/widgets"
        version   = "2.0.0">

    <content src="index.html" />

    <!-- Whitelist docs: https://github.com/apache/cordova-plugin-whitelist -->

    <!-- allow local pages -->
    <!-- <access origin="http://127.0.0.1*"/> -->
    <access origin="*" />

    <!-- Grant certain URLs the ability to launch external applications. This
         behaviour is set to match that of Cordova versions before 3.6.0, and
         should be reviewed before launching an application in production. It
         may be changed in the future. -->
    <allow-intent href="http://*/*" />
    <allow-intent href="https://*/*" />
    <allow-intent href="tel:*" />
    <allow-intent href="sms:*" />
    <allow-intent href="mailto:*" />
    <allow-intent href="geo:*" />
    <allow-intent href="market:*" />

    <preference name="loglevel" value="DEBUG" />
    <!--
      <preference name="splashscreen" value="splash" />
      <preference name="backgroundColor" value="0xFFF" />
      <preference name="loadUrlTimeoutValue" value="20000" />
      <preference name="InAppBrowserStorageEnabled" value="true" />
      <preference name="disallowOverscroll" value="true" />
    -->
</widget>

下面是客户端代码

uploadFile: function () {
    rst = document.getElementById(this.id + 'res');
    rst.innerHTML = "";
    var uploadTYPE = this.id;
    navigator.camera.getPicture(
        uploadPhoto,
        function(message) {
            rst.innerHTML = "Failed to get a picture. Please select one.";
        }, {
            quality         : 50,
            destinationType : navigator.camera.DestinationType.FILE_URI,
            sourceType      : navigator.camera.PictureSourceType.PHOTOLIBRARY
        });

    function uploadPhoto(fileURI) {
        var options = new FileUploadOptions();
        options.fileKey = "file";
        options.fileName = fileURI.substr(fileURI.lastIndexOf('/') + 1);

        if (cordova.platformId == "android") {
            options.fileName += ".jpg" 
        }

        options.mimeType = "image/jpeg";
        //options.httpMethod = "PUT";
        //options.contentType = 'multipart/form-data';
        var params = new Object();
        params.uid = localStorage.getItem("FOSCode");
        params.utyp = uploadTYPE;
        options.params = params; 

        options.headers = {
            Connection: "close"
        };
        //options.httpMethod = 'POST';
        options.chunkedMode = false;

        var ft = new FileTransfer();

        rst.innerHTML = "Upload in progress...";
        ft.upload(
            fileURI,
            encodeURI("https://www.kinrep.com/foster/upload.php"),
            onFileUploadSuccess,
            onFileTransferFail,
            options, true);

        function onFileUploadSuccess (result) {
           // rst.innerHTML = "Upload successful";
            console.log("FileTransfer.upload");
            console.log("Code = " + result.responseCode);
            console.log("Response = " + result.response);
            console.log("Sent = " + result.bytesSent);
            console.log("Link to uploaded file: https://www.kinrep.com/foster/ws/contentlibrary/" + result.response);
            var response = result.response;
            var destination = "https://www.kinrep.com/foster/WS/ContentLibrary/" + response.substr(response.lastIndexOf('=') + 1);
            if(this.id == 'uploadcheque') {
                document.getElementById("hdnchequeimgpath").value = destination;

            } else if(this.id == 'uploaddoorlock') {

                document.getElementById("hdndoorlockedimgpath").value = destination;
            } else {

                document.getElementById("hdnothersimgpath").value = destination;
            }
            rst.innerHTML = "File uploaded to: " +
                                                          destination + 
                                                          "</br><button class=\"button\" onclick=\"window.open('" + destination + "', '_blank', 'location=yes')\">Open Location</button>";
            //document.getElementById("downloadedImage").style.display="none";
        }

        function onFileTransferFail (error) {

            rst.innerHTML = "File Transfer failed: " + error.code;
            alert(rst.innerHTML);
            console.log("FileTransfer Error:");
            console.log("Code: " + error.code);
            console.log("Source: " + error.source);
            console.log("Target: " + error.target);
        }
    }

重现错误后,从 logcat 中我无法从我的应用程序中跟踪任何内容。Android 只是对我的应用程序的文件上传活动不做任何事情。同样的活动在模拟器上也很完美。

4

1 回答 1

2

好的,由于自 12 天以来没有人回答我发布的问题,因此决定回答我自己的问题。经过网上对这个问题的各种调查。我发现有一个社区正在测试认证跨设备的 cordova 构建。在他们的网站上清楚地记录了 Android 设备上的 cordova-camera-plugin 存在问题。以下是他们网站上提到的内容

科尔多瓦插件相机(版本 1.0.1)。该相机在运行 Jellybean、Kitkat 和 Lollipop 的三星设备上进行了许多测试。我们还注意到 iOS 和 Windows Phone 8 上的各种其他问题。由于这些问题,我们不会将相机作为该套件的一部分。

我在问题中也提到了一些建议的解决方法,但不幸的是,这些方法在我现在正在测试的 Jelly Bean 平台上不起作用。

因此,合乎逻辑的结论是在 Android Studio 中使用 Android SDK 开发和构建本机应用程序,而不是浪费时间和精力来寻找针对 cordova-camera-plugin 的修复程序。我知道这可能并不理想,但我认为这是目前处理的方法。希望这个答案可以为遇到类似问题的人节省时间

看起来 corodva 相机插件适用于最新的 android 6.x 版本。https://issues.apache.org/jira/browse/CB-10857但这不适用于我的用户仍然使用旧的 android 版本的情况。当文件传输即使在本机 SDK 代码中也不起作用时,这将是唯一的选择,但这种情况不太可能发生。

于 2016-06-26T17:05:11.703 回答