前阵子公司接了一个android打印机的项目,使用cordova打包出来的app调用开发商提供的硬件。
但是开发商只提供了android相关的接口,公司也没有Android程序员。
只能让我这个以前做过cordova项目的半吊子重新研究cordova项目插件开发。
1、cordova的android插件本质上使用的还是android,只是提供的是js的调用方法。
所以拿到原生android的Activity之后,只需新建java继承CordovaPlugin并稍作修改即可。
原Activity:
public class MainActivity extends AppCompatActivity { private static final String LOG_TAG = MainActivity.class.getSimpleName(); private UsbPrinter mUsbPrinter; private class MyThread extends Thread { @Override public void run() { mUsbPrinter = new UsbPrinter(getApplicationContext()); } } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mUsbPrinter = new UsbPrinter(getApplicationContext()); findViewById(R.id.button).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final UsbDevice dev = getCorrectDevice(); if (dev != null && mUsbPrinter.open(dev)) { final long stat1 = mUsbPrinter.getStatus(); final long stat2 = mUsbPrinter.getStatus2(); mUsbPrinter.close(); ((TextView) findViewById(R.id.textView)).setText(String.format("%04XH, %04XH", stat1, stat2)); } } }); findViewById(R.id.button2).setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { final UsbDevice dev = getCorrectDevice(); if (dev != null && mUsbPrinter.open(dev)) { mUsbPrinter.init(); mUsbPrinter.doFunction(Const.TX_FONT_ULINE, Const.TX_ON, 0); mUsbPrinter.outputStringLn("This is Font A with underline."); mUsbPrinter.doFunction(Const.TX_SEL_FONT, Const.TX_FONT_B, 0); mUsbPrinter.doFunction(Const.TX_FONT_ULINE, Const.TX_OFF, 0); mUsbPrinter.doFunction(Const.TX_FONT_BOLD, Const.TX_ON, 0); mUsbPrinter.outputStringLn("This is Font B with bold."); mUsbPrinter.resetFont(); mUsbPrinter.doFunction(Const.TX_ALIGN, Const.TX_ALIGN_CENTER, 0); mUsbPrinter.outputStringLn("center"); mUsbPrinter.doFunction(Const.TX_ALIGN, Const.TX_ALIGN_RIGHT, 0); mUsbPrinter.outputStringLn("right"); mUsbPrinter.doFunction(Const.TX_ALIGN, Const.TX_ALIGN_LEFT, 0); mUsbPrinter.doFunction(Const.TX_FONT_ROTATE, Const.TX_ON, 0); mUsbPrinter.outputStringLn("left & rotating"); mUsbPrinter.resetFont(); mUsbPrinter.doFunction(Const.TX_CHINESE_MODE, Const.TX_ON, 0); mUsbPrinter.outputStringLn("中文"); mUsbPrinter.doFunction(Const.TX_FONT_SIZE, Const.TX_SIZE_3X, Const.TX_SIZE_2X); mUsbPrinter.doFunction(Const.TX_UNIT_TYPE, Const.TX_UNIT_MM, 0); mUsbPrinter.doFunction(Const.TX_HOR_POS, 20, 0); mUsbPrinter.outputStringLn("放大Abc"); mUsbPrinter.resetFont(); mUsbPrinter.doFunction(Const.TX_FEED, 30, 0); mUsbPrinter.outputStringLn("feed 30mm"); mUsbPrinter.doFunction(Const.TX_BARCODE_HEIGHT, 15, 0); mUsbPrinter.printBarcode(Const.TX_BAR_UPCA, "12345678901"); //mUsbPrinter.printImage("/storage/sdcard0/a1.png"); mUsbPrinter.printImage(getExternalFilesDir(null).getPath()+"/../../../../a1.png"); mUsbPrinter.doFunction(Const.TX_UNIT_TYPE, Const.TX_UNIT_PIXEL, 0); mUsbPrinter.doFunction(Const.TX_FEED, 140, 0); mUsbPrinter.doFunction(Const.TX_CUT, Const.TX_CUT_FULL, 0); mUsbPrinter.close(); } } }); } private UsbDevice getCorrectDevice() { final UsbManager usbMgr = (UsbManager)getSystemService(Context.USB_SERVICE); final Map<String, UsbDevice> devMap = usbMgr.getDeviceList(); for(String name : devMap.keySet()) { Log.v(LOG_TAG, "check device: " + name); if (UsbPrinter.checkPrinter(devMap.get(name))) return devMap.get(name); } return null; } }
修改后的MUsbPrinter.java:
public class MUsbPrinter extends CordovaPlugin { private UsbPrinter mUsbPrinter; private CallbackContext callbackContext; private JSONObject params; /* private class MyThread extends Thread { @Override public void run() { mUsbPrinter = new UsbPrinter(getApplicationContext()); } }*/ @Override public boolean execute(String action, final JSONArray args, final CallbackContext callbackContext) throws JSONException { this.callbackContext = callbackContext; this.params = args.getJSONObject(0); //获取打印机状态事件 if (action.equals("getState")) { final UsbDevice dev = getCorrectDevice(); if (dev != null && mUsbPrinter.open(dev)) { final long stat1 = mUsbPrinter.getStatus(); final long stat2 = mUsbPrinter.getStatus2(); mUsbPrinter.close(); callbackContext.success(String.format("%04XH, %04XH", stat1, stat2)); } } //打印小票事件 if (action.equals("printTicket")) { // TODO 打印前需要检查打印机状态 final UsbDevice dev = getCorrectDevice(); if (dev != null && mUsbPrinter.open(dev)) { mUsbPrinter.init(); //抬头图片 mUsbPrinter.printImage(cordova.getActivity().getExternalFilesDir(null).getPath()+"../res/vopakTicket.png"); /** * 业务内容 */ mUsbPrinter.doFunction(Const.TX_UNIT_TYPE, Const.TX_UNIT_PIXEL, 0); mUsbPrinter.doFunction(Const.TX_FEED, 140, 0); mUsbPrinter.doFunction(Const.TX_CUT, Const.TX_CUT_FULL, 0); mUsbPrinter.close(); } } return true; } private UsbDevice getCorrectDevice() { final UsbManager usbMgr = (UsbManager)cordova.getActivity().getSystemService(Context.USB_SERVICE); final Map<String, UsbDevice> devMap = usbMgr.getDeviceList(); for(String name : devMap.keySet()) { if (UsbPrinter.checkPrinter(devMap.get(name))) return devMap.get(name); } return null; } }
2、使用plugman工具修改项目。
安装
npm install -g plugman
新建插件目录
plugman create --name musbprinter --plugin_id cordova-plugin-musbprinter --plugin_version 1.0.0
--name:插件名称 --plugin_id:插件名称(plugin.xml中定义的id) --plugin_version:插件版本
生成的文件结构:
3、在src下新建android文件夹,将上面修改好的java文件放入。
如果有原生aar文件,则也将它放入到android目录下。
printlib.gradle:
repositories{ jcenter() flatDir { dirs 'src/main/libs' } } dependencies { compile(name:'printlib', ext:'aar') } android { packagingOptions { exclude 'META-INF/NOTICE' exclude 'META-INF/LICENSE' } }
www下的musbprinter.js文件为cordova混合开发中提供给js的调用方法文件,内容如下:
var exec = require('cordova/exec'); /** * 获取打印机状态 * @param arg0 * @param success * @param error */ exports.getState = function (arg0, success, error) { if (!arg0) { arg0 = {}; } exec(success, error, 'MUsbPrinter', 'getState', [arg0]); }; /** * 打印小票 * @param arg0 * @param success * @param error */ exports.printTicket = function (arg0, success, error) { if (!arg0) { arg0 = {}; } exec(success, error, 'MUsbPrinter', 'printTicket', [arg0]); };
最后配置plugin.xml文件<?xml version='1.0' encoding='utf-8'?>
<plugin id="cordova-plugin-musbprinter" version="1.0.0" xmlns="http://apache.org/cordova/ns/plugins/1.0" xmlns:android="http://schemas.android.com/apk/res/android"> <name>musbprinter</name> <description> 安卓嵌入式打印机 </description> <!-- js调用 --> <js-module name="MUsbPrinter" src="www/musbprinter.js"> <clobbers target="MUsbPrinter" /> </js-module> <!-- android --> <platform name="android"> <!-- arr引用 --> <resource-file src="src/android/printlib.aar" target="libs/printlib.aar" /> <framework src="src/android/printlib.gradle" custom="true" type="gradleReference" /> <!-- 业务类指定 --> <config-file target="res/xml/config.xml" parent="/*"> <feature name="MUsbPrinter"> <param name="android-package" value="com.ourway.musbprinter.MUsbPrinter"/> </feature> </config-file> <!-- 需要的android权限 --> <config-file target="AndroidManifest.xml" parent="/manifest"> <uses-feature android:name="android.hardware.usb.host" android:required="false" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> </config-file> <config-file parent="/*" target="AndroidManifest.xml"> </config-file> <source-file src="src/android/MUsbPrinter.java" target-dir="src/android" /> </platform> </plugin>
至此,android插件转cordova插件开发完成。
4、将cordova插件添加到cordova项目中并打包
cordova plugin add C:UsersDavidcordova-plugin-musbprinter
添加android平台
cordova platform add android
编译
cordova build android
过程中未报错即为正常。