关于Android蓝牙打印和网络打印,其实都是利用Socket通信机制,只是蓝牙打印将socket做了一层封装BluetoothSocket ,打印的数据都是以流的方式进行传输或保存的,程序需要数据的时候要使用输入流读取数据,而当程序需要将一些数据保存起来的时候,就要使用输出流完成。

在java.io包中操作文件内容的主要有两大类:字节流、字符流,两类都分为输入和输出操作。在字节流中输出数据主要是使用OutputStream完成,输入使的是InputStream,在字符流中输出主要是使用Writer类完成,输入流主要使用Reader类完成。(这四个都是抽象类)

字节流可用于任何类型的对象,包括二进制对象,而字符流只能处理字符或者字符串; 字节流提供了处理任何类型的IO操作的功能,但它不能直接处理Unicode字符,而字符流就可以。字节流主要是操作byte类型数据,以byte数组为准,而打印指令是以字节数组形式存在的,所以对于打印,我们使用字符流进行读写操作。

对于蓝牙打印,需要的操作有:

  • 搜索蓝牙设备
  • 和蓝牙设备建立连接
  • 如果连接成功 则打印相应内容和命令(可以控制字体大小 等等一些指令)
  • 还可记住该台设备的蓝牙mac,下次可直接连接该设备进行打印

由于上述流程存在耗时操作,需要开一个线程,使用Thread+Handler处理

/*** 保持蓝牙连接的线程*/
public class BluetoothThread extends Thread {// 固定不变,表示蓝牙通用串口服务private static final UUID BLUETOOTH_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");private BluetoothSocket mSocket; // 蓝牙连接的socketprivate OutputStream mOutputStream;   // 用于打印数据的输出流private Handler mHandler;private Callback mCallback;private BluetoothDevice mDevice;public BluetoothThread(BluetoothDevice bondedDevice) throws Exception {mDevice = bondedDevice;if (bondedDevice.getBondState() != BluetoothDevice.BOND_BONDED) {throw new Exception("BluetoothDevice has not bonded.");}try {mSocket = bondedDevice.createRfcommSocketToServiceRecord(BLUETOOTH_UUID);  // 创建连接的Socket对象mSocket.connect();mOutputStream = mSocket.getOutputStream();} catch (IOException e) {if (mSocket != null) {try {mSocket.close();} catch (IOException e1) {e1.printStackTrace();}}throw new Exception("BluetoothDevice connect fail. " + e.getMessage());}}public void quit() {if (mHandler == null) {return;}mHandler.sendEmptyMessage(-1);}public void write(String text) {byte[] bytes = new byte[0];try {bytes = text.getBytes("GBK");} catch (UnsupportedEncodingException e) {e.printStackTrace();}write(bytes);}public void write(byte[] bytes) {if (mHandler == null) {return;}Message msg = mHandler.obtainMessage(0);msg.obj = bytes;mHandler.sendMessage(msg);}public boolean isInnerPrinter() {return "00:11:22:33:44:55".equals(mDevice.getAddress());}@Overridepublic void run() {Looper.prepare();mHandler = new Handler() {@Overridepublic void handleMessage(Message msg) {super.handleMessage(msg);if (msg.what == -1) {Looper looper = Looper.myLooper();if (looper != null) {looper.quit();}removeCallbacksAndMessages(null);mHandler = null;} else {byte[] bytes = (byte[]) msg.obj;try {mOutputStream.write(bytes);if (mCallback != null) {mCallback.onWriteFinished(mDevice);}} catch (IOException e) {if (mCallback != null) {mCallback.onWriteFail(mDevice);}}}}};Looper.loop();// 线程结束,则关闭try {mOutputStream.close();mSocket.close();} catch (IOException e) {e.printStackTrace();}}public void setCallback(Callback callback) {mCallback = callback;}interface Callback {void onWriteFinished(BluetoothDevice device);void onWriteFail(BluetoothDevice device);}
}

对于蓝牙连接和打印定义一个蓝牙管理类

