Android集成Cordova

导语

Apache Cordova是一个开源的移动开发框架。允许你用标准的web技术-HTML5,CSS3和JavaScript做跨平台开发。 应用在每个平台的具体执行被封装了起来,并依靠符合标准的API绑定去访问每个设备的功能,比如说:传感器、数据、网络状态等。

使用Apache Cordova的人群:

  • 移动应用开发者,想扩展一个应用的使用平台,而不通过每个平台的语言和工具集重新实现。

  • web开发者,想包装部署自己的web App将其分发到各个应用商店门户。

  • 移动应用开发者,有兴趣混合原生应用组建和一个WebView(一个特别的浏览器窗口) 可以接触设备A级PI,或者你想开发一个原生和WebView组件之间的插件接口。

一、安装Cordova环境

1.下载安装Node.js node.js下载地址,这样就可以使用npm命令。

2.在终端中使用以下命令安装cordova。
sudo npm install -g cordova
其中g表示全局安装。

3.安装完成后运行一下命令查看cordova版本,若出现版本号则说明安装成功,我目前的版本号是8.0.0。
cordova -v

二、创建第一个Cordova工程,添加Android平台并运行

1.在创建第一个cordova工程。选择一个目录例如桌面cd desktop,运行以下命令创建一个cordova工程。
cordova create HelloCordova com.xxx
其中HelloCordova是项目名称,com.xxx是包名。

2.运行之后会生成一个空项目,目录如下:


Android集成Cordova_第1张图片
image.png

3.进入工程根目录下,添加平台
Android:cordova platform add android
iOS:cordova platform add ios
添加完成之后会发现在platforms文件夹下生成了一个Android项目:

Android集成Cordova_第2张图片
image.png

本文章主要介绍Android平台,如不需要iOS平台则可以不添加iOS。

4.在编译项目之前应该先检测编译环境是否满足,在cordova项目根目录下运行如下命令:
cordova requirements
运行后若环境满足则会打印如下信息:

Android集成Cordova_第3张图片
image.png

若不满足则会提示缺少SDK配置或者jdk配置。

5.直接编译运行:
cordova build
注意:若使用cordova build则会编译所有平台,例如Android和iOS以及其他平台会同时被编译,若只想编译其中一个平台则运行cordova build android,加上平台后缀即可,单独编译iOS则cordova build ios
编译Android项目时用到gradle编译命令,所以运行前请保证环境变量已经配置完毕。
编译后将生成一个apk,可直接传到手机上运行:

image.png

运行截图:
Android集成Cordova_第4张图片
image.png

这样第一个Android的Cordova项目就运行起来了。

6.用Android Studio打开该项目跟打开普通Android项目一样的:


Android集成Cordova_第5张图片
image.png

三、Cordova插件调用

cordova官网提供了很多原生插件以供开发者使用,具体插件命令和作用可以查看这两篇文章:

  • https://cordova.apache.org/plugins/
  • cordova插件大全
    下面使用相机插件为例演示调用官方插件完成拍照及选择图片:

1.在cordova工程根目录或者Android目录下运行一下命令
cordova plugin add cordova-plugin-camera
其中cordova plugin add 为添加插件操作,cordova-plugin-camera为插件名称。
卸载插件命令为:
cordova plugin remove cordova-plugin-camera
等待控制台打印

Android集成Cordova_第6张图片
image.png

这样一个相机插件就添加完成了,查看文件目录可以发现添加该插件的同时都添加了哪些代码文件:


Android集成Cordova_第7张图片
image.png

Android集成Cordova_第8张图片
image.png

Android集成Cordova_第9张图片
image.png

Android集成Cordova_第10张图片
image.png

Android集成Cordova_第11张图片
image.png

2.在用cordova添加Android平台时会在assets文件夹下创建www目录来管理插件和js代码:


Android集成Cordova_第12张图片
image.png

首页面的页面编辑在index.html中:


Android集成Cordova_第13张图片
index.html

逻辑编写在js文件夹下的index.js文件中:
Android集成Cordova_第14张图片
index.js

3.我们可以分别编辑这两个文件,首先在index.html中编写两个按钮




    
    
    
    
    
    Hello World


     

注意cordova.js不能省略,且需放在其他js文件引用的第一行


image.png

4.编写index.js

首先简化代码:

var app = {
initialize: function() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},
onDeviceReady: function() {
},
};
app.initialize();

document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
这一行是在初始化js文件的时候初始化cordova,不做改动。

初始化完成后会自动调用onDeviceReady: function() {},我们的点击事件就在这里面写:

var app = {
// Application Constructor
initialize: function() {
    document.addEventListener('deviceready', this.onDeviceReady.bind(this), false);
},

onDeviceReady: function() {
   //调用原生拍照
    document.getElementById("take_picture")
            .onclick = function(){

            navigator.camera.getPicture(onSuccess, onFail, {quality: 50,destinationType: Camera.DestinationType.DATA_URL});

            function onSuccess(imageData) {
              document.getElementById('picture')
              .src = "data:image/jpeg;base64," + imageData;
            }

            function onFail(message) {
            alert('Failed because: ' + message);
            }

    };

     //调用原生选择图片
     document.getElementById("open_photo")
             .onclick = function(){

             navigator.camera.getPicture(onSuccess, onFail, {quality: 50,destinationType: Camera.DestinationType.DATA_URL,
                            sourceType: Camera.PictureSourceType.PHOTOLIBRARY
                        });

             function onSuccess(imageData) {
                document.getElementById('photo')
                .src = "data:image/jpeg;base64," + imageData;
                };

              function onFail(message) {
                alert('Failed because: ' + message);
              };

            };

},
};

app.initialize();

需要说明的是:调用原生方法时需要传入一个调用成功onSuccess()和一个调用失败的方法onFail(),
Android返回结果时就会通过这两个方法,这里返回的是base64格式图片。

5.两个文件编写完成,运行查看结果:


Android集成Cordova_第15张图片
image.png

关于相机动态权限问题该插件已经自动处理好了,cordova拥有一套完整的权限处理机制,主要通过PermissionHelper类来完成处理,在之后的自定义插件中如用到动态权限则可以参照相机插件的源码完成,具体可以查看该插件源码,这里就先不贴了。

四、创建自定义插件及调用

很多时候官方的插件并不能满足我们的开发需求,此时需要自定义插件以供开发调用,下面以创建一个能弹Toast的插件为例进行讲解。
1.插件的创建我们依赖一个plugman插件,该插件可以为我们自动创建一个cordova插件所需要的文件。
首先打开终端,运行以下命令安装plugman:
npm install -g plugman
安装完成后可通过plugman -v查看版本信息:

Android集成Cordova_第16张图片
image.png

2.随便选择一个目录在该目录下打开终端创建自定义插件:
命令:plugman create --name [插件名] --plugin_id [插件ID] --plugin_version [插件版本号]
例子:plugman create --name toast-plugin --plugin_id toast-plugin --plugin_version 1.0.0
创建完成后可以看到该插件目录文件结构如下:

Android集成Cordova_第17张图片
image.png

需要在src下手动创建一个android空目录,里面存放代码和资源文件,如果没有android目录则将该插件添加到项目中时会报找不到资源的错误。
Android集成Cordova_第18张图片
image.png

3.根据功能先编写java文件,该java文件要继承cordova的CordovaPlugin.java,如我们要创建的插件功能为弹出一条Toast,为了结构规范以及编写方便,我们在Android studio中的app-src-java-org-apache下创建一个toa包,在包中创建ToaPlugin.java文件继承自CordovaPlugin.java,并编写Toast代码:
Android集成Cordova_第19张图片
image.png

重写三个execute方法,这三个方法的功能是一样的,按照个人喜好重写其中一个即可,这里我们使用第三个方法

  • 参数action:js调用原生的方法名
  • 参数CordovaArgs:js传过来的参数,cordova做了封装
  • 参数CallbackContext:该对象很重要,要靠它实现js与原生的回调及数据交互
  • 另外需要返回一个boolean值来告诉cordova是否调用成功,若不写则会直接调用失败。
  • 上下文可以使用cordova.getActivity()或者cordova.getContext();

4.编写完成后将该插件文件剪切到plugman创建的插件文件夹toast-plugin中的src-android目录下:


Android集成Cordova_第20张图片
image.png

注意:是剪切,如果复制的话记得将toa包和其中的ToaPlugin.java文件删掉,因为后面添加插件的时候cordova会自动将toa包和java文件复制进来。若项目中已经有了则会在添加插件的时候报错”已存在“。
5.编辑plugin.xml文件,该文件是各个平台对插件的各项配置,包括插件名称、id、调用方法名、代码文件及资源文件配置等。
初始只有插件名称和js配置:


Android集成Cordova_第21张图片
image.png

在plugin节点下添加我们的插件配置,完整代码:


toast-plugin

    




      
         
         
            
              
          
      
    
      
 

注意:

  • 之所以要在toa包下编写ToaPlugin.java文件是为了包名匹配,若在别的包下编写则需要在复制java文件的时候记得把包名手动改成package org.apache.cordova.toa;
  • toast-plugin.js文件暂时不用编写
  • 这个xml文件不仅仅可以添加Android插件配置,同时也可以在plugin节点下继续添加iOS插件配置。

6.在插件目录下通过npm注册该插件:
npm init
弹出的提示依次回车:

Android集成Cordova_第22张图片
image.png

完成后会在插件目录下生成一个package.json文件:
Android集成Cordova_第23张图片
image.png

Android集成Cordova_第24张图片
image.png

里面的内容是插件的名称、版本、描述、作者等信息,我们可以暂时不去管它,以后需要编辑的话重新在 npm init弹出的提示中填入即可。

7.这样一个插件就编写完成了,复制插件路径,在as控制台或者终端通过以下命令将该插件添加到项目中去:
cordova plugin add /Users/mac/Desktop/toast-plugin
添加成功会打印如下信息:

Android集成Cordova_第25张图片
image.png

可以看到插件文件已经被自动添加进来了:
Android集成Cordova_第26张图片
image.png

另外插件会被注册到项目中:
Android集成Cordova_第27张图片
image.png

Android集成Cordova_第28张图片
image.png

8.编写index.html添加一个按钮

Android集成Cordova_第29张图片
image.png

编写index.js代码调用ToaPlugin插件:

      //调用原生选择图片
      document.getElementById("show_toa")
      .onclick = function(){
      cordova.exec(onSuccess,onFailed,"ToaPlugin","showToa",["这是从js传过来的消息"]);
      function onSuccess(deviceInfo) {}
      function onFailed(message) {alert('Failed : ' + message);}
      };
Android集成Cordova_第30张图片
image.png

9.运行截图:


Android集成Cordova_第31张图片
image.png

五、管理自定义插件中使用到的各种资源文件

以上只是创建了一个简单的自定义插件,没有使用其他资源文件,那么如要在自定义插件使用资源文件如图片,style,string,lib库等资源则需要将该插件写成lib库的形式导入工程中。下面使用加载图片资源的Activity作为插件来创建一个插件lib。
1.建立一个新项目或者在原项目上新建一个lib module,起名叫photolib
2.在res-drawbale中插入一张图片,创建Activity,编写布局代码,界面如下:


Android集成Cordova_第32张图片
image.png

3.按照上面创建自定义插件的流程在桌面创建一个photo-plugin插件
4.将该lib库整体复制到插件src-android目录下:


Android集成Cordova_第33张图片
image.png

5.在app项目中编写一个用于启动PhotoActivity的插件:
Android集成Cordova_第34张图片
image.png

6.将插件文件同样复制到桌面创建的photo-plugin插件-src-android中:
Android集成Cordova_第35张图片
image.png

7.编辑plugin.xml文件:

    
    
    photo-plugin
    
    
    



      
         
         
            
              
          
      
    
      
    
 

请注意这一句,
framework标签代表引用内部或外部库资源,如要使用gson.jar包则这样写:

关于plugin.xml文件中各个标签节点的含义可以参考cordova Plugin.xml 详解

8.编辑完成,在插件目录下打开终端运行 npm init,生成对应package.json文件。

9.复制插件路径,将插件添加到项目中,在as项目中运行命令:
cordova plugin add /Users/guibo/Desktop/photo-plugin
会发现photo-plugin插件以lib库的形式添加了进来:

Android集成Cordova_第36张图片
image.png

同时项目自动依赖了该插件库:
Android集成Cordova_第37张图片
image.png

10.编辑index.html再添加一个按钮,其余不变:

  
Android集成Cordova_第38张图片
image.png

index.js中:

      //跳转到图片界面
     document.getElementById("jump_photo")
             .onclick = function(){
             cordova.exec(onSuccess,onFailed,"PhotoPlugin","jumpPhoto");
             function onSuccess() {}
             function onFailed(message) {alert('Failed : ' + message);}
             };
Android集成Cordova_第39张图片
image.png

运行测试即可。

10.若引用的资源文件不多也可以不使用lib库,可直接将图片文件复制到PhotoPlugin.java同级目录下:

Android集成Cordova_第40张图片
image.png

plugin.xml中添加

Android集成Cordova_第41张图片
image.png

这里需留意一下target-dir="app/src/main/res/drawable这个目录,表示将图片复制到app项目中的drawable中,若资源文件不是图片而是.xml文件,则指定的目录可以省略app/src/main,例如:

    
    

    
    

原因是添加插件时由cordova中的js代码控制文件拷贝,查看该源码可以发现在cordova在处理图片、.xml文件和.java文件时的逻辑并不一样:

Android集成Cordova_第42张图片
image.png

可以看到处理.xml和.java文件时会给目录前自动加上app/src/main,但并没有处理图片路径,所以我们在plugin.xml中的目标路径要写全路径:
target-dir="app/src/main/res/drawable
路径不正确会导致添加插件时指定的图片资源无法复制到项目中去。

六、补充操作

1.想要在AndroidManifest.xml文件中添加权限或者四大组件,platform标签下添加:

     
     
     
     

    
       
    
    
  1. string.xml:

     
    
        "取消"
        请扫描
        确定
        完成
       
     
    

3.lib库:

    

七、常见问题

1.经过实测,res/values文件夹下除了string.xml能添加资源以外,该文件夹下其他资源均添加不进去,如attr.xml、ids.xml、color、style、diments等。因此在使用的资源文件很多的情况下建议将插件写成lib库的形式添加,也方便管理。

八、感谢提供参考的宝贵文章:

Android使用Cordova进行混合开发
Android+Cordova混合开发以及Cordova自定义插件
cordova 插件之资源文件处理
cordova Plugin.xml 详解

你可能感兴趣的:(Android集成Cordova)