1: 思路

百度百科的介绍

所谓蓝牙打印机,就是指在主机端用一单片机来仿真打印机进行工作,截取从主机并口传出的数据及控制信号,并通过蓝牙无线连接传送到打印机端。在打印机侧的单片机则根据所收到的蓝牙数据来仿真主机对打印机进行控制操作,从而实现打印机与主机的蓝牙无线连接.

具体逻辑

由于蓝牙的协议栈比较复杂, 以及蓝牙的状态机相关的代码也比较多, 所以实现的方式可以通过framework代码注入一个假的蓝牙打印机设备, 然后用户可以连接这个打印机。

蓝牙打印机是通过Socket连接的, 所以可以在打开蓝牙的时候, 开启一个ServerSocket, 连接蓝牙打印机的时候, 真实就是连接这个ServerSocket。

注意事项

碰到一个巨坑的BUG, 口碑外卖, 蓝牙打印连接成功, 但是UI没有更新。

最后通过反编译的方式, 发现口碑的UI更新是通过监听蓝牙连接变化的广播实现的。

最后在虚拟蓝牙连接和断开的时候加上相应的广播就可以了。

public static final String ACTION_ACL_CONNECTED =

"android.bluetooth.device.action.ACL_CONNECTED";

public static final String ACTION_ACL_DISCONNECT_REQUESTED =

"android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED";

2: 实现

1: framework修改

BluetoothSocket.java 根据虚拟的蓝牙地址建立一个本地Socket。

public void connect() throws IOException {

...

if(BluetoothDevice.BLUETOOTH_ADDRESS.equals(mAddress)){

Log.d(TAG, "Address: " + mAddress);

mSocket = new LocalSocket();

mSocket.connect(new LocalSocketAddress(BluetoothDevice.BLUETOOTH_NAME));

mSocketIS = mSocket.getInputStream();

mSocketOS = mSocket.getOutputStream();

return;

}else{

mSocket = new LocalSocket(fd);

}

...

}

2: Bluetooth修改

AdapterProperties.java 注入假的蓝牙设备

static void deviceFoundCallback(Context context) {

BluetoothDevice device = BluetoothDevice.createSimulateDevice(BluetoothDevice.BLUETOOTH_ADDRESS);

Intent intent = new Intent(BluetoothDevice.ACTION_FOUND);

intent.putExtra(BluetoothDevice.EXTRA_DEVICE, device);

intent.putExtra(BluetoothDevice.EXTRA_CLASS, new BluetoothClass(BluetoothClass.Device.Major.IMAGING));

intent.putExtra(BluetoothDevice.EXTRA_RSSI, 0);

intent.putExtra(BluetoothDevice.EXTRA_NAME, "Simulate Imaging");

context.sendBroadcast(intent, BLUETOOTH_PERM);

}

实现一个ServerSocket的服务端监听蓝牙打印请求, AdapterService.java 开启和关闭这个ServerSocket.

3: 打印客户端

普通的打印服务

public boolean connect() {

Log.e("Gank", "1 connect()");

System.out.println("2 connect()");

if (!this.isConnection) {

try {

bluetoothSocket = this.device

.createRfcommSocketToServiceRecord(uuid);

bluetoothSocket.connect();

outputStream = bluetoothSocket.getOutputStream();

this.isConnection = true;

if (this.bluetoothAdapter.isDiscovering()) {

System.out.println("关闭适配器!");

this.bluetoothAdapter.isDiscovering();

}

} catch (Exception e) {

Toast.makeText(this.context, "连接失败!", Toast.LENGTH_SHORT).show();

Log.e("Gank", "", e);

System.out.println("1" + e);

return false;

}

Toast.makeText(this.context, this.device.getName() + "连接成功!",

Toast.LENGTH_SHORT).show();

return true;

} else {

return true;

}

}

/**

* 发送数据

*/

public void send(String sendData) {

if (this.isConnection) {

System.out.println("开始打印!!");

try {

byte[] data = sendData.getBytes();

outputStream.write(data, 0, data.length);

outputStream.flush();

} catch (IOException e) {

Toast.makeText(this.context, "发送失败!", Toast.LENGTH_SHORT)

.show();

}

} else {

Toast.makeText(this.context, "设备未连接,请重新连接!", Toast.LENGTH_SHORT)

.show();

}

}

