ionic3 项目使用Cordova自定义插件

作者: 星辰大海_王 | 来源:发表于2018-07-29 16:56 被阅读4次

    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
    

    执行结果如图:


    QQ20180729-151156@2x.png

    为插件添加平台

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

    执行结果如图: 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" src="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 src="src/ios/TestPlugin.m" />
            <!-- 插件依赖的iOS平台库 -->
            <framework src="libz.dylib" />
            <framework src="libc++.dylib" />
            <framework src="libz.tbd" />
            <framework src="Security.framework" weak="true" />
            <framework src="VideoToolbox.framework" weak="true" />
            <framework src="AVFoundation.framework" weak="true" />
            <framework src="Contacts.framework" weak="true" />
            <framework src="AddressBook.framework" weak="true" />
            <framework src="AddressBookUI.framework" weak="true" />
            <framework src="CoreTelephony.framework" weak="true" />
            <framework src="CoreText.framework" weak="true" />
            <framework src="QuartzCore.framework" weak="true" />
            <framework src="CoreGraphics.framework" weak="true" />
            <framework src="CoreMotion.framework" weak="true" />
            <framework src="CFNetwork.framework" weak="true" />
            <framework src="SystemConfiguration.framework" weak="true" />
            <!-- 插件的功能实现文件:比如把插件的某个方法执行是打开TestViewController文件 -->
            <header-file src="src/ios/TestViewController.h"/>
            <source-file src="src/ios/TestViewController.m"/>
            <!-- 插件依赖的第三方库,可以用pods管理,当插件被添加的时候,会自动帮iOS项目生成podfile文件,并自动install此处引用的框架, -->
            <framework src="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 src="src/android/helloPlugin.java" target-dir="src/com/plugin/helloPlugin/helloPlugin" />
        </platform>
    </plugin>
    
    我们还需要一个package.json文件
    npm init
    

    执行结果:


    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配置
    参考文章

    相关文章

      网友评论

      • 海天owen:我是照着大神的代码,敲的,后来又复制粘贴,还是报错,求解
      • 海天owen:[INFO] Looks like @ionic/app-scripts isn't installed in this project.

        This package is required for this command to work properly.

        ? Install @ionic/app-scripts? Yes
        > npm i -D -E @ionic/app-scripts
        npm WARN deprecated browserslist@2.11.3: Browserslist 2 could fail on reading Browserslist >3.0 config used in other tools.
        npm WARN deprecated cryptiles@2.0.5: This version is no longer maintained. Please upgrade to the latest version.
        npm WARN deprecated boom@2.10.1: This version is no longer maintained. Please upgrade to the latest version.
        npm WARN deprecated hoek@2.16.3: This version is no longer maintained. Please upgrade to the latest version.
        这个错误怎么回事啊,安装了也不行,大神,讲解一下

      本文标题:ionic3 项目使用Cordova自定义插件

      本文链接:https://www.haomeiwen.com/subject/iujzmftx.html