mirror of
https://github.com/apache/cordova-plugin-camera.git
synced 2025-02-22 22:12:54 +08:00
CB-7286 [BlackBerry10] Use getUserMedia if camera card is unavailable
This commit is contained in:
parent
42bf5d2983
commit
d53a7770d9
@ -56,7 +56,7 @@
|
|||||||
<runs />
|
<runs />
|
||||||
</js-module>
|
</js-module>
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
<!-- android -->
|
<!-- android -->
|
||||||
<platform name="android">
|
<platform name="android">
|
||||||
<config-file target="res/xml/config.xml" parent="/*">
|
<config-file target="res/xml/config.xml" parent="/*">
|
||||||
@ -153,10 +153,12 @@
|
|||||||
</config-file>
|
</config-file>
|
||||||
<config-file target="www/config.xml" parent="/widget/rim:permissions">
|
<config-file target="www/config.xml" parent="/widget/rim:permissions">
|
||||||
<rim:permit>access_shared</rim:permit>
|
<rim:permit>access_shared</rim:permit>
|
||||||
|
<rim:permit>use_camera</rim:permit>
|
||||||
</config-file>
|
</config-file>
|
||||||
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
<js-module src="www/CameraPopoverHandle.js" name="CameraPopoverHandle">
|
||||||
<clobbers target="CameraPopoverHandle" />
|
<clobbers target="CameraPopoverHandle" />
|
||||||
</js-module>
|
</js-module>
|
||||||
|
<asset src="www/blackberry10/assets" target="chrome" />
|
||||||
</platform>
|
</platform>
|
||||||
|
|
||||||
<!-- wp7 -->
|
<!-- wp7 -->
|
||||||
|
@ -27,7 +27,98 @@ var PictureSourceType = {
|
|||||||
DATA_URL: 0, // Return base64 encoded string
|
DATA_URL: 0, // Return base64 encoded string
|
||||||
FILE_URI: 1, // Return file uri (content://media/external/images/media/2 for Android)
|
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)
|
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) {
|
function encodeBase64(filePath, callback) {
|
||||||
var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox, // save original sandbox value
|
var sandbox = window.qnx.webplatform.getController().setFileSystemSandbox, // save original sandbox value
|
||||||
@ -112,7 +203,11 @@ module.exports = {
|
|||||||
|
|
||||||
switch(sourceType) {
|
switch(sourceType) {
|
||||||
case PictureSourceType.CAMERA:
|
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;
|
break;
|
||||||
|
|
||||||
case PictureSourceType.PHOTOLIBRARY:
|
case PictureSourceType.PHOTOLIBRARY:
|
||||||
|
82
www/blackberry10/assets/camera.html
Normal file
82
www/blackberry10/assets/camera.html
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<!--
|
||||||
|
Licensed 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.
|
||||||
|
-->
|
||||||
|
<!DOCTYPE HTML>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<script src="camera.js" type="text/javascript"></script>
|
||||||
|
<script>
|
||||||
|
var meta = document.createElement("meta");
|
||||||
|
meta.setAttribute('name','viewport');
|
||||||
|
meta.setAttribute('content','initial-scale='+ (1/window.devicePixelRatio) + ',user-scalable=no');
|
||||||
|
document.getElementsByTagName('head')[0].appendChild(meta);
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<style type="text/css">
|
||||||
|
body {
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
.action-bar {
|
||||||
|
position: fixed;
|
||||||
|
left: 0px;
|
||||||
|
bottom: 0px;
|
||||||
|
height: 100px;
|
||||||
|
width: 100%;
|
||||||
|
background-image: linear-gradient(rgb(41, 41, 41), rgb(32, 32, 32));
|
||||||
|
}
|
||||||
|
.action-bar-back {
|
||||||
|
width: 78px;
|
||||||
|
height: 100px;
|
||||||
|
background-color: black;
|
||||||
|
}
|
||||||
|
.action-bar-divider {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 0px;
|
||||||
|
left: 78px;
|
||||||
|
width: 28px;
|
||||||
|
height: 100px;
|
||||||
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABwAAABkCAYAAACVfFA4AAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggLDiUo1ElOKAAABHdJREFUaN612ktvE1cUB/Bz7bGdGcePJk1i4tA0DomCRJUQEGphAa3KQwGpUHWFYMEiIBZdtKgfADbdsekXaFW1XZUuQAiFh0BRi+iqap2EJrUSJSjg2I7Hk3GmdmwPi5Z4ziQEx57/XeXKUn6255w558y1ICKTUOvKverfpkl0/ahwEXKZ1c/iLhlERAQDu85etcrkX3mGBbPhPiIhXnkUyPyNBfO+1upGEIUyU1iQXG52LSd/HRNY0BIwPiNbfR8Iq+3CN5brZ5KiJrBgLrCT7cPpKSxYlPyWgBE0e/d7AQMHDh0nEhavVOSx5DRodA6zm6WSX8SC2dYBFjCvEh4GrsjtbB9MT2BB0+Vh++nx2wIG7jp2liW8VNQ23oAc/To79lavH5nkV+ewoBrqsVak9Rs2DCx4Q6xCfDbUKcHA/R+dsnydRKJSputfXyvDwHSgl1cIPbl51XLs+rXvYQnfnJ3BgprSyfah1AQWrLh9ZI2YxKNfBAzs//A0a2/da/nXdx5OgHpkH9sr2jwWVFv6eIVIT2HBVV8Lq/DB9CQWZP/GrNDTJw8FDIydHGUB4zXStb61OvOvY5BXiOUEFlSb3+EVYouAcQQsSTKrEHP3fxQwsP/gCdYSukqF7YRXHS1hlLeE8v8zIAzMtu62tYTTWDAvt7HrF0jFsaApJBahM7+NCRjYe+wcS3hPIbfde9I2W8LIEK8Q2QQWVEMxFjDB1CQWLHoCrEIs3P1OwMD/WkKLV16rp67UvpYCu1jCN+kvsKC9JfQvT2NBXdnB9rUkfEMgawkF0ez4TQEDe4+c4S1hMV9vM1Jjw7RjH3vapGwyAzoKqm/1sSmp+Q0VvmHQ8IVZwn85MuSFguwpYaVMX31+eQ0Gdo9cZDOgdzXdSAdbQ0sYGeQBk5nBgiuBnSxggqm/sGDJrbCAmX/0s4CBvQdPsIR3rRmNTiFvagmtM6BJsraABXMtA+xYwJ96igVXlTZbhZjAgqZLYl9p4vf7Agb2fHyOPyU0VCdG1y3yr3Mvr/A1toR1g1qwh+39S3EsWPTylnDxwQ8CBg7bW0LbsYDj4FKQt4Q+/TkW1Nre4+dIqSksqPt5SxhMxbFgxW09FhA09/iOgIGxw2fY9XMXdSefWW0yUkeHWYTK6iwW1MJ9tC6aJvlrnAHrBo0m/pTwxtVRFxQk6+8KKmU69P4BEwZ2j4w23BJuC1Q7hnjC284BHQd128FxczKOBcuSwhL+2fgNAQNjHxznLWHJIKfWpqDRxY8FmnILWFCzPSV0IuG3BPPK2yzho//OYUESHjYl/fHgloCB3UfPs4T3GMvk5NoA5iODvEJk/sGCWijGK8RSHAvaW8LnD38SUJDFTrlITi8GRj/5gr3oW1nEglo7bwnlOmfAmkFdiVjv1xRI/okFTclrHQFp/smYgIHvHv6U/5awoBFirYOr0WH2gpydxYK5cD+vEA4n/Aaw0BRiCZ+8962AgrwlLBFquYiIuk5ess2ASRgoERHp7XtIUGUdlTPTVACBLwEignyX5voIbgAAAABJRU5ErkJggg==);
|
||||||
|
}
|
||||||
|
.action-bar-back-button {
|
||||||
|
position: fixed;
|
||||||
|
bottom: 35px;
|
||||||
|
left: 34px;
|
||||||
|
width: 18px;
|
||||||
|
height: 28px;
|
||||||
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAAcCAYAAABsxO8nAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAAsTAAALEwEAmpwYAAAAB3RJTUUH3ggLDh43ZfOs5QAAAvdJREFUOMuVlU9LMm0Uh6+ZRguUKaNoWbs0QVIMCb9CqQtb1UdI2lS0dBNhn6D2EVQQLaM2UZpTUknRwm3UooI2lTZ/9H42b/M+g2k+A/fmPjcXF+f8OAMg/vVEIhFRLBbF4+Oj0DRNjI2NCem/YsdfJBJhf38fWZbtu4eHBzoGSZJELBZjZ2cHSZKa6nKnkKmpKQ4ODgAQQjhOpVL53UiWZaanp9nY2EDX9ab6+/s76XS6vVFXVxepVIrNzc0fIU9PTySTSSqVCkoriKIozM7OksvlqNVqjpoQwoa8vb217pHL5SKTybC+vk61WnX0o9FocH9/TyKRsCFAs5Hb7SaTybC8vMzn56ej1mg0uL29ZWZmhnq93npqHo+HhYUFlpaW+Pj4sC0ALMuiUCiQTqebIA4jr9dLNptlbm7OYSJJEqZpcnx8zPz8fOuIAEJVVdbW1kilUo7GSpJErVbj8PCQxcXF9lnz+XxidXWVRCLRNJ1qtcr29ja5XO7X0MorKyskk8kmiCzLHB0ddQQBkF9eXnh9fUWSpKboK4rCwMBAR6CuYrGYdbvdBAIBuru77SkJIQiFQoyMjKBpGtVqtT0IyF5cXKAoCuFwGEX5P1qWZeH3+xkeHiafz/P19dUeBFAqlejr68Pv9+NyuWwz0zQJBAKoqkq5XG7qZRMI4OzsDFVVCQQCuFwu+5FhGExMTKCqKtfX1z/CHCCAQqGA1+tlfHzcHgCArutEo1E8Hg+lUgnDMNqDAM7PzxkcHMTv9yPLsg0zDINoNIosy9zd3TlWy48ggJOTE/r7+wkGg47Vapom8XgcRVG4ubmxzVqCAE5PT+nt7SUcDtNoNOx7XdeZnJwE4OrqCsuy2oMA8vk8Q0NDBINBxzYwDINYLMb3xH8FfZv5fD5CoZAN+s5ZPB5H07TOQEII8vk8qqoSjUaxLMu2M02T5+fnzn5HAPV6nVwux+7uLm63277v6emhXC53ZvT3qr28vMTn8zE6OgrA3t4eW1tb/AH4Zo+8fEoEngAAAABJRU5ErkJggg==);
|
||||||
|
}
|
||||||
|
.camera-cross-hairs {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
-webkit-transform: translate(-50%, -147px);
|
||||||
|
width: 194px;
|
||||||
|
height: 195px;
|
||||||
|
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAMIAAADDCAQAAAB6tAYfAAAAAmJLR0QA/4ePzL8AAAAJcEhZcwAACxMAAAsTAQCanBgAAAAHdElNRQfeCAsPDxicOdibAAACbElEQVR42u3a7U7aYBgG4Oet0yZLTMx2bDu5nYo7nSUmzi34DUSe/bA0UHSDbpS5Xpc/sECNuW/a5yV5I4CI8toL03y31R94ipMy7gj/PKmNp7/lWSx27PEuzkZaxFWe7viJL3EdH8ovS5hnRkTu+K9UcVzGehX0u/WsXxNVt4LcuYLoccb/ok9WGRHzfKWEWS56xvkw2hLue1a3WKuh9L+wluqRD+bH7BdA6Q7qr59mOW1/LBr3Wdky5VlenK9dCattjv2TPdwwXy5oqu4iSQX7VpfsjPVq7OubQ1i8VMLFefndF2j24i7b1O/z6LWJzT4Wtp28K5EcnhKUgBKUgBKUgBKUgBKUgBKUgBKUgBKUgBLeSglP7eFMIgPo5t3Zd2TDyzCWe4/q1X1HPz5HREykM5BJyBsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWhfn05zl95TEMC5zmrO8bPIuzw+zfD44LgIawjxzJe8qIuI2MzIyFnHnWhjATS6avG+zLaFqXz6W0ACO2t9OYj1/DkYJSkAJSkAJSkAJSkAJSkAJSkAJSkAJSkAJb6WE6y+COIzbiGh3WzxmaQ5P7LfYu4dc3oDq4nb0j8yA5ni50yWbHUjsz2bCTQmTlakwVcMeraZ73TyWzftUiYiMjO2Gw1O8H/kUuc+jrd6XUZpsY20ixGrSy+HceXoLN/FxpEVc5elO71+9ydTlxbT73oiq0e5hneei55l1eWVQ1z2jHO8Qyb9QwcZqqS6TPuve8a74e5wz2fiwl22m+C6tjnu9IyngTfsJ8D+4z5r15Y4AAAAASUVORK5CYII=);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<body>
|
||||||
|
<div id="camera">
|
||||||
|
<video id="v"></video>
|
||||||
|
<div class="camera-cross-hairs"></div>
|
||||||
|
</div>
|
||||||
|
<canvas id="c" style="display: none;"></canvas>
|
||||||
|
<div class="action-bar">
|
||||||
|
<div id="back" class="action-bar-back">
|
||||||
|
<div class="action-bar-back-button"></div>
|
||||||
|
</div>
|
||||||
|
<div class="action-bar-divider"></div>
|
||||||
|
</div>
|
||||||
|
</body>
|
||||||
|
</html>
|
46
www/blackberry10/assets/camera.js
Normal file
46
www/blackberry10/assets/camera.js
Normal file
@ -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');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
Loading…
Reference in New Issue
Block a user