文章目录

  • 蓝牙概述
  • Android蓝牙开发
  • 判断是否支持蓝牙
  • 打开蓝牙
  • 搜索蓝牙设备
  • 配对
  • 连接打印机


蓝牙概述

蓝牙,是一种支持设备短距离通信(一般10m内)的无线电技术,能在包括移动电话、PDA、无线耳机、笔记本电脑、相关外设等众多设备之间进行无线信息交换。利用“蓝牙”技术,能够有效地简化移动通信终端设备之间的通信,也能够成功地简化设备与因特网Internet之间的通信,从而数据传输变得更加迅速高效,为无线通信拓宽道路。(copy自百度

Android蓝牙开发

在Android蓝牙开发中,主要用到BluetoothManageBluetoothAdapter这两个类,从名字上看一个是蓝牙管理器,一个是蓝牙适配器。下面来看下怎么使用:

  1. 开发蓝牙相关的APP,首先要在清单文件中声明:
<uses-permission android:name="android.permission.BLUETOOTH" />
    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
    <!-- android5.0以上需要定位权限 -->
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
  1. BluetoothManager和BluetoothAdapter
//BluetoothManager通过getSystemService获取
var bluetoothManager:BluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
// BluetoothAdapter可以通过BluetoothManager获取,也可以通过BluetoothAdapter获取
var adapter = bluetoothManager.adapter
adapter = BluetoothAdapter.getDefaultAdapter()

判断是否支持蓝牙

var bluetoothManager:BluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
var adapter = bluetoothManager.adapter
if (adapter == null) {//如果adapter为空,不支持蓝牙
    Toast.makeText(this,"Bluetooth is not supported by the device",Toast.LENGTH_SHORT).show()
    return
}

打开蓝牙

class MainActivity : AppCompatActivity() {

    val REQUEST_ENABLE_BT = 2

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var bluetoothManager:BluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        var adapter = bluetoothManager.adapter
        if (adapter == null) {
            Toast.makeText(this, "Bluetooth is not supported by the device", Toast.LENGTH_SHORT)
                .show()
            return
        } else {
            if (!adapter.isEnabled) {//未开启
                var enableIntent: Intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                startActivityForResult(enableIntent, REQUEST_ENABLE_BT)
            } else {
                //TODO 蓝牙开启
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == Activity.RESULT_OK) {
                //TODO 蓝牙开启
            } else {
                // bluetooth is not open
                Toast.makeText(
                    this, "蓝牙没有开启",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }
}

搜索蓝牙设备

搜索蓝牙设备,需要注册个广播接收者,然后系统搜索到蓝牙设备的时候,系统会发送广播通知我们。

class MainActivity : AppCompatActivity() {

    val REQUEST_ENABLE_BT = 2

    private var mDevicesArrayAdapter: ArrayList<String> = ArrayList()

    val mFindBlueToothReceiver = object : BroadcastReceiver() {
        override fun onReceive(context: Context, intent: Intent) {
            var action = intent.action
            if (BluetoothDevice.ACTION_FOUND == action) {
                // 找到新的蓝牙设备
                var device : BluetoothDevice? =
                    intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE)
                if (device?.bondState != BluetoothDevice.BOND_BONDED) {
                    mDevicesArrayAdapter.add(device?.name + "\n" + device?.address + "\n" + "未配对")
                }
            }else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED == action) {
                // 扫描完成
                BluetoothAdapter.getDefaultAdapter().cancelDiscovery()
            }
        }
    }

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        var bluetoothManager:BluetoothManager = getSystemService(Context.BLUETOOTH_SERVICE) as BluetoothManager
        var adapter = bluetoothManager.adapter
        if (adapter == null) {
            Toast.makeText(this, "Bluetooth is not supported by the device", Toast.LENGTH_SHORT)
                .show()
            return
        } else {
            if (!adapter.isEnabled) {//未开启
                var enableIntent: Intent = Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE)
                startActivityForResult(enableIntent, REQUEST_ENABLE_BT)
            } else {
                //TODO 蓝牙开启
                getDeviceList()
            }
        }
    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == REQUEST_ENABLE_BT) {
            if (resultCode == Activity.RESULT_OK) {
                //TODO 蓝牙开启
                getDeviceList()
            } else {
                // bluetooth is not open
                Toast.makeText(
                    this, "蓝牙没有开启",
                    Toast.LENGTH_SHORT
                ).show()
            }
        }
    }

    private fun getDeviceList() {
        // Register for broadcasts when a device is discovered
        var filter = IntentFilter(BluetoothDevice.ACTION_FOUND)
        this.registerReceiver(mFindBlueToothReceiver, filter)
        // Register for broadcasts when discovery has finished
        filter = IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)
        this.registerReceiver(mFindBlueToothReceiver, filter)
        var adapter = BluetoothAdapter.getDefaultAdapter()
        val bondedDevices: Set<BluetoothDevice> = adapter.bondedDevices //获取已配对蓝牙列表
        if (bondedDevices.size > 0) {
            for (device in bondedDevices) {
                mDevicesArrayAdapter.add(device.name + "\n" + device.address + "\n" + "已配对")
            }
        }
        adapter.startDiscovery() // 开始扫描
    }
}

