1. 程式人生 > >Ionic 3 專案實戰------自定義外掛

Ionic 3 專案實戰------自定義外掛

一個外掛應該至少包含以下file:

plugin-name

-----------------src                                 //外掛支援平臺

------android.java      //添加了支援Android平臺

-----------------www                             //JS檔案,將Cordova.exec方法暴露給HTML/JS呼叫

                       ------android.js

-----------------plugin.xml                   //外掛的配置檔案,通知CLI哪個平臺應該從什麼地方Copy哪些檔案到什麼地方,以及CLI在生成config.xml時應該根據平臺加入什麼樣的特殊設定

在自定外掛時,我們可以按照上述的目錄結構,建立各自的檔案,但是這樣做的話,比較繁瑣,因此一般不推薦這樣做。

推薦使用外掛生成工具plugman,他會自動幫我們建立好想要的外掛目錄,然後去對應檔案中實現我們需要的功能即可。

1、安裝plugman

$ npm install -g plugman
2、建立外掛模板

先看一下plugman可用的命令

plugman manages plugin.xml-compatible cordova plugins into cordova-generated projects.

Usage
=====

To display this help file, use one of the following:

$ plugman --help
$ plugman -h

To display the plugman version, use one of the following:

 $ plugman --version
 $ plugman -v

Optional flags
--------------

 --debug|-d    : Verbose mode

Install a plugin
----------------

    $ plugman install --platform <platform> --project <directory> --plugin <plugin> [--variable NAME=VALUE]

