一.创建一个android项目,编写插件功能,并测试ok,这里以一个简单的调用原生Toast.makeText为例。

1.新建android项目

2.编写插件类

package com.plugin.testPlugin;

import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException; import android.R.string;
import android.app.Activity;
import android.util.Log;
import android.widget.Toast; /**
* 插件类必须继承CordovaPlugin,(如果导入CordovaPlugin一系列包,见下面)
* @author lzy
*
*/
public class TestPlugin extends CordovaPlugin { public Activity activity;/**
* 该方法会在调用execute()方法之前调用,此时用来获取activity和webView等
*/
@Override
public void initialize(CordovaInterface cordova,CordovaWebView webView){
super.initialize(cordova, webView);
Log.i("initialize","============================");
this.activity = cordova.getActivity();
} /**
* js方法接口,
* js中通过调用该方法来执行原生的方法
* @param action 方法名
* @param args 参数(数组类型)
* @param callbackContext 回掉
* 原生方法执行完后,会执行js中传过来的回掉方法
*/
@Override
public boolean execute(String action,JSONArray args,CallbackContext callbackContext) throws JSONException{
this.callbackContext = callbackContext;
if(action=="hello"){
String orderInfo = args.getString(0);
hello(orderInfo,callbackContext);
return true;
}
return false;
} public void hello(String hello, CallbackContext callbackContext){

//执行js中传过来的回调
         if(hello!=null && hello.length()>0){
           callbackContext.success(hello);
         }else{
           callbackContext.error("参数不能为空");
         }

       //原生代码,放在js回调后面,否则js回调不执行

    Toast.makeText(this.activity, hello, Toast.LENGTH_SHORT).show();
    }

}

3.因为编写插件需要继承CordovaPlugin,所以需要依赖cordova一系列包,编写时才不会出错,怎么做?

3.1新建一个ionic3的项目ionic-plugin-hello(如何新建,查看这篇

3.2 执行下命令 ionic cordova run android (安装到手机 ,确保数据线已连接到电脑)

3.3执行成功后,查看该项目下文件夹E:\myObject\my\netObject\ionic-plugin-hello\platforms\android\CordovaLib

3.4在eclipse(android studio也行)中导入该文件夹,成为一个项目

File->import->

3.5 在插件项目中,添加对CordovaLib项目的依赖

到此就可以尽情的编写你的原生插件代码了。

二.创建ionic3自定义插件项目

(直接查看转载https://www.cnblogs.com/smartsensor/p/7904254.html)

4.1新建一个ionic3的插件项目,

(注意此时有点绕,刚才我们在eclipse中编写插件代码,是为了借助eclipse的开发环境,便于编写代码,这还不能算一个真正的ionic3插件)

pluman的安装(有了pluman才能创建插件项目)
 npm install -g plugman

创建插件项目

plugman create --name TestPlugin --plugin_id com.plugin.testPlugin --plugin_version 1.0.

说明:

--name TestPlugin //自定义插件名称
--plugin_id com.plugin.testPlugin //自定义插件的包名
--plugin_version 1.0.0 //自定义插件版本

执行上述命令后会在Plugins文件夹下生成一个TestPlugin文件夹,并且TestPlugin文件夹内包含如下内容:

—TestPlugin
|——src
|——www
|——plugin.xml

3 生成平台(android/ios)插件代码

进入插件的根目录,然后执行创建android或者ios的平台支持命令

cd TestPlugin
plugman platform add --platform_name android

命令执行后在TestPlugin/src目录下出现了android目录,把刚才编写好的,android项目中的TestPlugin.java文件直接拷贝过来

拷贝到 TestPlugin\src\android\TestPlugin.java

并且在www文件夹下也新生成TestPlugin.js,TestPlugin.js的作用是通过js暴露插件的功能给ionic

var exec = require('cordova/exec');

exports.coolMethod = function (arg0, success, error) {
exec(success, error, 'TestPlugin', 'coolMethod', [arg0]);
};

说明:

TestPlugin //插件名称
coolMethod //方法名称

4 介绍plugin.xml

<?xml version="1.0" encoding="utf-8"?>

<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android" id="com.plugin.testPlugin" version="1.0.0">
<name>TestPlugin</name>
<js-module name="TestPlugin" src="www/TestPlugin.js">
<clobbers target="cordova.plugins.TestPlugin"/>
</js-module>
<platform name="android">
<config-file parent="/*" target="res/xml/config.xml">
<feature name="TestPlugin">
<param name="android-package" value="com.plugin.testPlugin.TestPlugin"/>
</feature>
</config-file>
<config-file parent="/*" target="AndroidManifest.xml"/>
<source-file src="src/android/TestPlugin.java" target-dir="src/com/plugin/testPlugin/TestPlugin"/>
</platform>
</plugin>

说明:

id: 插件的标识,即发布安装到plugin 的 ID
name:插件的名称
js-module:对应我们的 javascript 文件,src 属性指向 www/TestPlugin.js
platform:支持的平台,这里仅仅用到了 android

5 初始化package.json

在ionic3项目中添加插件,所添加的插件必须包含package.json文件,网上一些生成的方式尝试失败,最后发现执行下面命令可行。

npm init

例如下面执行过程

C:\work\ionic\plugins\TestPlugin>npm init
This utility will walk you through creating a package.json file.
It only covers the most common items, and tries to guess sensible defaults. See `npm help json` for definitive documentation on these fields
and exactly what they do. Use `npm install <pkg>` afterwards to install a package and
save it as a dependency in the package.json file. Press ^C at any time to quit.
package name: (testplugin)
version: (1.0.0)
description:
entry point: (index.js)
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to C:\work\ionic\plugins\TestPlugin\package.json: {
"name": "testplugin",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
} Is this ok? (yes) yes C:\work\ionic\plugins\TestPlugin>

标识红色的地方,可以自定义,也可以直接回车选择默认值。

然后会在插件根目录下看到新建的package.json文件

三.创建ionic3项目,并引用自定义插件

1.创建ionic3项目

ionic start ionic-plugin-hello tabs

2.引用刚才自定义的插件

ionic cordova plugin add E:\myObject\my\netObject\TestPlugin

3 使用自定义插件

3.1 在home.html 上添加下面代码

<p>
<button ion-button color="primary" (click)="callMyPlugin()">call my plugin</button>
</p>

3.2 修改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) { }
callTestPlugin(){
cordova.plugins.TestPlugin.coolMethod("今天好运气,一老狼请吃鸡呀!",result=>alert(result),error=>alert(error));
}
}