/*** 负责蓝牙相关的业务逻辑*/
public class BluetoothManager {private static BluetoothManager sBluetoothManager; // 防止创建多次,设置为单例private Map<BluetoothDevice, BluetoothThread> mBluetoothThreadMap = new HashMap<>();   // 存储每个蓝牙设备连接成功时对应连接的线程private int mPrintingThreadCount = 0;private BluetoothManager() {// 通过getInstance()方法获取实例}/*** 获取当前类示例*/public synchronized static BluetoothManager getInstance() {if (sBluetoothManager == null) {sBluetoothManager = new BluetoothManager();}return sBluetoothManager;}/*** 连接蓝牙设备*/public boolean connect(BluetoothDevice device, Context context) {BluetoothAdapter.getDefaultAdapter().cancelDiscovery();BluetoothThread thread = mBluetoothThreadMap.get(device);if (thread == null) {try {thread = new BluetoothThread(device);thread.start();mBluetoothThreadMap.put(device, thread);// 连接的蓝牙设备无法确定的判断出是否是打印机,所以将所有连接上的蓝牙设备全部放到PrinterManager中PrinterManager.getInstance().register(GeneralPrinter.getPrinterThroughBluetooth(context, device.getAddress(), device.getName(), thread));return true;} catch (Exception e) {return false;}} else {return true;}}/*** 断开当前正在连接的蓝牙设备*/public void disconnect(Context context, BluetoothDevice device) {BluetoothThread thread = mBluetoothThreadMap.get(device);if (thread != null) {thread.quit();mBluetoothThreadMap.remove(device);// 断开连接时从PrinterManager中去除PrinterManager.getInstance().unregister(context, device.getAddress());}}/*** 断开所有设备*/public void disconnectAll() {for (BluetoothThread thread : mBluetoothThreadMap.values()) {thread.quit();}mBluetoothThreadMap.clear();}/*** 获取已经连接成功的蓝牙设备*/public List<BluetoothDevice> getConnectedDeviceList() {return new ArrayList<>(mBluetoothThreadMap.keySet());}public boolean hasConnectedDevice() {return !mBluetoothThreadMap.isEmpty();}private void preparePrint() {int count;do {synchronized (BluetoothManager.class) {count = mPrintingThreadCount;if (count <= 0) {mPrintingThreadCount = mBluetoothThreadMap.size();}}} while (count > 0);}public void printText(String text, final OnPrintListener listener) {if (TextUtils.isEmpty(text)) {return;}preparePrint();for (final BluetoothThread thread : mBluetoothThreadMap.values()) {if (thread.isInnerPrinter()) {IPrinter innerPrinter = PrinterManager.getInstance().getInnerPrinter();if (innerPrinter != null) {synchronized (BluetoothManager.class) {mPrintingThreadCount--;if (mPrintingThreadCount <= 0) {if (listener != null) {listener.onPrintFinished();}}}continue;}}thread.setCallback(new BluetoothThread.Callback() {@Overridepublic void onWriteFinished(BluetoothDevice device) {thread.setCallback(null);synchronized (BluetoothManager.class) {mPrintingThreadCount--;if (mPrintingThreadCount <= 0) {if (listener != null) {listener.onPrintFinished();}}}}@Overridepublic void onWriteFail(BluetoothDevice device) {thread.setCallback(null);if (listener != null) {listener.onPrintFail(device);}synchronized (BluetoothManager.class) {mPrintingThreadCount--;if (mPrintingThreadCount <= 0) {if (listener != null) {listener.onPrintFinished();}}}}});thread.write(text);}}public void printText(byte[] bytes, final OnPrintListener listener) {if (TextUtils.isEmpty(Arrays.toString(bytes))) {return;}preparePrint();for (final BluetoothThread thread : mBluetoothThreadMap.values()) {if (thread.isInnerPrinter()) {IPrinter innerPrinter = PrinterManager.getInstance().getInnerPrinter();if (innerPrinter != null) {synchronized (BluetoothManager.class) {mPrintingThreadCount--;if (mPrintingThreadCount <= 0) {if (listener != null) {listener.onPrintFinished();}}}continue;}}thread.setCallback(new BluetoothThread.Callback() {@Overridepublic void onWriteFinished(BluetoothDevice device) {thread.setCallback(null);synchronized (BluetoothManager.class) {mPrintingThreadCount--;if (mPrintingThreadCount <= 0) {if (listener != null) {listener.onPrintFinished();}}}}@Overridepublic void onWriteFail(BluetoothDevice device) {thread.setCallback(null);if (listener != null) {listener.onPrintFail(device);}synchronized (BluetoothManager.class) {mPrintingThreadCount--;if (mPrintingThreadCount <= 0) {if (listener != null) {listener.onPrintFinished();}}}}});thread.write(bytes);}}/*** 指定某个蓝牙设备打印文本内容** @param text 打印的文本内容*/public void printText(BluetoothDevice device, String text, final OnPrintListener listener) {if (TextUtils.isEmpty(text)) {return;}final BluetoothThread thread = mBluetoothThreadMap.get(device);if (thread != null) {if (listener != null) {thread.setCallback(new BluetoothThread.Callback() {@Overridepublic void onWriteFinished(BluetoothDevice device) {thread.setCallback(null);listener.onPrintFinished();}@Overridepublic void onWriteFail(BluetoothDevice device) {thread.setCallback(null);listener.onPrintFail(device);}});}thread.write(text);  // 打印文本}}public interface OnPrintListener {void onPrintFinished();void onPrintFail(BluetoothDevice device);}
}

以上就是Android蓝牙打印整个流程,蓝牙打印可以同时连接多个打印机(一般情况下连2-3个没什么问题,如果多了,机器可能撑不住而直接崩溃 ,这和机器的硬件有关。)