Parameters:

 - platform <platform>: One of android, ios, blackberry10, wp8, or windows8
 - project <directory>: Path reference to a cordova-generated project of the platform you specify
 - plugin <plugin>: One of a path reference to a local copy of a plugin, or a remote https: or git: URL pointing to a cordova plugin (optionally append #branch:subdir) or
 a plugin ID from http://plugins.cordova.io
 - variable NAME=VALUE: Some plugins require install-time variables to be defined. These could be things like API keys/tokens or other app-specific variables.

 Optional parameters:

 - www <directory>: www assets for the plugin will be installed into this directory. Default is to install into the standard www directory for the platform specified
 - plugins_dir <directory>: a copy of the plugin will be stored in this directory. Default is to install into the <project directory>/plugins folder
 - searchpath <directory>: when looking up plugins by ID, look in this directory and each of its subdirectories for the plugin before hitting the registry.
   Multiple search paths can be used by either specifying the flag multiple times, or by separating paths with a delimiter (: on 'nix, ; on Windows).

Uninstall a plugin
------------------

    $ plugman uninstall --platform <platform> --project <directory> --plugin <plugin-id>

Parameters:

 - platform <platform>: One of android, ios, blackberry10, wp8, or windows8
 - project <directory>: Path reference to a cordova-generated project of the platform you specify
 - plugin <plugin-id>: The plugin to remove, identified by its id (see the plugin.xml's <plugin id> attribute)


Interacting with the registry
=============================

NOTICE: The Cordova Plugin registry became read-only, so the following commands have been deprecated and removed:

    $ plugman adduser
    $ plugman publish
    $ plugman unpublish
    $ plugman owner add/rm

For managing plugins for the npm registry, use corresponding npm commands. For more info on npm commands see `npm help <command>`.
Learn more about publishing your plugins to npm at http://plugins.cordova.io/npm/developers.html

Search for a plugin
-------------------

    $ plugman search <keyword1 keyword2 ...>

Display plugin information
--------------------------

    $ plugman info <pluginID>

Manage registry configuration
-----------------------------
Display current configuration settings:

    $ plugman config ls

Display the current registry URL:

    $ plugman config get registry

Set registry URL:

    $ plugman config set registry <url>

Example:

    $ plugman config set registry http://localhost:5984/registry/_design/app/_rewrite

Manage Owners
-------------
Plugin owners are allowed to publish updates to a plugin. To display a list of owners for a plugin, use:

    $ plugman owner ls <pluginID>

Example:

    $ plugman owner ls org.apache.cordova.core.file

Create A Plugin
---------------

    $ plugman create --name <pluginName> --plugin_id <pluginID> --plugin_version <version> [--path <directory>] [--variable NAME=VALUE]

Parameters:

 - <pluginName>: The name of the plugin
 - <pluginID>: An ID for the plugin, ex: org.bar.foo
 - <version>: A version for the plugin, ex: 0.0.1
 - <directory>: An absolute or relative path for the directory where the plugin project will be created
 - variable NAME=VALUE: Extra variables such as description or Author

Add a Package.JSON file to plugin
---------------------------------
Creates a package.json file in the plugin based on values from plugin.xml.

 $ plugman createpackagejson <directory>


Add a Platform to a Plugin
--------------------------

    $ plugman platform add --platform_name <platform>

Parameters:

- <platform>: One of android, ios

Remove a Platform from a Plugin
-------------------------------

    $ plugman platform remove --platform_name <platform>

Parameters:

- <platform>: One of android, ios
然後使用建立外掛的命令
Create A Plugin
---------------

    $ plugman create --name <pluginName> --plugin_id <pluginID> --plugin_version <version> [--path <directory>] [--variable NAME=VALUE]

Parameters:

 - <pluginName>: The name of the plugin
 - <pluginID>: An ID for the plugin, ex: org.bar.foo
 - <version>: A version for the plugin, ex: 0.0.1
 - <directory>: An absolute or relative path for the directory where the plugin project will be created
 - variable NAME=VALUE: Extra variables such as description or Author
對應的引數都有說明,此處不再進行翻譯,開始建立一個外掛模板(外掛可以選擇建立在任意目錄)
$ plugman create --name ZKCustomPlugin --plugin_id zhaikun68.plugin.custom --plugin_version 0.0.1 --path E:\zhaikun\MyPlugins --variable zhaikun68
開啟建立的外掛模組


3、新增外掛支援的平臺

進入外掛的根目錄

支援Android

$ plugman platform add --platform_name android

支援iOS平臺

$ plugman platform add --platform_name ios

plugin.xml檔案內容說明

<?xml version='1.0' encoding='utf-8'?>
<!--外掛的標識,即釋出安裝到 plugin 的 ID ,在建立外掛是設定-->
<plugin id="zhaikun68.plugin.custom" version="0.0.1" xmlns="http://apache.org/cordova/ns/plugins/1.0"
        xmlns:android="http://schemas.android.com/apk/res/android">
    <!--外掛的名稱-->
    <name>ZKCustomPlugin</name>
    <ZHAIKUN68/>
    <!--對應我們的 javascript 檔案,src 屬性指向 www/ZKCustomPlugin.js-->
    <js-module name="ZKCustomPlugin" src="www/ZKCustomPlugin.js">
        <!--指定clobbers ,然後通過target的值來呼叫 ZKCustomPlugin.js,此處對應 ZKCustomPlugin.js 中exports的物件-->
        <clobbers target="cordova.plugins.ZKCustomPlugin"/>
    </js-module>

    <!--支援的平臺Android-->
    <platform name="android">
        <config-file parent="/*"
                     target="res/xml/config.xml"><!--這裡是表示在res/xml/config.xml檔案中插入以下一行程式碼-->
            <feature name="ZKCustomPlugin">
                <param name="android-package"
                       value="zhaikun68.plugin.custom.ZKCustomPlugin"/><!--呼叫外掛的類名,實現了execute方法-->
            </feature>
        </config-file>
        <config-file parent="/*" target="AndroidManifest.xml"/><!--對AndroidManifest.xml檔案進行修改-->
        <!--表示將外掛src/android目錄下的ZKCustomPlugin.java檔案拷貝到android的src/zhaikun68/plugin/custom目錄下面去-->
        <!--如果有引用包,也可以這樣拷貝到安卓的指定lib下面去-->
        <source-file src="src/android/ZKCustomPlugin.java" target-dir="src/zhaikun68/plugin/custom/ZKCustomPlugin"/>
    </platform>

    <!--支援的平臺iOS-->
    <platform name="ios">
        <config-file parent="/*" target="config.xml">
            <feature name="ZKCustomPlugin">
                <param name="ios-package" value="ZKCustomPlugin"/>
            </feature>
        </config-file>
        <source-file src="src/ios/ZKCustomPlugin.m"/>
    </platform>
</plugin>
ZKCustomPlugin.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, "ZKCustomPlugin", "coolMethod", [arg0]);
};
ZKCustomPlugin.java檔案內容說明
package zhaikun68.plugin.custom;

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.
 */
public class ZKCustomPlugin extends CordovaPlugin {//必須繼承CordovaPlugin

    /**
    * action對應exec傳過來的action
    * args對應exec傳過來的引數陣列
    * callbackContext:對應exec傳過來的回撥函式
    */
    @Override
    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.");//失敗的回撥函式
        }
    }
}