配对

获取蓝牙设备的MAC地址就可以进行配对了,这里假设我们获取了某个蓝牙设备的MAC地址

val remoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress()) //这里传入蓝牙的mac地址
var method: Method? = null
try {
    if (remoteDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
        method = BluetoothDevice::class.java.getMethod("createBond")
        Log.e("log", "开始配对")
        method.invoke(remoteDevice)
    }
} catch (e: Exception) {
    e.printStackTrace()
}

连接打印机

Thread(Runnable {
    val remoteDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress()) //这里传入蓝牙的mac地址
    var method: Method? = null
    try {
        if (remoteDevice.getBondState() != BluetoothDevice.BOND_BONDED) {
            method = BluetoothDevice::class.java.getMethod("createBond")
            Log.e("log", "开始配对")
            method.invoke(remoteDevice)
        }
    } catch (e: Exception) {
        e.printStackTrace()
    }

    var socket: BluetoothSocket? = null
    try {
        // 蓝牙串口服务对应的UUID。如使用的是其它蓝牙服务,需更改下面的字符串
        if (BluetoothAdapter.checkBluetoothAddress(remoteDevice.getAddress())) {
            val MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB")
            socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID)
            val connected = socket!!.isConnected
            try {
                if (!connected) {
                    socket.connect()
                }
            } catch (e: Exception) {
                Log.i("log", "关闭重连")
                socket.close()
                socket = device.createInsecureRfcommSocketToServiceRecord(MY_UUID)
                if (!connected) {
                    socket!!.connect()
                }
                Log.i("log", "重连失败")
            }

            BluetoothUtils.setBluetoothSocket(socket)
            Log.d("log", "连接成功")
            runOnUiThread {
                Toast.makeText(applicationContext, "连接成功", Toast.LENGTH_SHORT).show()
                finish()
            }

        }

    } catch (e: Exception) {
        try {
            if (socket != null) {
                socket.close()
                socket = null
            }
        } catch (e1: Exception) {
            e.printStackTrace()
        }

        e.printStackTrace()
        Log.d("log", "获取Socket失败")
        runOnUiThread {
            Toast.makeText(applicationContext, "连接失败", Toast.LENGTH_SHORT).show()
        }
    }
}).start()
public class BluetoothUtils {

	private static BluetoothSocket mmSocket = null;
	
	public static void setBluetoothSocket(BluetoothSocket socket) {
		mmSocket = socket;
	}
	
	public static BluetoothSocket getBluetoothSocket() {
		if(mmSocket != null) {
			return mmSocket;
		}
		return null;
	}
}

获取到BluetootSocket,就可以获取输入输出流

tmpIn = socket.getInputStream();
tmpOut = socket.getOutputStream();