通过 Cordova 官方提供的插件,我们可以轻松的在 H5 上调用 Android 封装好的调用手机硬件的方法
个人理解,Cordova 插件就是 java 开发中的 jar 工具包、H5 开发中的 Ionic/AngularJs 等封装好的框架,方便我们一行代码或者一个标签就能实现一个完整的效果
Cordova 自定义插件的官方文档
能让 H5 调用任何原生封装好的功能(照相、对话框、数据库、二维码扫描、指纹、NFC)
可以用一个 js 文件指向多个平台下封装好的原生方法
最后,想要开发自己的插件,还是参考官方已有的插件结构来最好
举例:官方 Vibration 插件结构(仅列出重要文件)
|cordova-plugin-vibration
----|src
---------|android
--------------Vibration.java(①)
----|www
---------|vibration.js(②)
----plugin.xml(③)
①**java 代码:**继承 CordovaPlugin
,复写 execute()
方法,在方法中接收 js 传来的 action
,匹配相应的java方法
②**js 中间件:**调用 java 的方法暴露方法给 H5 调用
③**配置文件:**重要性参考 Android 的 AndroidManifest.xml、Servlet 的 Web.xml
PART_0:照猫画虎,仿照官方明确插件结构
|catface.toast
----|src
---------|android
--------------MyToast.java
----|www
---------|toast.js
----plugin.xml
PART_A:plugin.xml – 配置清单
以 |
结尾为相对不重要或为固定写法
以 **
结尾为重要内容,需仔细核对
// 清单模板
plugin
· id:插件唯一标识|
· version:版本号|
··· name:插件名称|
··· description:插件描述|
··· license:证书|
··· keywords:关键字|
··· repo:仓库地址|
··· issue:问题地址|
js-module
· src:js中间件相对目录地址**
· name://|
··· clobbers/merges
·target:H5通过它调用js中间件方法,可以配置多个**
platform
· name:对应平台"android"|
··· source-file
· src:"src/android/java类名"**
· tartget-dir:"src/包类"**会复制进项目包中
··· config-file
· target:"res/xml/config.xml"|
· parent:"/*"|
··· feature
· name:"js中间件通过它调用java方法"**
··· param
· name:"android-package"|
· value:原生插件类的包类路径**
··· config-file
· target:"AndroidManifest.xml"|
· parent:"/manifest"|
··· uses-permission:相关权限|
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0"
id="catface.javat"
version="0.0.2">
<name>Catface Native Toastname>
<description>this is...description>
<js-module src="www/toast.js" name="toast">
<clobbers target="catface"/>
js-module>
<platform name="android">
<source-file src="src/android/MyToast.java" target-dir="src/catface"/>
<config-file target="res/xml/config.xml" parent="/*">
<feature name="Toast">
<param name="android-package" value="catface.MyToast"/>
feature>
config-file>
<config-file target="AndroidManifest.xml" parent="/*">
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
config-file>
platform>
plugin>
PART_B:toast.js – 中间件
prototype.
跟上暴露给 H5 的接口方法,可带参数及回调函数
exec
通过传入配置文件中的 js-module/clobbers/target
的属性值 、传给 java 类的 action 参数来调用 java 方法
var exec = require('cordova/exec');
var myFunc = function(){};
// arg1:成功回调
// arg2:失败回调
// arg3:将要调用类配置的标识
// arg4:调用的原生方法名
// arg5:参数,json格式
myFunc.prototype.javaShow=function() {
exec(null, null, "Toast", "javaShow", []);
};
myFunc.prototype.javaShowJs=function(text, lenth) {
exec(null, null, "Toast", "javaShowJs", [text, lenth]);
}
myFunc.prototype.jsShowJava=function(success, error) {
exec(success, error, "Toast", "jsShowJava", []);
}
myFunc.prototype.jsShowJs=function(text, success, error) {
exec(success, error, "Toast", "jsShowJs", [text]);
}
myFunc.prototype.openVideo=function(content){
exec(null, null, "Toast", "openVideo", [content]);
};
var showt = new myFunc();
module.exports = showt;
PART_C:MyToast.java – 原生 java 类
继承 CordovaPlugin
接口,复写 execute
方法.
arg1:js 传来的 action
参数,通过匹配执行相应方法.
arg2:js 传来的参数,以 JSONArray
格式,通过 get
方法获取值.
arg3:java 提供的接口供回调给 H5.
public class MyToast extends CordovaPlugin {
private static final String TAG = "Toast";
@Override public void initialize(CordovaInterface cordova, CordovaWebView webView) {
super.initialize(cordova, webView);
Context context = this.cordova.getActivity().getApplicationContext();
}
@Override public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
Activity activity = cordova.getActivity();
if("javaShow".equals(action)) {
Toast.makeText(activity, "java show...", Toast.LENGTH_SHORT).show();
} else if("javaShowJs".equals(action)) {
String str = args.getString(0);
int lenth = args.getInt(1);
if (lenth == 1) {
Toast.makeText(activity, "::" + str, Toast.LENGTH_LONG).show();
} else {
Toast.makeText(activity, "::" + str, Toast.LENGTH_SHORT).show();
}
} else if("jsShowJava".equals(action)) {
int a = 4, b = 5;
if (a > b) {
callbackContext.success("sucsucsuc" + a);
} else {
callbackContext.error("errerrerr" + b);
}
return true;
} else if("jsShowJs".equals(action)) {
String text = args.getString(0);
if (!(text.equals(""))) {
callbackContext.success("js'text: " + text);
} else {
callbackContext.error("errjsjs");
}
return true;
} else if("openVideo".equals(action)) {
openVideo(args.getString(0));
}
callbackContext.success();
return true;
}
private void openVideo(String text){
String url = text;
String extension = MimeTypeMap.getFileExtensionFromUrl(url);
String mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
Intent mediaIntent = new Intent(Intent.ACTION_VIEW);
mediaIntent.setDataAndType(Uri.parse(url), mimeType);
//startActivity(mediaIntent);
cordova.startActivityForResult((CordovaPlugin) this, mediaIntent, 200);
}
}
PART_D:H5 调用演示
<script type="text/javascript">
function bt1() {
catface.javaShow();
}
function bt2() {
catface.javaShowJs('fuck me', 1);
}
function bt3() {
catface.jsShowJava(function(msg) {
alert(msg);
}, function(msg) {
alert(msg);
});
}
function bt4() {
catface.jsShowJs("from js", function(msg) {
alert(msg);
}, function(msg) {
alert(msg);
});
}
function bt5() {
catface.openVideo('video net src');
}
</script>
PART_END:无关紧要
js ------> java
js ---args---> java
:js带参给java处理
js ------> java ---args---> js
:js得到java返回的参数
js ---args---> java ---args---> js