diff --git a/plugin.xml b/plugin.xml index 3afc48f..1bb7b57 100644 --- a/plugin.xml +++ b/plugin.xml @@ -56,7 +56,7 @@ - + @@ -153,10 +153,12 @@ access_shared + use_camera + diff --git a/src/blackberry10/index.js b/src/blackberry10/index.js index 9a5ebf3..74cb191 100644 --- a/src/blackberry10/index.js +++ b/src/blackberry10/index.js @@ -27,7 +27,98 @@ var PictureSourceType = { DATA_URL: 0, // Return base64 encoded string FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android) NATIVE_URI: 2 // Return native uri (eg. asset-library://... for iOS) - }; + }, + savePath = window.qnx.webplatform.getApplication().getEnv("HOME").replace('/data', '') + '/shared/camera/', + invokeAvailable = true; + +//check for camera card - it isn't currently availble in work perimeter +window.qnx.webplatform.getApplication().invocation.queryTargets( + { + type: 'image/jpeg', + action: 'bb.action.CAPTURE', + target_type: 'CARD' + }, + function (error, targets) { + invokeAvailable = !error && targets && targets instanceof Array && + targets.filter(function (t) { return t.default === 'sys.camera.card' }).length > 0; + } +); + +//open a webview with getUserMedia camera card implementation when camera card not available +function showCameraDialog (done, cancel, fail) { + var wv = qnx.webplatform.createWebView(function () { + wv.url = 'local:///chrome/camera.html'; + wv.allowQnxObject = true; + wv.allowRpc = true; + wv.zOrder = 1; + wv.setGeometry(0, 0, screen.width, screen.height); + wv.backgroundColor = 0x00000000; + wv.active = true; + wv.visible = true; + wv.on('UserMediaRequest', function (evt, args) { + wv.allowUserMedia(JSON.parse(args).id, 'CAMERA_UNIT_REAR'); + }); + wv.on('JavaScriptCallback', function (evt, data) { + var args = JSON.parse(data).args; + if (args[0] === 'org.apache.cordova.camera') { + if (args[1] === 'cancel') { + cancel('User canceled'); + } else if (args[1] === 'error') { + fail(args[2]); + } else { + saveImage(args[1], done, fail); + } + wv.un('JavaScriptCallback', arguments.callee); + wv.visible = false; + wv.destroy(); + qnx.webplatform.getApplication().unlockRotation(); + } + }); + wv.on('Destroyed', function () { + wv.delete(); + }); + qnx.webplatform.getApplication().lockRotation(); + qnx.webplatform.getController().dispatchEvent('webview.initialized', [wv]); + }); +} + +//create unique name for saved file (same pattern as BB10 camera app) +function imgName() { + var date = new Date(), + pad = function (n) { return n < 10 ? '0' + n : n }; + return 'IMG_' + date.getFullYear() + pad(date.getMonth() + 1) + pad(date.getDate()) + '_' + + pad(date.getHours()) + pad(date.getMinutes()) + pad(date.getSeconds()) + '.png'; +} + +//convert dataURI to Blob +function dataURItoBlob(dataURI) { + var byteString = atob(dataURI.split(',')[1]), + mimeString = dataURI.split(',')[0].split(':')[1].split(';')[0], + arrayBuffer = new ArrayBuffer(byteString.length), + ia = new Uint8Array(arrayBuffer), + i; + for (i = 0; i < byteString.length; i++) { + ia[i] = byteString.charCodeAt(i); + } + return new Blob([new DataView(arrayBuffer)], { type: mimeString }); +} + +//save dataURI to file system and call success with path +function saveImage(data, success, fail) { + var name = savePath + imgName(); + require('lib/webview').setSandbox(false); + window.webkitRequestFileSystem(window.PERSISTENT, 0, function (fs) { + fs.root.getFile(name, { create: true }, function (entry) { + entry.createWriter(function (writer) { + writer.onwriteend = function () { + success(name); + }; + writer.onerror = fail; + writer.write(dataURItoBlob(data)); + }); + }, fail); + }, fail); +} function encodeBase64(filePath, callback) { var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox, // save original sandbox value @@ -112,7 +203,11 @@ module.exports = { switch(sourceType) { case PictureSourceType.CAMERA: - window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked); + if (invokeAvailable) { + window.qnx.webplatform.getApplication().cards.camera.open("photo", done, cancel, invoked); + } else { + showCameraDialog(done, cancel, fail); + } break; case PictureSourceType.PHOTOLIBRARY: diff --git a/www/blackberry10/assets/camera.html b/www/blackberry10/assets/camera.html new file mode 100644 index 0000000..2ebd9d1 --- /dev/null +++ b/www/blackberry10/assets/camera.html @@ -0,0 +1,82 @@ + + + + + + + + + + +
+ +
+
+ +
+
+
+
+
+
+ + diff --git a/www/blackberry10/assets/camera.js b/www/blackberry10/assets/camera.js new file mode 100644 index 0000000..6d163d0 --- /dev/null +++ b/www/blackberry10/assets/camera.js @@ -0,0 +1,46 @@ +/* + * 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. + * +*/ + +document.addEventListener('DOMContentLoaded', function () { + document.getElementById('back').onclick = function () { + window.qnx.callExtensionMethod('org.apache.cordova.camera', 'cancel'); + }; + window.navigator.webkitGetUserMedia( + { video: true }, + function (stream) { + var video = document.getElementById('v'), + canvas = document.getElementById('c'), + camera = document.getElementById('camera'); + video.autoplay = true; + video.width = window.innerWidth; + video.height = window.innerHeight - 100; + video.src = window.webkitURL.createObjectURL(stream); + camera.onclick = function () { + canvas.width = video.videoWidth; + canvas.height = video.videoHeight; + canvas.getContext('2d').drawImage(video, 0, 0, video.videoWidth, video.videoHeight); + window.qnx.callExtensionMethod('org.apache.cordova.camera', canvas.toDataURL('img/png')); + }; + }, + function () { + window.qnx.callExtensionMethod('org.apache.cordova.camera', 'error', 'getUserMedia failed'); + } + ); +});