标识红色的部分是定义cordova对象,和引用自定义插件方法

注意,这个变量的定义,是个全局的引用,表示所有的插件对象都加载进来

declare let cordova: any;

具体插件类的调用需要看被调用插件的配置文件plugin.xml中的节点

 <clobbers target="cordova.plugins.TestPlugin"/>

如果这个节点被定义为

 <clobbers target="BaiduTTS"/>

那么在调用时直接这样写

BaiduTTS.XXX(xxxxx);//xxxx代表方法名或者参数

4.安装到手机查看效果

ionic cordova run android

5.修改插件,多增加一个方法

自定义插件修改后必须先删除插件,然后再安装插件才可生效。

1)ionic cordova plugin list 列出所有已安装的插件
2)ionic cordova plugin remove com.plugin.testPlugin 从ionic3项目中删除插件
3)ionic cordova plugin add 自定义插件路径 安装插件到ionic3项目

执行顺序为1->2->修改代码->3

例如在插件中增加一个方法,首先修改TestPlugin/Android/TestPlugin.java

package com.plugin.testPlugin;

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 TestPlugin extends CordovaPlugin { @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;
}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);
}
}

修改TestPlugin/www/TestPlugin.js代码

var exec = require('cordova/exec');

var testAPI = {}

testAPI.coolMethod = function(arg0, success, error) {
exec(success, error, "TestPlugin", "coolMethod", [arg0]);
};
//求和方法
testAPI.plus = function(arg0,arg1, success, error) {
exec(success, error, "TestPlugin", "plus", [arg0,arg1]);
}; module.exports = testAPI;

修改自定义插件package.json和plugin.xml文件的版本号

修改ionic项目home.html代码,增加一个button

 <p>
<button ion-button color="primary" (click)="callTestPluginNew()">new plus function</button>
</p>

修改home.ts代码,增加一个调用方法

  callTestPluginNew(){
cordova.plugins.TestPlugin.plus(3,7,result=>alert(result),error=>alert(error));
}

重新添加自定义插件后,再次重新生成apk,查看效果

ionic cordova build android

四.创建自定义插件时用到第三包

详细参考https://www.jianshu.com/p/050ed1bd4973

比如在上述插件中增加一个调用支付宝接口的方法,需要引入支付宝接口包

此时目录结构是这样的:

TestPlugin------
|------src
| |-----android
| |------libs (我们导入了一个jar嘛)
| | |--------alipaySdk-20161009.jar
| |
| |------AliPay.java
| |------AuthResult.java
| |------PayResult.java
|------www
| |------TestPlugin.js
|-------plugin.xml
anrdoid文件夹是我们自己创建的,里面的libs和java文件是我们之前项目中拷贝过来的

Alipay.java实现代码:

package com.plugin.testPlugin;

import android.annotation.SuppressLint;
import android.app.Activity;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast; import com.alipay.sdk.app.AuthTask;
import com.alipay.sdk.app.PayTask; import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaWebView;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject; import java.util.Map; /**
* Created by Administrator on 2016/12/13.
* 支付宝支付接口
*/ public class AliPay extends CordovaPlugin {
private Activity activity;
private static final int SDK_PAY_FLAG = 1;
private static final int SDK_AUTH_FLAG = 2; private CallbackContext callbackContext; @SuppressLint("HandlerLeak")
private Handler mHandler = new Handler() {
@SuppressWarnings("unused")
public void handleMessage(Message msg) {
switch (msg.what) {
case SDK_PAY_FLAG: {
@SuppressWarnings("unchecked")
PayResult payResult = new PayResult((Map<String, String>) msg.obj);
/**
* 对于支付结果,请商户依赖服务端的异步通知结果。同步通知结果,仅作为支付结束的通知。
*/
String resultInfo = payResult.getResult();// 同步返回需要验证的信息
String resultStatus = payResult.getResultStatus();
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
callbackContext.success(resultInfo);
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
callbackContext.success(resultInfo);
}
break;
}
default:
break;
}
}
};
@Override
public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
Log.e("initialize","============================");
activity = cordova.getActivity();
} @Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
this.callbackContext = callbackContext;
switch (action) {
case "payV2":
String orderInfo = args.getString(0);
payV2(orderInfo);
break;
default:
return false;
}
return false;
} /**
* 支付宝支付业务
* 返回ali20247 错误的原因是没有签约APP支付功能
*/
public void payV2(final String orderInfo) { /**
* 这里只是为了方便直接向商户展示支付宝的整个支付流程;所以Demo中加签过程直接放在客户端完成;
* 真实App里,privateKey等数据严禁放在客户端,加签过程务必要放在服务端完成;
* 防止商户私密数据泄露,造成不必要的资金损失,及面临各种安全风险;
*
* orderInfo的获取必须来自服务端;
*/ Runnable payRunnable = new Runnable() { @Override
public void run() {
Log.e("run","run");
PayTask alipay = new PayTask(activity);
Log.e("orderInfo",orderInfo);
Map<String, String> result = alipay.payV2(orderInfo, true);
Log.e("msp", result.toString()); Message msg = new Message();
msg.what = SDK_PAY_FLAG;
msg.obj = result;
mHandler.sendMessage(msg);
}
}; Thread payThread = new Thread(payRunnable);
payThread.start();
}
}

这个类必须继承CordovaPlugin(重要),必须重写execute方法(重要),选择使用initialize方法。

根据支付宝官方要求在plugin.xml的<config-file target="AndroidManifest.xml" parent="/*">节点中配置权限

  • 文件拷贝:
    <source-file src="src/android/AliPay.java" target-dir="src/com/plugin/testPlugin/TestPlugin"/>
<source-file src="src/android/AuthResult.java" target-dir="src/com/plugin/testPlugin/TestPlugin"/>
<source-file src="src/android/PayResult.java" target-dir="src/com/plugin/testPlugin/TestPlugin"/> <source-file src="src/android/libs/alipaySdk-20161009.jar" target-dir="libs"/>

说明:
src:文件源,就是这个文件现在在哪。
target-dir:目标路径,就是将这个文件拷到哪里去。
这个配置就是,将:

AliPay-----------
|------src
| |-----android

下的文件拷贝到Android项目的对应位置中去(注意包名)。
无论是java文件还是jar文件甚至是xml文件,只要是Android项目中需要的文件,都按这种方式拷贝到相应的目录下面去。