Android打印机--蓝牙打印相关推荐

  1. Android 实现蓝牙打印的功能

    第一步:首先需要一个蓝牙打印工具类 import android.bluetooth.BluetoothSocket; import android.graphics.Bitmap; import a ...

  2. Android打印机--小票打印格式及模板设置

    小票打印就是向打印设备发送控制打印格式的指令集,而这些打印格式需要去查询对应打印机的API文档,这里我把常用的api给封装了一下 文字对齐方式 打印字体大小 字体是否加粗 打印二维码 打印条形码 切纸 ...

  3. Android连接蓝牙打印机实现PDF文档的打印

    目前网上教程与Demo介绍的都是蓝牙连接热敏打印机(pos机大小的打印机),如果想通过蓝牙连接日常所见到的打印机,进行打印,这些教程或Demo是做不到的. 目前Android的蓝牙并不支持BPP(Ba ...

  4. Android打印机--TSC 标签打印

    打印机按照连接方式分为USB打印机.蓝牙打印机.网络打印机.云打印机.内联打印机:按照打印纸张大小分为带切刀的80厨房打印机和58热敏票据打印机:按照打印结果分为小票打印机和标签打印机:关于小票打印, ...

  5. Android 蓝牙打印指令

    一.概述 目前打印打印机支持的无线打印方式一般为wifi和蓝牙. 蓝牙打印关于蓝牙连接部分请查看上篇文章 -> Android 蓝牙连接 ,本篇文章讨论Android中蓝牙打印的指令实现. 蓝牙 ...

  6. Android蓝牙打印服务,Android 模拟蓝牙打印机

    1: 思路 百度百科的介绍 所谓蓝牙打印机,就是指在主机端用一单片机来仿真打印机进行工作,截取从主机并口传出的数据及控制信号,并通过蓝牙无线连接传送到打印机端.在打印机侧的单片机则根据所收到的蓝牙数据 ...

  7. android 蓝牙打印机(ESC/POS 热敏打印机),打印菜单小票和图片,对蓝牙配对和连接打印功能进行了封装,让你超快实现蓝牙打印功能

    BluetoothPrint 项目地址:liuGuiRong18/BluetoothPrint  简介:android 蓝牙打印机(ESC/POS 热敏打印机),打印菜单小票和图片,对蓝牙配对和连接打 ...

  8. android 蓝牙打印兼容,在Android中使用蓝牙打印机打印不起作用

    我正在开发应用程序,允许用户创建PDF并允许使用蓝牙打印机进行打印. 我创建了PDF,但每当我要使用蓝牙打印机集成打印功能时,都会出现错误. 我无法获得蓝牙设备列表. 如果您有任何示例代码,请提供给我 ...

  9. android打印机没反应了,使用蓝牙打印机在Android中打印不起作用

    我正在研究的应用程序允许用户创建PDF,并且还允许使用蓝牙打印机打印它. 我创建了PDF,但每当我打算使用蓝牙打印机集成打印功能时,它就会在那里发生错误. 我无法获取蓝牙设备列表. 如果您有任何示例代 ...

最新文章

  1. scala函数式编程(二) scala基础语法介绍
  2. linux hdparm 测试磁盘io,hdparm测试硬盘性能
  3. vux 实现多栏滚动
  4. python实现两数之和
  5. xay loves or 异或
  6. Linux内存管理之一 分段与分页
  7. GM6 pageset - DB get scenario
  8. JavaScript Unicode字符操作
  9. IT男出轨概率最高是哪家机构得出的统计结论?
  10. 自学python能干什么-python能干啥
  11. 图解cgroup架构中cgroup与css之间的多对多的关系
  12. 软考网络工程师备考经验分享
  13. 端到端矢量化高清地图学习框架VectorMapNet
  14. RJ45网线水晶头线序,568A与568B区别,交叉线与直连线区别,10/100M base TX RJ45 接口引脚功能定义
  15. c语言1%3等于多少,%取余语句1%3等于多少的作用
  16. NHibernate Step by Step (三) Configuration和Sessionfactory
  17. 创业案例:如何调整股权,才不伤害合伙人感情?
  18. 基于单片机的电机转速测量设计
  19. java中的就近原则、方法中值传递和引用传递的区别、什么是构造方法、this关键字用法、什么是封装
  20. JDBC,你真的知道怎么用吗?

热门文章

  1. 【文智背后的奥秘】系列篇——基于CRF的人名识别
  2. 3D Game Pr ramming Design(五):与游戏世界交互(对象池)
  3. 浦发银行信息科技岗运维2020校招面试分享
  4. 102 613 SWP协议学习笔记--通讯流程参考
  5. sqlserver各版本的介绍对比
  6. Gtalent如何帮助HR确定人才测评指标
  7. AndroidRuntime: FATAL EXCEPTION: OkHttp Dispatcher
  8. oracle存储过程sql und,oracle导入sql脚本
  9. 阿尔茨海默病及其先兆分期的神经影像分类研究及相关特征提取
  10. Python游戏之Pygame——太空飞机大战(二)