为了账号安全,请及时绑定邮箱和手机立即绑定

ionic3 项目使用Cordova自定义插件

标签:
Html5 AngularJS

PS: Ionic 为什么要用Cordova插件?

先看下Ionic是什么?

Ionic(ionicframework)一款开源的Html5移动App开发框架,是以AngularJS为基础的移动端解决方案,Ionic以流行的跨平台移动app开发框架phoengap为蓝本,让开发者可以通过命令行工具快速生成android ios移动app应用。

phoengap又是什么?

PhoneGap是Apache Cordova最原始和最流行的分发,用基于HTML,CSS和JavaScript的,创建移动跨平台移动应用程序的快速开发平台。它使开发者能够利用iPhone,Android,Palm,Symbian,WP7,WP8,Bada和Blackberry智能手机的核心功能——包括地理定位,加速器,联系人,声音和振动。原本由Nitobi公司开发,在2011年10月4日,Adobe公司收购了这个Nitobe公司,后来Adobe把PhoneGap项目捐献给了Apache基金会。当2012年PhoneGap更新到1.4版本后,Apache又把名字更新成Cordova,有趣的是Cordova是PhoneGap团队附近一条街的名字。参考

Ionic/Angular和Cordova关系是?

可能会有人被问道:“Cordova比Ionic/Angular好吗?”,这就很尴尬了,根本是毫无意义的问题。它们在混合开发中扮演的是不同的角色–Ionic/Angular负责页面的实现,而Cordova负责将实现的页面包装成原生应用(Android:apk;iOS:ipa)。就像花生,最内层的花生仁是Angular,花生仁的表皮是Ionic,而最外层的花生壳则是Cordova。包装完成之后我们的页面才有可能调用设备的原生能力,最后才能上传到应用商店被用户使用。

关于Ionic使用Cordova插件:

Cordova插件的作用是提供一个桥梁供页面和原生通信,首先我们的页面不能直接调用设备能力,所以需要与能够调用设备能力的原生代码(Android:Java;iOS:OC)通信,此时就需要Cordova插件了。
Cordova插件能够再任何Cordova工程中使用,和使用什么前端框架(如Ionic)无关。
Ionic 2中封装了Ionic Native,方便了Cordova插件的使用,但在Ionic 2中仍然可以像Ionic 1中一样使用Cordova插件,Ionic Native不是必须的。
即使在Ionic 2中使用了Ionic Native,也首先需要手动添加插件,如:cordova plugin add cordova-plugin-pluginName。

了解这些概念之后,我们就可以愉快的创建一个cordova插件了,具体有这几个步骤:

安装插件管理脚手架:plugman

npm install -g plugman

创建插件:

plugman create --name 插件名称 --plugin_id 插件id --plugin_version 插件版本号  [--path ] [--variable NAME=VALUE]

参数说明:
pluginName: 插件名称,eg:toast
pluginID: 插件id, eg: org.my.toast
version: 版本号, eg: 0.0.1
variable NAME=VALUE: 扩展参数,如说明或者作者

例如:

plugman create --name helloPlugin --plugin_id helloPlugin --plugin_version 0.0.1

执行结果如图:


700

QQ20180729-151156@2x.png

为插件添加平台

添加android平台: plugman platform add --platform_name android
添加iOS平台:plugman platform add --platform_name ios



执行结果如图:

700

QQ20180729-152839@2x.png