ionic3自定义android原生插件的更多相关文章

  1. 《Android原生整合虹软SDK开发uniapp插件》

    1.项目背景 应公司要求,需要开发一套类似人脸打卡功能的app,但是因为我们公司没有很强的原生android开发者,所以根据现状选择了第三方跨平台的uniapp,想必目前大多人都了解这个平台了,我也就 ...

  2. Flutter学习(9)——Flutter插件实现(Flutter调用Android原生

    原文地址: Flutter学习(9)--Flutter插件实现(Flutter调用Android原生) | Stars-One的杂货小窝 最近需要给一个Flutter项目加个apk完整性检测,需要去拿 ...

  3. Android Gradle 学习笔记(七):Android Gradle 插件

    我们知道Android Gradle其实就是一个Gradle的一个第三方插件,它是由Google的Android团队开发的,基于Gradle构建的,和Android Studio完美搭配.相比于旧的构 ...

  4. uniapp安卓ios百度人脸识别、活体检测、人脸采集APP原生插件

    插件亮点 1 支持安卓平板(横竖屏均可),苹果的iPad.2 颜色图片均可更换. 特别提醒 此插件包含 android 端和 iOS 端,考虑到有些同学只做其中一个端的 app,特意分为 2 个插件, ...

  5. 推荐几款实用的Android Studio 插件

    推荐几款实用的Android Studio 插件 泡在网上的日子 发表于 2015-10-09 10:47 第 17453 次阅读 插件,Android Studio 10 编辑推荐:稀土掘金,这是一 ...

  6. android原生ExpandableListView

    android原生可扩展ExpandableListView就是可以伸缩的listView,一条标题下面有多条内容. 这个list的adapter对的数据要求与普通ListView的数据要求也有一些差 ...

  7. Android Small插件化框架源码分析

    Android Small插件化框架源码分析 目录 概述 Small如何使用 插件加载流程 待改进的地方 一.概述 Small是一个写得非常简洁的插件化框架,工程源码位置:https://github ...

  8. 8 个最优秀的 Android Studio 插件

    Android Studio是目前Google官方设计的用于原生Android应用程序开发的IDE.基于JetBrains的IntelliJ IDEA,这是Google I/O 2013第一个宣布的作 ...

  9. [精品推荐]Android Studio插件整理

    GOOD 现在Android的开发者基本上都使用Android Studio进行开发(如果你还在使用eclipse那也行,毕竟你乐意怎么样都行).使用好Android Studio插件能大量的减少我们 ...

随机推荐

  1. 三、CSS样式——链接

    CSS链接的四种状态: a:link ——普通的.未被访问的链接 a:visited ——用户已访问的链接 a:hover ——鼠标指针位于链接的上方 a:active ——链接背点击的时刻 常见的链 ...

  2. DocKer 创建容器 镜像端口映射失败

    问题一: 我想使用同一个镜像创建多个容器,并映射端口出现以下错误,该怎么解决? docker: Error response from daemon: driver failed programmin ...

  3. 使用Git将本地文件提交到远程仓库

    一 操作准备条件: git远程仓库已经建好了,本地文件已经存在了,现在要将本地代码推到git远程仓库保存. 解决办法如下: 1.(先进入项目文件夹)通过命令 git init 把这个目录变成git可以 ...

  4. yml文件搞一波

    引用https://www.cnblogs.com/zslli/p/8717483.html https://www.cnblogs.com/baoyi/p/SpringBoot_YML.html 划 ...

  5. 线上CPU100%排查

    生产服务器上部署了几个java程序,突然出现了CPU100%的异常告警,你如何定位出问题? 这个问题分为两版回答!高调版对不起,我是做研发的,这个问题在生产上是不可能遇见的!因为研发是不可能直接操作生 ...

  6. 解决用try except 捕获assert函数产生的AssertionError异常时,导致断言失败的用例在测试报告中通过的问题

    在使用Python3做自动化测试过程中可能会遇到,assert函数不加try  except,就可以正常在报告里体现用例不通过,加上变成通过. 这是因为在使用try except 时,捕获了asser ...

  7. Open CDN 2.0管控端和节点端安装

    原文:http://www.safecdn.cn/cdn/2018/12/opencdn-2-0/1076.html OpenCDN是一套快速部署CDN加速的工具,针对专门提供CDN加速服务的企业或对 ...

  8. LeetCode 141. Linked List Cycle 判断链表是否有环 C++/Java

    Given a linked list, determine if it has a cycle in it. To represent a cycle in the given linked lis ...

  9. HTML一片空白, 无法渲染: Empty tag doesn't work in some browsers

    html 文件直接引入一个script, 如下 <html> <head> <script type="application/javascript" ...

  10. orcal -对表的操作

    设计表 varchar2(n) number(n,m)整数:n-m,小数m DATE 日期 CLOB 大文本 BLOB二进制 创建表=============== create table membe ...