首页 > Android通过OTG线连接打印机实现打印功能

Android通过OTG线连接打印机实现打印功能

一、创建demo调用PrinterShare服务,虽然能找到相应的类和方法但调用后没有反应

//打印图片,进入PrinterShare打印图片预览界面
public static void printPicture(File file,Context context,AlertDialog.Builder builder){
    Log.e("test", "printPicture");
    if (!CheckAPK.appIsInstalled(context)) {
        builder.show();
        return;
    }
    Intent intent  = new Intent();
    ComponentName comp = new ComponentName("com.dynamixsoftware.printershare"
            ,"com.dynamixsoftware.printershare.ActivityPrintPictures");
    intent.setComponent(comp);
    intent.setAction("android.intent.action.VIEW");
    intent.setType("application/picture");
    intent.setData(Uri.fromFile(file));
    context.startActivity(intent);
    invokeAimMethod(context);
}

//调用目标方法
private static void invokeAimMethod(Context context){
    try {
        Context otherPackageContext = context.createPackageContext("com.dynamixsoftware.printershare",
                Context.CONTEXT_INCLUDE_CODE | Context.CONTEXT_IGNORE_SECURITY);
        if (otherPackageContext != null) {
            //载入类
            Class<?> clazz = otherPackageContext.getClassLoader().loadClass("com.dynamixsoftware.printershare.ActivityPrintPictures");
            if (clazz != null) {
                //创建类的实例
                Object obj = clazz.newInstance();
                Class[] clazzs = {boolean.class};
                Object[] objs = {false};
                Thread.sleep(2000);
                //调用PrinterShare的打印方法后打印机没反应
                invokeMethod(obj,"print",clazzs,objs);
            } else {
                Log.e("print","没有获取到类");
            }
        } else {
            Log.e("print", "没有获取到其它包上下文");
        }
    } catch (PackageManager.NameNotFoundException e) {
        e.printStackTrace();
        Log.e("print", "NameNotFoundException");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
        Log.e("print", "ClassNotFoundException");
    } catch (InstantiationException e) {
        e.printStackTrace();
        Log.e("print", "InstantiationException");
    } catch (IllegalAccessException e) {
        e.printStackTrace();
        Log.e("print", "IllegalAccessException");
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

// 直接调用对象方法, 而忽略修饰符(private, protected, default)
// @param object : 子类对象
// @param methodName : 父类中的方法名
// @param parameterTypes : 父类中的方法参数类型
// @param parameters : 父类中的方法参数
// @return 父类中方法的执行结果
public static Object invokeMethod(Object object, String methodName,
                                  Class<?> [] parameterTypes,Object [] parameters) {
    //根据 对象、方法名和对应的方法参数 通过反射 调用上面的方法获取 Method 对象
    Method method = getDeclaredMethod(object, methodName, parameterTypes) ;
    //抑制Java对方法进行检查,主要是针对私有方法而言
    method.setAccessible(true) ;
    try {
        if(null != method) {
            //调用object 的 method 所代表的方法,其方法的参数是 parameters
            return method.invoke(object, parameters);
        }
    } catch (IllegalArgumentException e) {
        e.printStackTrace();
    } catch (IllegalAccessException e) {
        e.printStackTrace();
    } catch (InvocationTargetException e) {
        e.printStackTrace();
    }
    return null;
}

// 循环向上转型, 获取对象的 DeclaredMethod
// @param object : 子类对象
// @param methodName : 父类中的方法名
// @param parameterTypes : 父类中的方法参数类型
// @return 父类中的方法对象
public static Method getDeclaredMethod(Object object, String methodName, Class<?> ... parameterTypes){
    Method method;
    for(Class<?> clazz = object.getClass() ; clazz != Object.class ; clazz = clazz.getSuperclass()) {
        try {
            method = clazz.getDeclaredMethod(methodName, parameterTypes) ;
            return method ;
        } catch (Exception e) {
            //这里甚么都不要做!并且这里的异常必须这样写,不能抛出去。
            //如果这里的异常打印或者往外抛,则就不会执行clazz = clazz.getSuperclass(),最后就不会进入到父类中了
        }
    }
    return null;
}

二、不使用PrinterShare服务,虽然下面的方法可以和打印机建立连接但是并不能控制打印机,发送的命令打印机没有反应。是否是需要打印机驱动,还有如何在Android中调用打印机驱动与打印机进行信息交流呢?

  1. 获取手机外接usb设备
    USBManager usbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
    HashMap<String, UsbDevice> deviceList = usbManager.getDeviceList();
    List<UsbDevice> list;
    Iterator<Map.Entry<String, UsbDevice>> iterator = deviceList.entrySet().iterator();
    while (iterator.hasNext()) {

       Map.Entry<String, UsbDevice> entry2 = iterator.next();
       list.add(entry2.getValue());

    }

  2. 点击列表获取设备的UsbEndpoint
    listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {

           @Override
           public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
               UsbEndpoint end_in, end_out;
               UsbDevice usbDevice = list.get(position);
               UsbInterface usbInterface = usbDevice.getInterface(0);
               int j = usbInterface.getEndpointCount();
               for (int i = 0; i < j; i++) {
                   // getEndpoint(index)对于指定的index获得此接口的一个节点,返回一个UsbEndpoint
                   UsbEndpoint localUsbEndpoint = usbInterface.getEndpoint(i);
    
                   // getDirection返回的是一个整数,128(USB_DIR_IN)代表in,0(USB_DIR_OUT)代表out
                   if (localUsbEndpoint.getDirection() == 128) {
                       end_in = localUsbEndpoint;
                   } else if (localUsbEndpoint.getDirection() == 0) {
                       end_out = localUsbEndpoint;
                   }
               }
           }

    });

  3. 请求临时接入权限
    private void requestPermission(UsbDevice paramUsbDevice) {

       PendingIntent localPendingIntent = PendingIntent.getBroadcast(this,
               0, new Intent(ACTION_USB_PERMISSION),PendingIntent.FLAG_UPDATE_CURRENT);
               
       // USB设备请求临时的接入权限
       usbManager.requestPermission(paramUsbDevice, localPendingIntent);

    }

  4. 建立连接,通过UsbEndpoint发送消息
    UsbDeviceConnection connection = usbManager.openDevice(usbDevice);
    if (end_out != null && connection != null) {

       connection.claimInterface(usbInterface, true);
       String cmdClear = "" + (char)29 + (char)86 + (char)66 + (char)0;
       try {
           output = cmdClear.getBytes("GBK");
       } catch (UnsupportedEncodingException e) {
           e.printStackTrace();
       }
       // bulkTransfer通过给定的endpoint来进行大量的数据传输,传输的方向取决于该节点的方向,
       // 传输成果返回传输字节数组的长度,失败返回负数
       int flag = connection.bulkTransfer(end_out, output, output.length, 0);
       if (flag < 0) {
           Toast.makeText(LocalPrinterActivity.this, "传输失败!",
                   Toast.LENGTH_SHORT).show();
       }else{
           Toast.makeText(LocalPrinterActivity.this, "传输成功flag="+flag,
                   Toast.LENGTH_SHORT).show();
       }
       if (connection != null) {
           connection.releaseInterface(usbInterface);
           connection.close();
       }

    }

【热门文章】
【热门文章】