在www文件夹下生成了helloPlugin.js,helloPlugin.js的作用是通过js暴露插件的功能给插件使用者,helloPlugin.js文件如下:
exports.coolMethod = function (arg0, success, error) {
       /**
     * Cordova.exec()方法说明
     * function(winParam) {}:成功回调函数。假设您的 exec成功完成,此功能将随您传递给它的任何参数一起执行
     * function(error) {}:错误回调函数。如果操作未成功完成,则此功能将执行可选的错误参数
     * "service":在本机端呼叫的服务名称,与原生端的类名保持一致
     * "action":在本机端调用的动作名称,对应原生类execute()的入参,原生代码通过对action进行判断,从而知道JS让原生端执行什么样的功能,也就是执行的方法名
     * [ arguments ]:传到原生环境的参数数组
     */    exec(success, error, 'helloPlugin', 'coolMethod', [arg0]);
};
android目录下生成的helloPlugin.java文件:
package helloPlugin;import org.apache.cordova.CordovaPlugin;import org.apache.cordova.CallbackContext;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;/**
 * This class echoes a string called from JavaScript.
 */
 //自定义插件需要继承CordovaPlugin类,并且覆盖execute方法。public class helloPlugin extends CordovaPlugin {    @Override
    //参数action是用来判断执行哪个方法,args是json格式的参数,callbackContext响应返回结果。
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {        if (action.equals("coolMethod")) {
            String message = args.getString(0);            this.coolMethod(message, callbackContext);            return true;
        }        return false;
    }    //私有方法--调用的功能方法
    private void coolMethod(String message, CallbackContext callbackContext) {        if (message != null && message.length() > 0) {            //成功回调
            callbackContext.success(message);
        } else {            //失败回调
            callbackContext.error("Expected one non-empty string argument.");
        }
    }
}
插件配置文件:plugin.xml,关于plugin.xml的详细讲解请看这里
<?xml version='1.0' encoding='utf-8'?><plugin id="helloPlugin" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android">
     <name>helloPlugin</name>
    <engines>
        <engine name="cordova" version=">=8.0.0" />
        <engine name="cordova-android" version=">=7.1.0" />
        <engine name="cordova-ios" version=">=4.5.4" />
    </engines>
    <js-module name="helloPlugin" class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="www/helloPlugin.js">
        <clobbers target="helloPlugin" />
    </js-module>
    <platform name="ios">
        <config-file parent="/*" target="config.xml">
            <feature name="helloPlugin">
                <param name="ios-package" value="helloPlugin" />
            </feature>
            <!-- 设置ALIpay 的scheme -->
        <config-file target="*-Info.plist" parent="CFBundleURLTypes">
            <array>
                <dict>
                     <key>CFBundleURLSchemes</key>
                     <array>
                         <string>ALI$APP_ID</string>
                     </array>
                </dict>
        </array>
        </config-file>
            <preference name="APP_ID" value="$APP_ID" />
        </config-file>
        <!-- 申请权限设置:比如相机权限 -->
        <config-file target="*-Info.plist" parent="NSCameraUsageDescription">
            <string>我们的xxx功能想使用相机来为您提供更好的服务</string>
        </config-file>
        <!-- 插件源文件 -->
        <source-file class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="src/ios/TestPlugin.m" />
        <!-- 插件依赖的iOS平台库 -->
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="libz.dylib" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="libc++.dylib" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="libz.tbd" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="Security.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="VideoToolbox.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="AVFoundation.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="Contacts.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="AddressBook.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="AddressBookUI.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="CoreTelephony.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="CoreText.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="QuartzCore.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="CoreGraphics.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="CoreMotion.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="CFNetwork.framework" weak="true" />
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="SystemConfiguration.framework" weak="true" />
        <!-- 插件的功能实现文件:比如把插件的某个方法执行是打开TestViewController文件 -->
        <header-file class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="src/ios/TestViewController.h"/>
        <source-file class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="src/ios/TestViewController.m"/>
        <!-- 插件依赖的第三方库,可以用pods管理,当插件被添加的时候,会自动帮iOS项目生成podfile文件,并自动install此处引用的框架, -->
        <framework class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="NIMKit" type="podspec" spec="~> 2.6.0" />
    </platform>
    <platform name="android">
    <config-file parent="/*" target="res/xml/config.xml">
        <feature name="helloPlugin">
           <param name="android-package" value="helloPlugin" />
        </feature>
    </config-file>
    <config-file parent="/*" target="AndroidManifest.xml">
    </config-file>
        <source-file class="lazyload" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC" data-original="src/android/helloPlugin.java" target-dir="src/com/plugin/helloPlugin/helloPlugin" />
    </platform></plugin>
我们还需要一个package.json文件
npm init

执行结果:


700

QQ20180729-162256@2x.png

{  "name": "helloplugin",  "version": "1.0.0",  "description": "",  "main": "index.js",  "scripts": {    "test": "echo \"Error: no test specified\" && exit 1"
  },  "author": "",  "license": "ISC"}

name等值可以自定义,也可以直接回车选择默认值。

ionic项目引用自定义插件

ionic cordova plugin add 你插件的存储路径
然后home.html文件中,添加btn click测试插件的方法有没有生效:
<ion-header>
  <ion-navbar>
    <ion-title>Home</ion-title>
  </ion-navbar></ion-header><ion-content padding>
  <h2>Welcome to Ionic!</h2>
  <p>
    This starter project comes with simple tabs-based layout for apps
    that are going to primarily use a Tabbed UI.  </p>
  <p>
    Take a look at the <code>src/pages/</code> directory to add or change tabs,
    update any existing page or create new pages.  </p>
  <button ion-button (click)="testPlugin()">测试自定义插件</button></ion-content>