4、將自定義的外掛新增到我們建立的專案

$ ionic cordova plugin add E:\zhaikun\MyPlugins\ZKCustomPlugin
未新增成功,有錯誤資訊提示
$ > cordova plugin add E:\zhaikun\MyPlugins\ZKCustomPlugin --save
× Running command - failed!
[ERROR] An error occurred while running cordova plugin add E:\zhaikun\MyPlugins\ZKCustomPlugin --save (exit code 1):


        Error: Invalid Plugin! E:\zhaikun\MyPlugins\ZKCustomPlugin needs a valid package.json
錯誤資訊翻譯過來大概就是:外掛的根目錄下需要一個package.json檔案

記性好的大牛應該發現了在 plugman 工具中,正好有建立package.json檔案的命令

Add a Package.JSON file to plugin
---------------------------------
Creates a package.json file in the plugin based on values from plugin.xml.

 $ plugman createpackagejson <directory>

建立package.json檔案(進入外掛的根目錄)

$ plugman createpackagejson E:\zhaikun\MyPlugins\ZKCustomPlugin
回車後會提示輸入外掛名、版本號、外掛描述、git倉庫地址、作者和證書資訊,如果不進行修改,一直回車即可


回到我們專案的根目錄,重新新增外掛

$ ionic cordova plugin add E:\zhaikun\MyPlugins\ZKCustomPlugin

5、外掛呼叫

在home.html檔案中增加兩個按鈕

<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)="getNativeSuccess()">模擬-成功呼叫原生外掛</button>
  <button ion-button (click)="getNativeFailed()">模擬-失敗呼叫原生外掛</button>

</ion-content>
然後修改home.ts檔案中的內容
import {Component} from '@angular/core';
import {NavController} from 'ionic-angular';

declare let cordova: any;//這裡是修改的程式碼

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {

  constructor(public navCtrl: NavController) {

  }

  //這裡是修改的程式碼
  getNativeSuccess() {
    cordova.plugins.ZKCustomPlugin.coolMethod(
      '原生外掛呼叫成功',
      successMsg => {
        alert(successMsg)
      }, failedMsg => {
        alert(failedMsg)
      }
    );
  }

  //這裡是修改的程式碼
  getNativeFailed() {
    cordova.plugins.ZKCustomPlugin.coolMethod(
      '',
      successMsg => {
        alert(successMsg)
      }, failedMsg => {
        alert(failedMsg)
      }
    );
  }
}
然後編譯專案即可
$ ionic cordova build android
效果圖




此處的除錯是在真機上進行的,在瀏覽器除錯會出現執行時異常

此外,外掛一旦新增到專案中,以後如需對外掛進行升級,需先解除安裝掉原先的外掛,在重新安裝