Android蓝牙打印服务,Android 模拟蓝牙打印机相关推荐

  1. android 打印机服务,Android系统打印服务插件printservice开发

    一 简介 从Android4.4开始,系统加入了打印相关的API,可以通过系统打印服务实现打印.对于需要使用打印功能的APP可参考官方教程接入打印服务. 这不是本文的内容,本文介绍打印机厂商如何使自己 ...

  2. Android蓝牙打印服务,GitHub - ZhuangXiong/BluetoothPrint: android bluetooth print .蓝牙打印

    Android 蓝牙打印 入口和回调方便,目前只针对一个打印模板做了封装. 没有扫描设备功能,后期会加入.用户需要先去 设置---蓝牙---配对设备,配对完成后,可以获取手机上已配对的设备信息,从而进 ...

  3. android 蓝牙打印格式,Android蓝牙打印格式排版

    最近由于项目需求,在做蓝牙打印的功能.Android连接蓝牙打印机网上满天飞,但是内容的排版却很少. 我也是研究了下,自己封装了一个工具类希望可以方便开发. 这个类叫 BluetoothPrintFo ...

  4. 精臣b3s蓝牙打印服务

    1.使用场景 蓝牙打印机 后台自动连接蓝牙,并实现蓝牙打印功能.不切入业务代码 2.示例代码 package com..service;import android.app.Service; impo ...

  5. android wifi 打印文件,android – 将文件发送到WiFi打印机

    我正在开发一个应用程序,在我的手机中,我通过IP地址和端口号将文件发送到WiFi打印机,它们是.txt,.png,.jpg,.doc.它们应该从打印机打印出来.我试过以下代码,但它只给我输出.txt文 ...

  6. android四大组件 服务,Android四大组件之Service

    Service Service(服务)是一个可以在后台执行长时间运行操作而不使用用户界面的应用组件.服务可由其他应用组件启动,而且即使用户切换到其他应用,服务仍将在后台继续运行. 此外,组件可以绑定到 ...

  7. android打开位置服务,Android - 位置定位(Location)服务(Service)类的基本操作

    位置定位(Location)服务(Service)类的基本操作 本文地址: http://blog.csdn.net/caroline_wendy 定位服务(Location Service),能够确 ...

  8. Android 进程 缓存服务,Android获取应用程序大小和缓存的实例代码

    info package com.qin.appsize; import android.content.Intent; import android.graphics.drawable.Drawab ...

  9. android无法实例化服务,Android:无法实例化类:没有空的构造函数

    请看下面,我得到一个无法实例化类:当试图运行我的"HomeFragmentListExpand"类时,LogCat中没有空的构造函数错误,即使我清楚地有一个空的构造函数那里.And ...

最新文章

  1. Flomaster 2020中文版
  2. 小米开源文件管理器MiCodeFileExplorer-源码研究(3)-使用最多的工具类Util
  3. 企业级控件库之大数据量分页控件 (非原创)
  4. LRN和Batch Norm
  5. Codeforces Gym - 100917 部分题解
  6. “约见”面试官系列之常见面试题之第八十七篇之ajax发送多个请求优化(建议收藏)
  7. linux下gdb的简单使用
  8. 键盘上每个键作用!!! (史上最全的)­
  9. 拉格朗日插值的优缺点_拉格朗日插值法与牛顿插值法比较
  10. VS开发Qt应用时遇到“找不到VCRUNTIME140D_APP.dIl,无法继续执行代码”的错误
  11. FCoin“暴雷”投资人该怎么办?律师这样建议
  12. 健康人寿保险服务平台
  13. JSP系列一:JSP简介
  14. 【已解决】华为手机如何关闭智慧助手·今天(负一屏) | 华为荣耀八手机智慧助手开关介绍 | 华为手机关闭负一屏开关后,仍接收到负一屏服务相关通知提醒怎么办
  15. [(1+1)2] ?
  16. 一步一步创建Sencha Architect Files(aux)
  17. linux命令如何查询某个线程,linux如何查看线程信息命令是什么
  18. msql 5.5 5.6 5.7 8.0 区别
  19. html电子书软件电脑版,4Easysoft PDF to HTML Converter
  20. 电气控制与PLC例题分析(第一章)

热门文章

  1. AI为什么救不了“想上天”的猪?
  2. 售后服务场景智能调度解决方案
  3. OpenCV 常用函数汇总(bitwise_*、pointPolygonTest、morphologyEx)
  4. iphone8位置无法连接服务器,iphone8无法连接到app store怎么办?苹果iphone8连接不到app store解决方法...
  5. 实验记录 | SpeedSeq安装
  6. mysql报错:check the manual that corresponds to your MySQL server version for the right syntax to use
  7. 二叉树【按层打印、序列化、反序列化】
  8. 国科大学习资料--人工智能原理与算法-第十次作业解析(学长整理)
  9. docker启动mysql失败(闪退)原因
  10. python兔子编程_Python兔子生兔子算法,编程练习题实例十一