cordova navigator.camera.getPicture not working in android

折月煮酒 提交于 2019-11-30 18:04:23

问题


navigator.camera.getPicure function not working. Its callback function never gets fired in below code. This function is from cordova camera plugin.

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
                            });

In the above code uploadPhoto callback function never gets fired. And there is no traces of it in chrome dev tools console when the above function is called it opens the file selection window and after the image is selected for upload it simply returns, and then the screen gets refreshed.

Update 6/26 After more testing noticed that this behavior different between two different android devices one with Jelly bean version 4.4.2 and other Jelly bean version 4.4.4. In the device running with 4.4.4 navigator.camera.getPicture was successfully called but struck at file transfer. The device running Jelly bean 4.4.2 has just failed at navigator.camera.getPicture without calling its success or error callback functions which is where I struck since few days. Looks like the cordova 5.1 with camera plugin 2.2.0 does not work with Jelly Bean or few of its versions. Maybe I will need to find cordova version & the cordova camera plugin version that works on Jelly Bean.

Update 6/25 Migrated the code from Telerik AppBuilder to PhoneGap. PhoneGap uses Cordova 5.1 and configured latest Camera Plugin 2.2.0, however issue is still the same. Not sure if this issue is same as in this post quite interesting this issue is not listed in release notes, I tested in different android versions it did not work. And atleast no response to the ticket raised in Telerik Premium support so far.

Update 6/23 1:28IST As suggested by Devid, followed this post I added below recommended fix right before the call navigator.camera.getPicture, the issue remains same.

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

UPDATE: 6/23 I checked the behavior in the console from chrome://inspect there is absolutely no trace during file upload activity. In the network tab could not find this http request. To understand where it stopped functioning I added console.log each stage within uploadFile function what I noticed was it did not trigger uploadPhoto callback function in navigator.camera.getPicture, but this call does invoked file chooser, but after file selection its callback uploadPhoto function did not trigger. Looks like the app is not having some access rights on the device.

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
    });

Here is the catlog from ADB if at all gives some clue.

Update 2/24-9:15AMIST Below is the Android manifest, is there any permission that I am missing?

<?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>

The below cordova file upload code works perfect in simulator but fails when deployed in Android device.

Below is 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>

Below is the client code

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);
        }
    }

From the logcat I could not trace anything from my app after reproducing the error. Android just simply does not do anything on file upload activity from my app. The same activity works perfect from simulator.


回答1:


Okay, since no one answered my question posted since 12 days, decided to answer my own question. After various findings on this issue across the net. I found there is one community which is test certifying cordova builds across the devices. In their website it is clearly documented that there are issues with cordova-camera-plugin with Android devices. Below is what is mentioned at their website

cordova-plugin-camera (version 1.0.1). The camera fails many of our tests on Samsung devices running Jellybean, Kitkat, and Lollipop. We noticed various other issues across iOS and Windows Phone 8 as well. Because of these issues, we will not be including the camera as a part of this kit.

There are some suggested workarounds which I also referred in my question, but unfortunately those did not work on Jelly Bean platforms I am testing with right now.

And hence so the logical conclusion is to develop & build the native app using Android SDK in Android studio instead wasting time & energy in finding a fix for cordova-camera-plugin. I know this may not be ideal but I think this is how to deal with at this point of time. Hope this answer saves time to some who experience similar issues

Looks like corodva camera plugin works with latest android 6.x versions. https://issues.apache.org/jira/browse/CB-10857 But this will not work for my case where my users are still with old android versions. This would be the only choice when file transfers wont work even in native SDK code, but that is quite unlikely the case.



来源:https://stackoverflow.com/questions/37808733/cordova-navigator-camera-getpicture-not-working-in-android

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!