In this beginner’s article, we’ll see what’s involved in adding the Cordova APIs to an PhoneGap Android project. It was written to help get your feet wet in case you’ve never tried it. An API (application programming interface) will allow us to use the features of the smartphone, such as accelerometer, camera, com
pass, and other features. In the case of Cordova’s PhoneGap, this APIs come in the form of plugins. They need to be added to the project on an as-needed basis.
If you’ve never built a PhoneGap project before, it’s better to follow the steps in http://iphonedevlog.wordpress.com/2013/08/16/using-phonegap-3-0-cli-on-mac-osx-10-to-build-ios-and-android-projects/ first so you’ll already have all program files need to create any Android project.
The Cordova APIs are found at phonegap.com under Developer > Docs. Scroll down to the API Reference section for the clickable list. We will open those links and copy/paste the code into our document. As usual, I’ll note every click needed to make the project.
Set Up the Android Project
1. Click on the Terminal icon in the dock to get it running.
2. Type “cd” without the quotes, a space, then drag your containing folder (into which we’ll put a new project folder) from the Finder window to the Terminal screen, and hit Enter. This orients the Terminal to your new folder.
3. In Terminal, type the following command to get the basic Cordova/PhoneGap files set up. I am going to think outside the box and cleverly call the project CordovaAPI:
cordova create CordovaAPI com.stevehusting.CordovaAPI CordovaAPI
(Notice that I am starting my commands with cordova and not phonegap. You may have installed phonegap instead, and if so, you should start all your commands with phonegap. This project will not be used for PhoneGap Build, so I use cordova in my commands.)
5. Type the following to see what Cordova version you have. Mine said 3.3.0-0.1.1:
cordova -v
6. We need to change directories to the project’s folder in Terminal so follow instructions in step 3 but drag the TestApp folder over. If you don’t do this, you’ll get the message: “Error: Current working directory is not a Cordova-based project” when trying to do a cordova command.
7. Create the platform files for the project, in our case, Android:
cordova platform add android
I received an error: “Error: An error occured during creation of android sub-project.
Error: ERROR : executing command ‘ant’, make sure you have ant installed and added to your path.” I resolved this error. Scroll down to note in the comments for this step.
8. Verify the platform was installed:
cordova platform list
9. Open /TestApp/www/index.html in a text editor (I use TextWrangler). You might want to save a copy of it an put it somewhere.
10. Copy and paste the below content in place of the current contents:
<!-- ********************* HMTL5 Skeleton begin *********************** --> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="format-detection" content="telephone=no" /> <!-- WARNING from Cordova: for iOS 7, remove the width=device-width and height=device-height attributes. See https://issues.apache.org/jira/browse/CB-4323 --> <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>Cordova APIs</title> <style type="text/css"> .buttonClass { border-radius:8px; background-color:#fff; border:#878787 solid 1px; padding:0 1em;margin:.5em; height: 3em; width: 46%; font-family: "Helvetica"; color: #000; font-size:1em; text-align:center; -webkit-appearance:none; } .segment { display:block; border-radius:8px; background-color:#eee; border:#878787 solid 1px; padding:1em; margin:.5em; font-family: "Helvetica"; color: #000; font-size:1.3em; text-align:left; -webkit-appearance:none; } @media screen and (max-width:700px) { .buttonClass { width: 100%;} } </style> <script type="text/javascript" src="cordova.js"></script> </head> <body> </body> </html> <!-- ********************* HMTL5 Skeleton end *********************** -->
Now we’re starting from the same code.
Accelerometer
The accelerometer captures the motion along the x, y, and z axis. We’ll follow this page from the docs to set it up: http://docs.phonegap.com/en/3.3.0/cordova_accelerometer_accelerometer.md.html#Accelerometer
Please review the page to gain an understanding of the steps we’ll be following.
1. Download the plugin in terminal:
cordova plugin add org.apache.cordova.device-motion
2. Make sure it’s downloaded:
cordova plugin ls
3. Open CordovaAPI/platforms/android/res/xml/config.xml in a text file and add the following to just above </widget> and save:
<feature name="Accelerometer"> <param name="android-package" value="org.apache.cordova.devicemotion.AccelListener" /> </feature>
4. In index.html, remove everything between the <body></body> tags and replace with the following. We will be updating the x, y, and z coordinates every 3 seconds:
<!-- ********************* Accelerometer begin *********************** --> <div class="segment"><h2>Accelerometer</h2> <p id="accelerometer">Waiting for accelerometer...</p> <input type="button" class="buttonClass" onclick="stopWatch();" value="Stop Watching"> <input type="button" class="buttonClass" onclick='window.location="http://iphonedevlog.wordpress.com/2014/01/31/adding-cordova-apis-to-android-via-cli-accelerometer-and-camera/"' value="View Code On iPhoneDevLog"> </div> <script type="text/javascript" charset="utf-8"> // The watch id references the current `watchAcceleration` var watchID = null; // Wait for device API libraries to load document.addEventListener("deviceready", onDeviceReady, false); // device APIs are available function onDeviceReady() { startWatch(); } // Start watching the acceleration, update every 3 seconds function startWatch() { var options = { frequency: 3000 }; watchID = navigator.accelerometer.watchAcceleration(onSuccess, onError, options); } // Stop watching the acceleration function stopWatch() { if (watchID) { navigator.accelerometer.clearWatch(watchID); watchID = null; } } // onSuccess: Get a snapshot of the current acceleration // function onSuccess(acceleration) { var element = document.getElementById('accelerometer'); element.innerHTML = 'Acceleration X: ' + acceleration.x + '<br />' + 'Acceleration Y: ' + acceleration.y + '<br />' + 'Acceleration Z: ' + acceleration.z + '<br />' + 'Timestamp: ' + acceleration.timestamp + '<br />'; } // onError: Failed to get the acceleration function onError() { alert('onError!'); } </script> <!-- ********************* Accelerometer end *********************** -->
6. In terminal, prepare the files:
cordova prepare android
7. Create the apk file:
cordova compile android
8. Navigate to /platforms/android/bin and copy the CordovaAPI-debug.apk file to your device to test. (I copy it to DropBox on my computer and retrieve it from the DropBox app on my device.)
9. With the device in hand and the app running, hold it parallel to the floor. The numbers change every 3 seconds.
Notice the Y number, then lift the top end so the device is perpendicular to the floor and see the number dramatically change. Mine went from 0.1 to 9.9.
Move it back to flat and notice the X number. Now turn the right edge up and watch the number change. Mine went from 0.1 to 9.8.
Move it back flat and notice the Z number, a positive number. Flip the device upside down over your head and it goes negative.
Image may be NSFW.
Clik here to view.
Camera
[Frankly, the following project isn't very practical; it's just an introduction. Some time later I did a more advanced, but practical, camera application. You can see it here: http://iphonedevlog.wordpress.com/2014/03/24/adding-cordova-apis-to-android-via-cli-camera-and-file-apis-shoot-picture-and-upload-to-server-folder-with-php/]
The camera API opens the device’s default camera application that allows users to snap pictures. Once the user snaps the photo, the camera application closes and the application is restored. Another script allows one to open the photo gallery and choose the captured image and display it onscreen in the app.
We’ll follow this page from the docs to set it up: http://docs.phonegap.com/en/3.3.0/cordova_camera_camera.md.html#Camera
According to this page, it works in Android versions before KitKat (4.4). Please review the page to gain an understanding of the steps we’ll be following.
1. Download the plugin in terminal:
cordova plugin add org.apache.cordova.camera
2. Make sure it’s downloaded:
cordova plugin ls
3. Open CordovaAPI/platforms/android/res/xml/config.xml in a text file and add the following to just above </widget> and save:
<feature name="Camera"> <param name="android-package" value="org.apache.cordova.camera.CameraLauncher" /> </feature>
4. Open platforms/android/AndroidManifest.xml with a text editor and enter the following among the other “<uses-permission” entries:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
5. Copy the following into your index.html file right above the </body> tag:
<!-- ********************* Camera begin *********************** --> <div class="segment"><h2>Camera</h2> <p><em>Shoot photo with camera and display as thumbnail on this page.</em></p> <input type="button" class="buttonClass" onclick="capturePhotoEdit();" value="Capture Photo"> <br><input type="button" class="buttonClass" onclick="removeImages();" value="Remove thumbnail"><br> <img style="display:none;width:60px;height:60px;" id="smallImage" src=""> <p id="smTitle"></p> <p><em>Display the captured photo from gallery on this page:</em></p> <input type="button" class="buttonClass" value="Browse Gallery" onclick="getPhoto(pictureSource.PHOTOLIBRARY);"><br> <input type="button" class="buttonClass" onclick="removeLargeImage();" value="Remove below image"><br> <img style="display:none;" id="largeImage" src=""> <p> </p> <input type="button" class="buttonClass" onclick='window.location="http://iphonedevlog.wordpress.com/2014/01/31/adding-cordova-apis-to-android-via-cli-accelerometer-and-camera/"' value="View Code On iPhoneDevLog"> </div> <script type="text/javascript" charset="utf-8"> var pictureSource; // picture source var destinationType; // sets the format of returned value // Wait for device API libraries to load document.addEventListener("deviceready",onDeviceReady,false); // device APIs are available function onDeviceReady() { pictureSource=navigator.camera.PictureSourceType; destinationType=navigator.camera.DestinationType; } // ---------------- CAMERA // STEP 2. Show thumbnail function onPhotoFileSuccess(imageData) { var note = document.getElementById('smTitle'); note.innerHTML = "Image location:<br>" + JSON.stringify(imageData); // put name of file onscreen var smallImage = document.getElementById('smallImage'); smallImage.style.display = 'block'; smallImage.src = imageData; // Show thumbnail } // STEP 1. Capture photo. function capturePhotoEdit() { navigator.camera.getPicture(onPhotoFileSuccess, onFail, { quality: 90, destinationType: Camera.DestinationType.FILE_URI, sourceType : Camera.PictureSourceType.CAMERA, allowEdit : true, encodingType: Camera.EncodingType.JPEG, // targetWidth: 200, // capture it at this size // targetHeight: 200, // capture it at this size popoverOptions: CameraPopoverOptions, saveToPhotoAlbum: true // saves photo to internal memory, viewed in Gallery }); } // ---------------- PHOTO GALLERY // STEP b. Called when a photo is successfully retrieved - gallery function onPhotoURISuccess(imageURI) { // Get image handle var largeImage = document.getElementById('largeImage'); // Unhide image elements largeImage.style.display = 'block'; // Show the captured photo largeImage.src = imageURI; navigator.camera.cleanup( cameraSuccess, cameraError ); } // STEP a. A button will call this function function getPhoto(source) { // Retrieve image file location from specified source navigator.camera.getPicture(onPhotoURISuccess, onFail, { quality: 50, destinationType: destinationType.FILE_URI, sourceType: source }); } // ---------------- REMOVE IMAGES function removeImages() { var smallImage = document.getElementById('smallImage'); smallImage.style.display = 'none'; smallImage = null; } function removeLargeImage() { var largeImage = document.getElementById('largeImage'); largeImage.style.display = 'none'; largeImage = null; } // Called if something bad happens. function onFail(message) { alert('Response: ' + message); } </script> <!-- ********************* Camera end *********************** -->
6. In Terminal, prepare the file:
cordova prepare android
7. Create the apk file:
cordova compile android
8. Navigate to /platforms/android/bin and copy the CordovaAPI-debug.apk and put the into your device to test.
9. With the device in hand and the app running, tap on Capture Photo and the camera app opens. Take the photo and tap done. See its thumbnail and file location in the device appear.
Click on Browse Gallery. I choose a photo. It appears in the app.
Exporting the captured images
What is curious is that I can see the image thumbnails in the gallery, but when I hook up the device to my PC, those images captured in the app show a zero byte count and are blank when opened. Fortunately, I found a way to export them.
1. I downloaded the Nexus Media Importer software to my Nexus 7 (free).
2. I plugged a USB thumbdrive into the USB end of my USB OTG cable and the other end into the Nexus 7.
3. The software recognized the cable. I selected the Export option (you can use this OTG cable to import files to the device), chose the images, and they were copied to the thumb drive.
4. I opened the images from the thumb drive on the PC and they were perfect.
Image may be NSFW.
Clik here to view.
Filed under: Android, PhoneGap Tagged: Accelerometer, Android, Camera, Cordova, Cordova APIs, export images from gallery, PhoneGap, Splashscreen API Image may be NSFW.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
Clik here to view.
