写在前面
通过Cordova官方提供的插件,我们可以轻松的在H5上调用Android封装好的调用手机硬件的方法.
个人理解,Cordova插件就是java开发中的jar工具包、H5开发中的Ionic/AngularJs等封装好的框架,方便我们一行代码或者一个标签就能实现一个完整的效果.
Cordova能干嘛
最后,想要开发自己的插件,还是参考官方已有的插件结构来最好.
举例:官方Vibration插件结构(仅列出重要文件)
|cordova-plugin-vibration
----|src ---------|android --------------Vibration.java(①) ----|www ---------|vibration.js(②) ----plugin.xml(③)
①java代码:继承CordovaPlugin,复写execute()方法,在方法中接收js传来的action,匹配相应的java方法.
开始自定义插件
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:相关权限|
<?xml version="1.0" encoding="UTF-8"?>
<plugin xmlns="http://apache.org/cordova/ns/plugins/1.0" id="catface.javat" version="0.0.2">
<name>Catface Native Toast</name>
<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.
package catface;
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.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.webkit.MimeTypeMap;
import android.widget.Toast;
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_0:无关紧要
细心 的朋友会发现,本案例介绍了四种调用方式,希望大家满意.
js ------> java
js ---args---> java
js ------> java ---args---> js
js ---args---> java ---args---> js
以上。如有错误和疑问,欢迎指正提出。 [email protected]