使用Cordova访问托管的PWA Web应用程序的本机摄像头,音频和文件

rap*_*lbs 1 media audio camera hybrid cordova

语境

我正在使用PWA应用程序。Webapp已完成。它使用MediaDevices API 在浏览器中具有相机,视频和音频记录功能。在台式机和移动设备(如Android)中使用Chrome或Firefox测试此应用程序时,一切正常。

但是,根据浏览器的“兼容性”选项卡,此功能受少数浏览器支持。

受此限制,我被分配去开发一个使用本地电话资源的混合应用程序。

约束条件

  • 构建一个混合应用
  • 指向主机的Web资源(文件不能位于本地)
  • 媒体资源:拍照,录制音频和视频,上传文件
  • 对AngularJS的支持

rap*_*lbs 5

科尔多瓦

作为Web开发人员,使用Cordova是自然的选择。

我决定记录此过程,因为我花了一个星期才能完成所有工作。


脚步

摘要

  1. 打开没有本地缓存​​的托管应用
  2. 访问托管应用程序中的插件
  3. 处理文件;从设备到网络视图

1)打开没有本地缓存​​的托管应用

为了将应用程序指向webapp,可以简单地更改config.xml

<content src="http://YOUR-DOMAIN/index.html" />
Run Code Online (Sandbox Code Playgroud)

但是那样,当应用程序加载时,它将所有页面缓存到设备中。如果我们更改了Web应用程序中的某些内容,则仅当我们清除应用程序缓存后,它才会在设备中更改。

为了解决第一个问题,我们使用了com.tiltshiftfocus.cordova.plugin.clearCache插件。

  • 1)安装插件:

在bash中:

cordova plugin add com.tiltshiftfocus.cordova.plugin.clearCache
Run Code Online (Sandbox Code Playgroud)
  • 2)创建一个简单的script.js

脚本:

var URL = "http://YOUR-DOMAIN/index.html?platform="
var app = {
    initialize: function() {
        document.addEventListener('deviceready', this.onDeviceReady, false);
    },
    onDeviceReady: function() {
        var targetUrl = URL + cordova.platformId;
        function cb(){
            window.location.replace(targetUrl);
        }
        window.cache.clear(cb, cb);
    }
};
app.initialize();
Run Code Online (Sandbox Code Playgroud)

请注意,我们正在将platform变量传递到主URL。我们稍后将在webapp中使用此变量。

  • 3)创建简单index.html的加载script.js

HTML:

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-Security-Policy" content="default-src 'self' data: gap: cdvfile: http://YOUR-DOMAIN/ https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *">
        <meta name="format-detection" content="telephone=no">
        <meta name="msapplication-tap-highlight" content="no">
        <meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width">
        <title>TITLE</title>
    </head>
    <body>
        <script type="text/javascript" src="cordova.js"></script>
        <script type="text/javascript" src="script.js"></script>
    </body>
</html>
Run Code Online (Sandbox Code Playgroud)
  • 4)更新config.xml以指向index.html

Config.xml:

<content src="index.html" />
Run Code Online (Sandbox Code Playgroud)

2)访问托管应用程序中的插件

使用托管的Webapp的问题在于,我们无法简单地访问打包在该应用中的已安装插件。幸运的是,解决方案很简单。

在安装完所有要使用的插件之后,在您的Cordova项目中,导航到platform文件夹,然后将所有内容复制到您的webapp项目中。

安卓系统

复制内容

Cordova_Project_Folder/platforms/android/platform_www
Run Code Online (Sandbox Code Playgroud)

publicwebapp项目中的目录

Webapp_Project_Folder/public_www/android/
Run Code Online (Sandbox Code Playgroud)

网络应用

复制插件文件夹后,您需要引用cordova.js

Webapp Index.html:

<script scr="/android/cordova.js"></script>
Run Code Online (Sandbox Code Playgroud)

请注意,我们需要为正确的平台引用正确的文件夹。然后,在此步骤中,我们使用platform先前提供给托管webapp 的变量。我不会详细介绍这个过程。


3)处理文件;从设备到网络视图

到目前为止,我们已经使托管的Webapp和所需的插件正常工作。现在我们需要处理存储在设备中的文件。

为了使此过程正常进行,我们最终使用了以下步骤:

  1. 获取文件的完整URL。
  2. 将完整网址转换为cdvfile://
  3. cdvfile://在网络应用中使用。
  4. 将任何网址转换为Blob

1)获取文件的完整URL。

几乎所有可用于创建或读取文件(相机,音频等)的插件都将返回完整的URL。

2.将完整的URL转换为cdvfile://

相机插件cordova-plugin-media-capture返回一个MediaFile对象,该对象已经包含cdvfile://path:fullPath属性。

但是在某些情况下,您必须将完整路径转换file:///Pictures/image.jpgcdvfile://localhost/image.jpg。您可以使用中的resolveLocalFileSystemURL方法来实现cordova-plugin-file

脚本:

function getCDVFromFullURL(fullURL, callback){
    window.resolveLocalFileSystemURL(fullURL, gotFile, callback);
    function gotFile(fileEntry) {
        callback(null, fileEntry.toInternalURL());
    }
};
getCDVFromFullURL('file:///Picture/image.jpg', function(err, cdvUrl){
    cdvUrl === 'cdvfile://localhost/image.jpg'; // example!!!
});
Run Code Online (Sandbox Code Playgroud)

3. cdvfile://在Web应用程序中使用。

问题之一是webapp标记中的参考文件。以下代码段无效。

<img src="cdvfile://path/image.jpg" />
Run Code Online (Sandbox Code Playgroud)

为了正常工作,我们需要使用更新config.xml

<access origin="cdvfile://*" />
Run Code Online (Sandbox Code Playgroud)

注意:如果您使用的是AngularJS,则必须将cdvfile://协议列入白名单:

.config(['$compileProvider', function( $compileProvider ){ 
    $compileProvider.imgSrcSanitizationWhitelist(/^\s*(https?|file|blob|cdvfile):|data:image\//);
}]);
Run Code Online (Sandbox Code Playgroud)

4.将任何URL转换为Blob

这项工作的整个目标是将资源发送到服务器。我们需要Blob添加一个对象FormData。我们仍然可以使用resolveLocalFileSystemURL它。

function getBlob(anyUrl, callback){
    window.resolveLocalFileSystemURL(anyUrl, gotFile, callback);
    function gotFile(fileEntry) {
        fileEntry.file(readFile);
    }
    function readFile(file){
        var reader = new FileReader();
        reader.onloadend = function(e) {
            callback(null, new Blob([ this.result ], { type: file.type } ));
        };
        reader.readAsArrayBuffer(file);
    }
}

getBlob('file:///Picture/image.jpg', function(err, blob){
    // formData.append('imagem', blob, 'iamge name');
}
Run Code Online (Sandbox Code Playgroud)

包起来

现在我们有:

  • 从设备访问任何媒体
  • 能够在我们托管的Webapp中显示任何本地媒体
  • 转换此本地媒体并随后通过webapp上传的工具

希望这篇文章可以节省时间。