票据打印机-蓝牙的开关

前言

14年时候做过一个可穿戴设备,对传统的蓝牙了解过一点,但是当我这次看android.bluetooth的官方文档的时候明白了,作为一个安卓程序员,关注安卓的发展;作为IT人员,关注科技发展的重要性
虽然当时也听说过BLE的蓝牙,但是可能是由于各厂商不同,所以也没有一个统一的文档,近些年穿戴设备越来越火,可能就是因为蓝牙的发展,
所以现在面对我的有传统蓝牙和低功耗蓝牙(ble),对低功耗蓝牙的介绍和使用会在以后更新,这一次先用传统的蓝牙文档吧

文档介绍

蓝牙可以使用无线的方式让两个不同的设备之间进行数据的传输.

  • BluetoothAdapter类:

    代表本地蓝牙适配器(蓝牙无线电)。BluetoothAdapter是所有蓝牙交互的入口。使用这个你可以发现其他蓝牙设备,查询已配对的设备列表,使用一个已知的MAC地址来实例化一个BluetoothDevice,以及创建一个BluetoothServerSocket来为监听与其他设备的通信。

    • getDefaultAdapter():得到本地蓝牙适配器
    • getBondedDevices():返回BluetoothDevice对象,里面包括与本机蓝牙所有绑定的远程蓝牙信息
    • getName():获取蓝牙设备Name
    • disable():关闭蓝牙(是关闭蓝牙而不是关闭此连接)
    • enable():打开蓝牙
    • isEnabled():判断蓝牙是否已启用并准备使用
    • getAddress():得到蓝牙的MAC地址
    • getRemoteDevice(byte[] address):以给定的MAC地址去创建一个 BluetoothDevice 类实例(代表远程蓝牙实例)。即使该蓝牙地址不可见,也会产生一个BluetoothDevice 类实例。
  • BluetoothDevice类:

    代表一个远程蓝牙设备,使用这个来请求一个与远程设备的BluetoothSocket连接,或者查询关于设备名称、地址、类和连接状态等设备信息。BluetoothDevice,以及创建一个BluetoothServerSocket来为监听与其他设备的通信。

    • createRfcommSocketToServiceRecord(UUID uuid):由UUID得到待连接的BluetoothSocket对象,准备建立通道.UUID就是蓝牙设备串口号,具体UUID介绍请百度.
    • getAddress():得到蓝牙的MAC地址
    • getName():获取蓝牙设备Name
  • BluetoothSocket类:

    代表一个蓝牙socket的接口(和TCP Socket类似)。这是一个连接点,它允许一个应用与其他蓝牙设备通过InputStream和OutputStream交换数据。

    • close():关闭通道,断开连接
    • connect():使待连接的通道连接上

有了这些,建立连接就很简单了,

  1. 先创建一个空的BluetoothAdapter对象,mBluetoothAdapter.getDefaultAdapter()拿到本机蓝牙设备适配器
  2. mBluetoothAdapter.isEnabled()判断本机蓝牙是否已启用并准备使用,若没开启则startActivity(new Intent(android.provider.Settings.ACTION_SETTINGS));;若开启则继续
  3. mBluetoothAdapter.getBondedDevices()拿到与本机蓝牙所有绑定的远程蓝牙信息
  4. 用远程蓝牙信息(BluetoothDevice)调用getAddress()方法,获取远程蓝牙设备的MAC地址
  5. 再由这个地址调用getRemoteDevice(byte[] address)返回一个BluetoothDevice对象,就拿到远程设备实例.至此我们获得了远程的设备地址,接下来去连接他
  6. mBluetoothDevice.createRfcommSocketToServiceRecord(UUID);这个方法返回了BluetoothSocket对象,那么我们就由本机实例得到了UUID这个通道下的远程设备的Bluetoothsocket连接
  7. mBluetoothsocket.connect();
  8. ……
  9. mBluetoothsocket.close();

总结一下:类比一下socket连接,这里的mac地址呢,就类似于Ip地址,而UUID则类似于端口号,这样想就容易理解的多.

