首先说蓝牙分类:蓝牙貌似分为4.0,和2.0版本,4.0版本更省电(BLE)

判断方式如下: 是否支持蓝牙: getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH)

        是否支持BLE蓝牙 : getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)

//判断远端蓝牙类型:
BluetoothDevice类中有个方法getType();如果返回的是 BluetoothDevice.DEVICE_TYPE_CLASSIC;经典蓝牙,也就是2.0,若是则是 BluetoothDevice.DEVICE_TYPE_LE) {//低功耗蓝牙设备

注册蓝牙需要的广播:

IntentFilter action_found = new IntentFilter(BluetoothDevice.ACTION_FOUND);
getActivity().registerReceiver(mReceiver, action_found);
IntentFilter action_bond = new IntentFilter(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
getActivity().registerReceiver(mReceiver, action_bond);
IntentFilter action_disconnected = new IntentFilter(BluetoothDevice.ACTION_ACL_DISCONNECTED);
getActivity().registerReceiver(mReceiver, action_disconnected);
IntentFilter action_discover_end = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
getActivity().registerReceiver(mReceiver, action_discover_end);
IntentFilter action_pairing_request = new IntentFilter(ACTION_PAIRING_REQUEST);
getActivity().registerReceiver(mReceiver, action_pairing_request);
//蓝牙广播
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {//发现一台蓝牙设备
            addDevice(device);
        } else if (ACTION_PAIRING_REQUEST.equals(action)) {//新设备直接连接,不用用户输入pin码可以这么做;
            setBluetoothPairingPin(device);
        } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {//扫描附近设备完成)

        } else if (BluetoothDevice.ACTION_BOND_STATE_CHANGED.equals(action)) {//蓝牙连接状态改变
            int prevBondState = intent.getIntExtra(BluetoothDevice.EXTRA_PREVIOUS_BOND_STATE, -1);
            int bondState = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR);
            if (bondState == BluetoothDevice.BOND_BONDING) {
                Log.i(TAG, "蓝牙连接中:" + device.getName());
            } else if (bondState == BluetoothDevice.BOND_BONDED) {//已连接
                ((MainActivity) getActivity()).goTagFragment();
            } else if (bondState == BluetoothDevice.BOND_NONE) {
                Log.i(TAG, "蓝牙没有连接" + device.getName());
            } else if (bondState == BluetoothDevice.ERROR) {
                Log.i(TAG, "蓝牙连接错误" + device.getName());
                ToastUtils.show(R.string.error_bluetooth_connect);
                ((MainActivity) getActivity()).goConnectBluetoothFragment();
            }
        } else if (BluetoothDevice.ACTION_ACL_DISCONNECTED.equals(action)) {//断开连接
            Log.i(TAG, "蓝牙断开连接" + device.getName());
            ToastUtils.show(getString(R.string.bluetooth_disconnected));
            ((MainActivity) getActivity()).goConnectBluetoothFragment();
        }
    }
};

 

//准备配对去人配对码pin  
public void setBluetoothPairingPin(BluetoothDevice device) {
    String string = "1234";
    byte[] pinBytes = string.getBytes();
    try {
        //Log.d(TAG, "Try to set the PIN");
        Method m = device.getClass().getMethod("setPin", byte[].class);
        m.invoke(device, pinBytes);
        Log.d(TAG, "Success to add the PIN.");
        try {
            device.getClass().getMethod("setPairingConfirmation", boolean.class).invoke(device, true);
            Log.d(TAG, "Success to setPairingConfirmation.");
        } catch (Exception e) {
            // TODO Auto-generated catch block
            //       Log.e(TAG, e.getMessage());
            e.printStackTrace();
        }
    } catch (Exception e) {
        //  Log.e(TAG, e.getMessage());
        e.printStackTrace();
    }
}
//取消蓝牙配对
private void unpairDevice(BluetoothDevice device) {
    try {
        Method m = device.getClass().getMethod("removeBond", (Class[]) null);
        m.invoke(device, (Object[]) null);
        if (device.getAddress().equals(mLast_addr)) {
            sp.edit().putString(KEY_LAST_ADDR_STRING, "").commit();
            mLast_addr = "";
        }
    } catch (Exception e) {
        Log.e(TAG, e.getMessage());
    }
}
BluetoothAdapter是本地自己的蓝牙类,获取蓝牙方法:
 BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
bluetoothAdapter.isEnabled();是判断蓝牙是否打开;
打开蓝牙方式:
bluetoothAdapter.enable();打开蓝牙(不做提示,强行打开)
//弹出对话框提示用户是后打开
Intent enabler = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enabler, REQUEST_ENABLE_BT);
bluetoothAdapter.disable()  ;关闭蓝牙
bluetoothAdapter.cancelDiscovery();取消扫描
bluetoothAdapter.startDiscovery();开始扫描附近蓝牙设备
Set<BluetoothDevice> mBTpaired  = bluetoothAdapter.getBondedDevices();获取曾经连接过的设备
再连接前最好停止扫描调用
cancelDiscovery这样能够加速
低功耗BLE蓝牙,连接与传输都使用的是回调的方式
BluetoothDevice 中 .connectGatt(mContext, false, mGattCallback);方法连接,第一个是上下文,第二个是否自动连接,第三个是连接监听回调接接口,如下,创建,然后重写方法即可
/**
 * 连接与远端蓝牙回调
 */
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() 
其中这个
onConnectionStateChange方法中有个newstate是当前蓝牙连接状态,如果和 BluetoothProfile.STATE_CONNECTED一致则是连接完成,同时需要开线程准备写入工作,
mBluetoothGatt.getDevice();然后获取当前连接的设备是这个
经典蓝牙需要创建一个线程,然后通过
BluetoothSocket mmSocket  = BluetoothDevice.createRfcommSocketToServiceRecord(SPP_UUID);的方法获取套接字一般UUID使用:
// Unique UUID for this application这个应用程序的唯一UUID
// 此处,必须使用Android的SSP(协议栈默认)的UUID:SPP UUID: 00001101-0000-1000-8000-00805F9B34FB
private static final UUID SPP_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

然后通过获取的套接字连接,为什么开线程就是因为这里会堵塞:
// Connect the device through the socket. This will block until it succeeds or throws an exception
// 通过插座连接设备。它会阻塞,直到它成功或抛出异常
mmSocket.connect();
然后需要在通过获取到的套接字socket进行获取输入输出流
然后死循环一直进行
BluetoothSocket socket中的socket.getInputStream();获取输入流
socket.getOutputStream();获取输出流
在连接前同时我们需要也开死循环判断服务端是否连接状态,实现多途径连接状态
通过BluetoothServerSocket  =bluetoothAdapter的listenUsingRfcommWithServiceRecord获取一个服务端的socket需要传入一个name和uuid,  name用当前类名就行,uuid还用刚才的
然后死循环判断状态BluetoothServerSocket  .accept();可以获取一个BluetoothSocket