写在最前面:首先说明一点,这些文字只包含Android平台的cordova插件的开发过程,IOS平台的如果有机会,会在后续补上。
这个标题已经不新鲜,我也是综合几位大神的博客,才能写出自己的cordova插件。之所以要写这些文字,是因为别人写的总是别人的,自己写的才是最适合自己的。以后忘记的时候能快速的把丢掉的东西捡起来。好了,进入主题。
首先,必须要有cordova的开发环境,本人做的是ionic的开发,所以环境是ionic的开发环境,不过对开发cordova插件两者皆可。环境的搭建可以看这里ionic项目环境搭建。
其次,本人选择了几个工具,用于编辑cordova插件,分别是:WebStrom、Android studio、GapDebug。既然说到这里了,就简单说明一下这几个工具的作用。WebStrom:网页开发IDE,主要用来写写js、html。Android studio:不用说,Android开发IDE,个人习惯用Android studio,用eclipse也没什么问题。GapDebug:调试软件,ionic项目,或者说cordova项目不像Android 项目,也不像单纯的网页,因为是跨平台,所以调试起来就比较麻烦了。这个软件用在这里还是非常好用的,为什么呢?很简单,一般我们做网页开发的人都会选择用浏览器做调试工具,那么问题来了,cordova项目中的那部分与平台相关的js代码在浏览器上是无法调试的。然而在做cordova插件的时候就是在做平台兼容,就是避不开的要和平台打交道。GapDebug可以让你的项目在手机上运行的同时还能像在浏览器上调试一样方便。废话先说道这,下面继续主题。
一切准备就绪,下面正式开始。
网上有教程说,先建一个cordova项目,如何如何。好吧,我来一个标新立异的。我先来写Android平台的本地代码实现,毕竟最终的实现才是一切的根本不是吗?至于cordova项目,咱不着急,那是接入的事了。
首先创建一个Android项目,既然做Android平台的Cordova插件,自然是Android大神,这个不需要我BB。
好吧上个例子来说事(简书不会插图,汗~)
这是我的项目结构,大家一看就知道我想做一个支付宝app支付的插件。
![](https://img.haomeiwen.com/i3586633/268ccf4715e87878.png)
解释一下,AliPay负责将java代码接入到cordova并且能用js调用。另外两个看名字就知道是用来解析支付和授权结果的工具。这是最终的项目,已经删掉了中间过程产生的文件。
好吧,我比较笨,我得一步一步来,看我们是怎么一步一步到这个结果的。
先创建一个Android项目,添加一个MainActivity(用来测试),包名我的为hld.alipay(随便取,前后保持一致就行)。
将AuthResult和PayResult文件拷到制定包下面(支付宝官方Demo里面的两个文件):
![](https://img.haomeiwen.com/i3586633/d9de022fa86122ca.png)
添加必要的库:
![](https://img.haomeiwen.com/i3586633/be61e166c07ccaaf.png)
根据支付宝官方文档添加权限:
![](https://img.haomeiwen.com/i3586633/0caccfffdf56334c.png)
贴上MainActivity的代码:
package hld.alipay;
import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.text.TextUtils;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import com.alipay.sdk.app.PayTask;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
private Button alipayBtn;
private static final int SDK_PAY_FLAG = 1;
private final String content = "app_id=2016072900115009×tamp=2016-12-02+16%3A55%3A53&biz_content=" +
"%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220" +
".01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_" +
"trade_no%22%3A%22121511134515401%22%7D&method=alipay.trade.app.pay&charset=utf-8&version=1.0&sign_type=RSA&sign=pCNuPrQlfBV" +
"be2GZPS1ikpDS613utsAdULTVXfzmx2ymS4ZvBqufuT15LV2OL1Rk9HWcIdJZDJxm30rWP4Jt0aaCYOYGhQ6%2Bcl6l3TdBoio6qDmheOczCfQ4hDAy9SoYb3ZpPC" +
"94BHsOJx4sEdfCKKZJlZdcb3lP0OVCx0to6%2Fc%3D";
@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")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
Toast.makeText(MainActivity.this, "支付成功", Toast.LENGTH_SHORT).show();
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
Toast.makeText(MainActivity.this, "支付失败", Toast.LENGTH_SHORT).show();
}
break;
}
default:
break;
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
alipayBtn = (Button) findViewById(R.id.alipay);
alipayBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
payV2(content);
}
});
}
/**
* 支付宝支付业务
* 返回ali20247 错误的原因是没有签约APP支付功能
*/
public void payV2(final String orderInfo) {
Runnable payRunnable = new Runnable() {
@Override
public void run() {
PayTask alipay = new PayTask(MainActivity.this);
Map<String, String> result = alipay.payV2(orderInfo, true);
Log.i("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();
}
}
简单说明:payV2()方法是我们的目标方法,将被封装成cordova插件。至于支付宝app支付的实现,不做解释。并且在界面上设置了一个按钮用于测试payV2()方法是否正确。
![](https://img.haomeiwen.com/i3586633/457dfdcb4c5c6a5a.jpg)
好的,看来已经成功调起了支付宝,说明我们的方法没有问题,继续。
这是一个Activity啊调起了有毛用?我们要做的是Cordova插件啊!~
不着急我们慢慢来,现在就做接入:
1、关键来了:
首先要添加一个Cordova的库,并添加依赖,不然要报错的。
- 之前有人提到过,我没有说清楚怎么导入CordovaLib,今天来修订一下,仔细说明。
首先创建一个ionic项目,并添加android 平台,然后你可以在下面的目录看到CordovaLib文件夹:
![](https://img.haomeiwen.com/i3586633/44a4ef614d260814.png)
CordovaLib在ionic项目下的platforms\android目录下,如果没有cordova项目,可以先创建一个,创建方法看这里。
2、然后导入CordovaLib模块。
在android studio中,File ==> New ==> Imorpt Module...,选择刚才的目录,点击确定:
![](https://img.haomeiwen.com/i3586633/497d33e718ac6501.png)
3、添加依赖,让app 模块依赖CordovaLib 模块:
![](https://img.haomeiwen.com/i3586633/62c8f995a56451e8.png)
4、紧接着创建AliPay.java文件
![](https://img.haomeiwen.com/i3586633/b310c1c064998764.png)
先贴代码:
package hld.alipay;
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方法。
execute方法是js调用Cordova插件时被调用的方法,是我们写的插件的入口。initialize是在调用插件前作的准备工作,在调用execute之前被调用。如上面的代码,我仅仅是获取了activity并保持下来。
重点来说一下execute方法,这个方法有三个参数action、args、callbackContext。
action活动,主要用来区分调用的是哪个方法,如果你的插件有多个方法,可以用这个区分。比如我只有payV2这个方法:
switch (action) {
case "payV2":
String orderInfo = args.getString(0);
payV2(orderInfo);
break;
default:
return false;
}
args传入的参数,我的插件传入了一个参数:
String orderInfo = args.getString(0);
如果有多个参数,依次取出即可。
接下来就是调用payV2方法了,这个方法才是真正做事的方法,execute、initialize方法都是为js接入做准备。
callbackContext参数:调用结果的回调方法,用于向js返回调用结果。
我先在execute方法中,将这个参数存成全局变量(这样不一定好)。
@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;
}
然后在payV2方法中,使用handler接受调用结果:
/**
* 支付宝支付业务
* 返回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();
}
再在handler中处理结果:
@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.error(resultInfo);
}
break;
}
default:
break;
}
}
};
可以看到,在handler中,将调用结果进行了解析判断。重点在这两行:
// 判断resultStatus 为9000则代表支付成功
if (TextUtils.equals(resultStatus, "9000")) {
// 该笔订单是否真实支付成功,需要依赖服务端的异步通知。
callbackContext.success(resultInfo);
} else {
// 该笔订单真实的支付结果,需要依赖服务端的异步通知。
callbackContext.error(resultInfo);
}
使用callbackContext将结果返回到js中去。
到这里,我们的java代码基本上已经准备就绪,下面就来写js接口:
现在我们需要一个工具:(拷一段别人的文字)
pluman的安装
npm install -g plugman
plugman安装完之后就可以创建一个插件了cordova plugin
plugman create --name <pluginName> --plugin_id <pluginID> --plugin_version <version> [--path <directory>] [--variableNAME=VALUE]
参数:
pluginName: 插件名字
pluginID: 插件id, egg : coolPlugin
version: 版本, egg : 0.0.1
directory:一个绝对或相对路径的目录,该目录将创建插件项目
variable NAME=VALUE: 额外的描述,如作者信息和相关描述
egg : plugman create --name CoolPlugin --plugin_id coolPlugin --plugin_version 0.0.1
5、好了,我们来创建我们的插件
E:\ionicPro>plugman create --name AliPay --plugin_id hld.alipay --plugin_version
1.0.0
成功的话是这样的:
![](https://img.haomeiwen.com/i3586633/07f4409d7501b2b2.png)
在src文件夹下创建android文件夹(我们支持的是Android平台嘛)。
目录结构是这样的:
AliPay-----------
|------src
| |-----android
| |------libs (我们导入了一个jar嘛)
| | |--------alipaySdk-20161009.jar
| |
| |------AliPay.java
| |------AuthResult.java
| |------PayResult.java
|------www
| |------AliPay.js
|-------plugin.xml
anrdoid文件夹是我们自己创建的,里面的libs和java文件是我们之前项目中拷贝过来的(我们已经编译通过,并测试没有问题的)。
android文件夹下面的文件结构不要拘泥固定格式,因为这不重要(后面就知道了)。
先说说这个目录结构:
-
src用于存放各个平台的本地代码,我的只有Android平台的,所以只有一个android文件夹。
-
www用于存放js文件,js文件主要做接口用(一般使用命令创建的时候会自动生成一个,但是需要修改)。
-
plugin.xml文件是插件的配置文件,至关重要。
android目录不多说,将插件需要用到的所有的java文件、库、layout、value等拷进去(处理android SDK中提供了的库)。
6、修改AliPay.js文件:
var exec = require('cordova/exec');
var alipay = function(){};
alipay.prototype.payV2 = function(arg,success,error) {
exec(success, error, "AliPay", "payV2", [arg]);
};
var pay = new alipay();
module.exports = pay;
按照这个格式写,解释一下这个:
alipay.prototype.payV2 = function(arg,success,error) {
exec(success, error, "AliPay", "payV2", [arg]);
};
-
alipay.prototype.payV2:js中调用时使用的方法名是payV2,参数是arg,success,error。
-
exec(success, error, "AliPay", "payV2", [arg]);中的参数解释
-
success:成功回调方法,对应java代码中的
private CallbackContext callbackContext;
callbackContext.success();方法。 -
error:失败回调方法,对应java代码中的
private CallbackContext callbackContext;
callbackContext.error();方法。 -
"AliPay":插件名。
-
"payV2",[arg]:这两个参数一起说,还记得这个吗?
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;
}
"payV2"对应action,[arg]对应args。
js文件的其他内容不多说(我也不懂,嘿嘿嘿...);
7、然后就是plugin.xml配置了,修改为如下:
<?xml version='1.0' encoding='utf-8'?>
<plugin id="hld.alipay" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0"
xmlns:android="http://schemas.android.com/apk/res/android">
<name>AliPay</name>
<js-module name="alipay" src="www/AliPay.js">
<clobbers target="alipay"/>
</js-module>
<platform name="android">
<config-file target="res/xml/config.xml" parent="/*">
<feature name="AliPay">
<param name="android-package" value="hld.alipay.AliPay"/>
</feature>
</config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</config-file>
<source-file src="src/android/AliPay.java" target-dir="src/hld/alipay"/>
<source-file src="src/android/AuthResult.java" target-dir="src/hld/alipay"/>
<source-file src="src/android/PayResult.java" target-dir="src/hld/alipay"/>
<source-file src="src/android/libs/alipaySdk-20161009.jar" target-dir="libs"/>
</platform>
</plugin>
对这个配置还是做下解释:
-
plugin 标签中的id,就是插件的id(或许你可以发布出去给别人用——总得有个身份证 不是)。
-
name标签,插件名字,自不必多说。
-
js-module标签,name:js模块的名字,调用的时候会用到;src源码位置。
-
platform标签,平台标签。
-
config-file标签,target:配置文件config.xml文件的位置(在ionic项目的Android平台中的Android项目中的res/xml文件夹下面)。
<feature name="AliPay">
<param name="android-package" value="hld.alipay.AliPay"/>
</feature>
feature标签中的name:插件名。
android-package:android包,报名后面要跟上java类名。
- Android权限:
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.GET_ACCOUNTS"/>
<uses-permission android:name="android.permission.READ_PROFILE"/>
<uses-permission android:name="android.permission.READ_CONTACTS"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</config-file>
config-file target:权限写入的目标文件(就是将权限配置到AndroidManifest中)。
<uses-permission android:name="android.permission.READ_PHONE_STATE"/>,权限,Android攻城狮都知道~。
- 文件拷贝:
<source-file src="src/android/AliPay.java" target-dir="src/hld/alipay"/>
<source-file src="src/android/AuthResult.java" target-dir="src/hld/alipay"/>
<source-file src="src/android/PayResult.java" target-dir="src/hld/alipay"/>
<source-file src="src/android/libs/alipaySdk-20161009.jar" target-dir="libs"/>
说明:
src:文件源,就是这个文件现在在哪。
target-dir:目标路径,就是将这个文件拷到哪里去。
这个配置就是,将:
AliPay-----------
|------src
| |-----android
下的文件拷贝到Android项目的对应位置中去(注意包名)。
无论是java文件还是jar文件甚至是xml文件,只要是Android项目中需要的文件,都按这种方式拷贝到相应的目录下面去。
好了,到这里,整个插件的开发就算完成了,接下来就看看我们的成果了。
- 诶。。。等等,有网友反应,在添加插件的时候没有package.json文件,那么现在补上。
在你的 插件的根目录执行命令
npm init
然后根据自己的情况输入相关内容,就能生成package.json文件了。
8、现在好了,插件的开发完成,测试下成果
首先创建一个ionic(cordova)项目,创建方式看这里。
在ionic(cordova)根目录下
ionic plugin add [path]
添加插件,比如ionic plugin add E:\AliPay
添加之后你会发现你的项目下面的plugins下面多了一个文件夹如下图:
![](https://img.haomeiwen.com/i3586633/733bc32b134827e5.png)
这个文件夹就是我们写的插件。(插件删除办法ionic plugin remove hld.alipay
hld.alipay是插件id)
插件使用方法:
$scope.testAlipay = function () {
alipay.payV2("app_id=2016072900115009×tamp=2016-12-02+16%3A55%3A53&biz_content=%7B%22timeout_express%22%3A%2230m%22%2C%22product_code%22%3A%22QUICK_MSECURITY_PAY%22%2C%22total_amount%22%3A%220.01%22%2C%22subject%22%3A%221%22%2C%22body%22%3A%22%E6%88%91%E6%98%AF%E6%B5%8B%E8%AF%95%E6%95%B0%E6%8D%AE%22%2C%22out_trade_no%22%3A%22121511134515401%22%7D&method=alipay.trade.app.pay&charset=utf-8&version=1.0&sign_type=RSA&sign=pCNuPrQlfBVbe2GZPS1ikpDS613utsAdULTVXfzmx2ymS4ZvBqufuT15LV2OL1Rk9HWcIdJZDJxm30rWP4Jt0aaCYOYGhQ6%2Bcl6l3TdBoio6qDmheOczCfQ4hDAy9SoYb3ZpPC94BHsOJx4sEdfCKKZJlZdcb3lP0OVCx0to6%2Fc%3D",
function (resultStatus, result) {
// 成功
alert(result);
}, function (resultStatus, result) {
// 错误
alert(result);
});
}
- 在写这篇博客的时候,用的还是ionic第一版,现在已经第三版了,引用一段别人的博客来介绍一下在ionic2+怎么使用自定义插件
如何使用插件呢
在HeaIonic/platforms/android/assets/www 这个路径下的这个文件cordova_plugins.js 打开
我们可以看到这个
image
我们在页面上这样使用
圈起来的是添加的代码
image
然后 ionic serve ,接着cordova build android
OK! 如果没有问题,那么到这里就结束了,不过一般不会这么好运。所以你需要使用一开始提到的那个软件GapDebug。
使用命令行ionic run android
运行项目后打开GapDebug,你会发现这里有个调试界面:
![](https://img.haomeiwen.com/i3586633/3505ed878b4482fc.png)
在这里慢慢的找坑吧,Good Luck!
好吧,附上源码,欢迎指教
https://github.com/xudefei/AliPayPlugin
网友评论