最后贴一下蓝牙部分的代码片段

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();//获得本设备的蓝牙适配器实例
...
...
 try {
            if (mBluetoothAdapter == null) {
        //做一个提示
            } else if (mBluetoothAdapter.isEnabled()) {
                String getName = mBluetoothAdapter.getName();//获取蓝牙设备Name
                pairedDevices = mBluetoothAdapter.getBondedDevices();//获取与本机蓝牙所有绑定的远程蓝牙信息

                for (BluetoothDevice device : pairedDevices) {
                    // Add the name and address to an array adapter to
                    // show in a ListView
                    getName = device.getName() + "#" + device.getAddress();//获取蓝牙设备的硬件地址(MAC地址)
                    mpairedDeviceList.add(getName);
                }
            } else {
                //做打开蓝牙的一个跳转
            }
        } catch (Exception e) {
        }
 public static int connBluetooth(BaseActivity v, String temString, BluetoothAdapter mBluetoothAdapter) {
        mBluetoothSocket = ((ApplicationData) v.getApplication()).getSocket();
        if (mBluetoothSocket != null) {
            try {
                mBluetoothSocket.close();
            } catch (Exception e) {

            } finally {
                ((ApplicationData) v.getApplication()).setSocket(null);
                return 0;
            }            
        }
        temString = temString.substring(temString.length() - 17);
        try {
            //以给定的MAC地址去创建一个 BluetoothDevice 类实例(代表远程蓝牙实例)。即使该蓝牙地址不可见,也会产生一个BluetoothDevice 类实例。
            mBluetoothDevice = mBluetoothAdapter.getRemoteDevice(temString);
            mBluetoothSocket = mBluetoothDevice.createRfcommSocketToServiceRecord(SPP_UUID);
            mBluetoothSocket.connect();
            ((ApplicationData) v.getApplication()).setSocket(mBluetoothSocket);
            return 1;
        } catch (Exception e) {
            return 0;
        }
    }

可以看到,这里我把mBluetoothSocket对象设置成了全局变量,有两个原因,一是因为蓝牙打印模版很多,要在每个页面都获取这个BluetoothSocket,二是监听与打印机是否连接需要用他作为反馈.

public class ApplicationData extends Application {
    private BluetoothSocket socket;  //保存蓝牙通道

    @Override
    public void onCreate() {
        super.onCreate();
        socket = null;
        setSocket(socket);
    }

    public BluetoothSocket getSocket() {
        return socket;
    }

    public void setSocket(BluetoothSocket socket) {
        this.socket = socket;
    }

}

上面这是全局变量的保存,记着注册记着注册注册!

全局变量的设置还有一个考虑就是面对一些突发状况,和难处理的另类操作,和程序变为后台等等,这里我面要设置一个广播来随时监听我们的连接状况.下面就不单独介绍常量值的意义了,代码简单易懂.

/**
 * Created by Qit
 * 2017/8/8 0008.
 */

public class BluetoothReceiver extends BroadcastReceiver {
    BluetoothSocket bluetoothSocket;

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        bluetoothSocket = ((ApplicationData) context.getApplicationContext()).getSocket();
        //Toast.makeText(context, "蓝牙状态改变广播", Toast.LENGTH_LONG).show();
        Button btn_conn = ((BaseActivity) context).$(R.id.btn_conn);
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            Toast.makeText(context, device.getName() + " 设备已发现", Toast.LENGTH_LONG).show();
        } else if (BluetoothDevice.ACTION_ACL_CONNECTED.equals(action)) {
            Toast.makeText(context, device.getName() + "已连接", Toast.LENGTH_LONG).show();
            btn_conn.setText("已连接");
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECT_REQUESTED.equals(action)) {
            Toast.makeText(context, device.getName() + "正在断开蓝牙连接。。。", Toast.LENGTH_LONG).show();
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {
            Toast.makeText(context, device.getName() + "蓝牙连接已断开", Toast.LENGTH_LONG).show();
            if (!((ApplicationData) context.getApplicationContext()).getSocket().equals(null)) {
                ((ApplicationData) context.getApplicationContext()).setSocket(null);
            }
            btn_conn.setText("未连接");
        } else if (action.equals(BluetoothAdapter.STATE_OFF)) {
            Toast.makeText(context, "蓝牙已关闭", Toast.LENGTH_LONG).show();
        } else if (action.equals(BluetoothAdapter.STATE_ON)) {
            Toast.makeText(context, "蓝牙打开", Toast.LENGTH_LONG).show();
        }
    }
}

比如打印机断电,那么蓝牙通道会关闭,此时要及时反映这个状况,可将APP内的按钮设为未连接状态和等等等…

至此蓝牙连接基本结束了,有什么没考虑到的请留言我,谢谢

蓝牙连接了,下面介绍使用ESC/POS指令集来设置打印机格式

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Qi T

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值