Search code examples
javascriptcordovacameraphonegapdevextreme

DevExtreme/Phonegap camera plugin: "Cannot read propetry 'getPicture' of undefined"


I'm getting crazy with my app.

I'm using DevExtreme, based on phonegap.

I'd like to take picture with the camera in my app, but I have some troubles.

First of all, here my config.xml.

<widget id="com.devexpress.apptemplate" version="1.0" versionCode="1">
  <name>ApplicationTemplate</name>
  <description>Template</description>
  <preference name="permissions" value="none" />
  <preference name="prerendered-icon" value="true" />
  <preference name="android-windowSoftInputMode" value="adjustPan" />
  <preference name="SplashScreenDelay" value="60000" />
  <preference name="AutoHideSplashScreen" value="false" />
  <preference name="SplashShowOnlyFirstTime" value="false" />
  <preference name="FadeSplashScreen" value="false" />
  <preference name="ShowSplashScreenSpinner" value="false" />
  <preference name="DisallowOverscroll" value="true" />
  <preference name="StatusBarOverlaysWebView" value="false" />
  <preference name="StatusBarBackgroundColor" value="#000000" />
  <preference name="android-minSdkVersion" value="14" />
  <preference name="android-targetSdkVersion" value="22" />
  <plugin name="cordova-plugin-camera" spec="^2.4.1" source="npm" />
  <plugin name="cordova-plugin-splashscreen" onload="true" />
  <plugin name="cordova-plugin-whitelist" />
  <plugin name="cordova-plugin-ios-longpress-fix" />
  <plugin name="cordova-plugin-statusbar" onload="true" />
  <access origin="*" />
</widget>

Do you see anything wrong here?

Further, I have a button to call the camera function (copied from a tutorial):

// Called when a photo is successfully retrieved
//
function onPhotoDataSuccess(imageData) {
    try
    {
        // Get image handle
        //
        var smallImage = document.getElementById('smallImage');
        // Unhide image elements
        //
        smallImage.style.display = 'block';
        // Show the captured photo
        // The inline CSS rules are used to resize the image
        //
        smallImage.src = "data:image/jpeg;base64," + imageData;
    }
    catch (err) {
        alert(err.message);
    }
}

// Called when a photo is successfully retrieved
//
function onPhotoFileSuccess(imageData) {
    // Get image handle
    console.log(JSON.stringify(imageData));

    // Get image handle
    //
    var smallImage = document.getElementById('smallImage');
    // Unhide image elements
    //
    smallImage.style.display = 'block';
    // Show the captured photo
    // The inline CSS rules are used to resize the image
    //
    smallImage.src = imageData;
}
// Called when a photo is successfully retrieved
//
function onPhotoURISuccess(imageURI) {
    // Uncomment to view the image file URI 
    // console.log(imageURI);
    // Get image handle
    //
    var largeImage = document.getElementById('largeImage');
    // Unhide image elements
    //
    largeImage.style.display = 'block';
    // Show the captured photo
    // The inline CSS rules are used to resize the image
    //
    largeImage.src = imageURI;
}
// A button will call this function
//
function capturePhotoWithData() {
    try {
        // Take picture using device camera and retrieve image as base64-encoded string
        navigator.camera.getPicture(onPhotoDataSuccess, onFail, { quality: 50 });
    }
    catch (err) {
        alert(err.message);
    }
}
function capturePhotoWithFile() {
    navigator.camera.getPicture(onPhotoFileSuccess, onFail, { quality: 50, destinationType: Camera.DestinationType.FILE_URI });
}

// A button will call this function
//
function getPhoto(source) {
    debugger;
    // Retrieve image file location from specified source
    navigator.camera.getPicture(onPhotoURISuccess, onFail, {
        quality: 50,
        destinationType: OverviewAPP.destinationType.FILE_URI,
        sourceType: source
    });
}
// Called if something bad happens.
// 
function onFail(message) {
    alert('Failed because: ' + message);
}

And here my related HTML:

[...]
<div class="myBtnPhoto" data-bind="dxButton: { text: 'Conferma con foto', onClick: capturePhotoWithData}" style="float:right;"></div>
[...]
<img style="display:none;width:60px;height:60px;" id="smallImage" src="" />
<img style="display:none;" id="largeImage" src="" />
[...]

The function capturePhotoWithData is correctly called, but the function goes in the catch branch and the alert shows "cannot read propetry 'getPicture' of undefined"

I create the template and the I build the solution. I am trying this on my Android device. I read a lot of forum and other questions in the web, but nothing still worked for me.

Do you see any mistakes or something missing here?


Solution

  • That means navigator.camera is undefined so your project doesn't see cordova-plugin-camera.

    The most common issue can be: you call it before device is ready. Be sure that you call camera into deviceready:

    document.addEventListener("deviceready", function(){
      console.log(navigator); // here you can check all plugins
    }
    

    You can run: $ cordova plugin list to be sure this plugin also exists in list.

    Also try to rebuild: $ cordova build android ( or ios)