home.ts:
import { Component } from '@angular/core';import { NavController } from 'ionic-angular';//定义cordova对象,注意,这个变量的定义,是个全局的引用,表示所有的插件对象都加载进来,我们的helloplugin插件也会被加载进来declare let cordova: any;
@Component({  selector: 'page-home',  templateUrl: 'home.html'})export class HomePage {   constructor(public navCtrl: NavController) {

  }
  testPlugin(){    // alert('testPlugin');
    //引用自定义插件方法,具体插件类的调用需要看被调用插件的配置文件plugin.xml中的clobbers节点
    helloplugin.coolMethod("插件测试!",result=>alert(result),error=>alert(error));
  }
}

ionic项目真机、模拟器运行的命令简单列一下:

ionic cordova platform add ios/android  //添加平台ionic cordova emulate ios/android –lc //模拟器运行ionic build ios/android //编译ionic cordova run ios/android –lc //真机运行

修改自定义插件

比如修改android平台下的插件功能:

1.修改helloplugin/src/android/helloplugin.java文件,新增一个求和方法:
package helloPlugin;import org.apache.cordova.CordovaPlugin;import org.apache.cordova.CallbackContext;import org.json.JSONArray;import org.json.JSONException;import org.json.JSONObject;/**
 * This class echoes a string called from JavaScript.
 */
 //自定义插件需要继承CordovaPlugin类,并且覆盖execute方法。public class helloPlugin extends CordovaPlugin {    @Override
    //参数action是用来判断执行哪个方法,args是json格式的参数,callbackContext响应返回结果。
    public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {        if (action.equals("coolMethod")) {
            String message = args.getString(0);            this.coolMethod(message, callbackContext);            return true;
        }else if (action.equals("plus")) {//主方法中增加一段方法名称判断和调用的代码
            int x = args.getInt(0);            int y = args.getInt(1);            this.plus(x, y, callbackContext);            return true;
        }        return false;
    }    //私有方法--调用的功能方法
    private void coolMethod(String message, CallbackContext callbackContext) {        if (message != null && message.length() > 0) {            //成功回调
            callbackContext.success(message);
        } else {            //失败回调
            callbackContext.error("Expected one non-empty string argument.");
        }
    }    //新增一个传入两个参数求和的方法
    private void plus(int x, int y, CallbackContext callbackContext) {
        callbackContext.success(x + y);
    }
}
2.修改helloplugin/www/helloplugin.js代码
// var exec = require('cordova/exec');// exports.coolMethod = function (arg0, success, error) {//        /**//      * Cordova.exec()方法说明//      * function(winParam) {}:成功回调函数。假设您的 exec成功完成,此功能将随您传递给它的任何参数一起执行//      * function(error) {}:错误回调函数。如果操作未成功完成,则此功能将执行可选的错误参数//      * "service":在本机端呼叫的服务名称,与原生端的类名保持一致//      * "action":在本机端调用的动作名称,对应原生类execute()的入参,原生代码通过对action进行判断,从而知道JS让原生端执行什么样的功能//      * [ arguments ]:传到原生环境的参数数组//      *///     exec(success, error, 'helloPlugin', 'coolMethod', [arg0]);// };var exec = require('cordova/exec');var testAPI = {}

testAPI.coolMethod = function(arg0, success, error) {
    exec(success, error, "helloPlugin", "coolMethod", [arg0]);
};//求和方法testAPI.plus = function(arg0,arg1, success, error) {
    exec(success, error, "helloPlugin", "plus", [arg0,arg1]);
};module.exports = testAPI;
3.修改自定义插件package.json和plugin.xml文件的版本号
4.自定义插件修改后必须先删除插件,然后再安装插件才可生效。

不知道自己的插件名字可以命令查看已安装的所有插件:

ionic cordova plugin list //列出所有已安装的插件
ionic cordova  plugin remove helloPlugin //从ionic3项目中删除插件
ionic cordova plugin add 自定义插件路径 //安装插件到ionic3项目

以上4步就是插件的跟新步骤了~
到这里自定义插件及使用的方法就说完了,希望对您有所帮助~~~
插件配置文件详情请看:plugin.xml配置
参考文章



作者:星辰大海_王
链接:https://www.jianshu.com/p/c10593d41b8a


点击查看更多内容
1人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消