美文网首页
Android手机蓝牙总结之传统蓝牙

Android手机蓝牙总结之传统蓝牙

作者: Jarly_Sun | 来源:发表于2018-05-11 16:12 被阅读487次

最近,公司有一个项目时关于手机蓝牙和硬件蓝牙相互通信的需求。基于之前很久没有学习硬件的知识,这次记录下来,以备下次需要时使用。

首先,需要搞清楚一些基本的概要,蓝牙3.0以前的是传统蓝牙,4.0以后的是低功耗蓝牙,Android蓝牙在不同手机系统版本也有不同的蓝牙,当然也有不一样的调用方法。android4.3(API18)版本以下的对应的是传统蓝牙,在扫描的时候等待时间会比较长。android4.3以上的是低功耗蓝牙,但是android4.3版本到5.0版本的调用方法和android5.0以上的调用方法是不一样的。android用传统的蓝牙连接方式是无法和低功耗蓝牙模块建立通信通道的,因为通信的协议是不一样的。低功耗蓝牙是用GATT这种属性传输协议,而传统蓝牙则是通过Socket的方式进行数据的传输。

android蓝牙权限在6.0以上增加了一个模糊定位的权限,不开启部分手机无法进行扫描蓝牙发出的广播。

蓝牙权限:

为了能够在你开发的应用设备中使用蓝牙功能,必须声明蓝牙的权限"BLUETOOTH"。在进行蓝牙的通信,例如请求连接,接受连接以及交换数据中,需要用到该权限。

<use-permission android:name="android.permission.BLUETOOTH"/>

如果你的应用程序需要实例化蓝牙设备的搜索或者对蓝牙的设置进行操作,那么必须声明BLUETOOTH_ADMIN权限。大多数应用需要该权限对本地的蓝牙设备进行搜索。该权限的其他能力并不应当被使用,除非你的应用是一个电源管理的应用,需要对蓝牙的设置进行修改

<use-permission android:name="android.permission.BLUETOOTH_ADMIN"/>

android 6.0版本之后增加模糊定位授权,如果不增加这个权限部分6.0以上的手机无法扫描出蓝牙。

<use-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>

开启关闭蓝牙:

在使用蓝牙通信之前,需要先开启,使用BluetoothAdapter来进行完成

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if(mBluetoothAdapter ==null) {// Device does not support Bluetooth}

如果BluetoothAdapter为null值,则表示此手机不支持蓝牙功能。

if(!mBluetoothAdapter.isEnabled()){ 
   Intent enableBtIntent =newIntent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
   startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

REQUEST_ENABLE_BT大于0的自己定义的int变量。isEnable()判断蓝牙是否可用。推荐使用这种方式进行开启蓝牙。

还有另一种方式开启,但是在部分手机不会弹出蓝牙的授权限页。

mBluetoothAdapter.enable()也能直接开启蓝牙。

搜索设备:

首先找到手机找出已匹配的蓝牙设备:

// 将已配对的设备添加到列表中
Set pairedDevices = mBluetoothAdapter.getBondedDevices();
if (pairedDevices.size() > 0) {
    for (BluetoothDevice device : pairedDevices) {
        mDevicesArray.add(device.getName() + "\n" + device.getAddress());
        deviceList.add(device);
    }
}

注册广播接收器并开启扫描:

IntentFilter filter = new IntentFilter();
 //注册设备被发现时的广播
filter.addAction(BluetoothDevice.ACTION_FOUND);
 //注册一个搜索结束时的广播  
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);

广播接收器:

public class BluetoothReceiver extends BroadcastReceiver {
    public final String TAG = getClass().getName();
    private BluetoothInterface bluetoothInterface;
    private List<BluetoothDevice> beans = null;

    public BluetoothReceiver(BluetoothInterface bluetoothInterface) {
        this.bluetoothInterface = bluetoothInterface;
        beans = new ArrayList<>();
    }

    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        //发现蓝牙广播
        if (action.equals(BluetoothDevice.ACTION_FOUND)) {
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            beans.add(device);
            //显示已配对设备
            if (device.getBondState() == BluetoothDevice.BOND_BONDED) {
                Log.e(TAG, "\n" + device.getName() + "==>" + device.getAddress() + "\n");
            } else if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
                Log.e(TAG, "\n" + device.getName() + "==>" + device.getAddress() + "\n");
            }
        //搜索完成回调
        } else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
            bluetoothInterface.discoveryCompleted(beans);
        }
    }
}

只要搜索没有完成,会一直接收外部蓝牙设备发送的广播。如果找到了对应的蓝牙设备,可以取消搜索。

mBluetoothAdapter.cancelDiscovery();

匹配和连接蓝牙

匹配蓝牙

//MY_UUID是蓝牙串口服务对应的应用UUID,网上有说不能写在UI线程,但我写在UI线程也没问题
BluetoothSocket socket =device.createRfcommSocketToServiceRecord(MY_UUID);

连接蓝牙

public class ConnectedThread extends Thread {
    private final BluetoothSocket mSocket;
    private final InputStream mInStream;
    private final OutputStream mOutStream;
    private Handler mHandler;
    public final static int MESSAGE_READ = 1;
    public final static int MESSAGE_EXCEPTIONS = 2;
    public final static int MESSAGE_SUCCESS = 3;

    public ConnectedThread(BluetoothSocket socket, Handler handler) {
        mSocket = socket;
        mHandler = handler;
        InputStream temIn = null;
        OutputStream temOut = null;
        try {
            temIn = socket.getInputStream();
            temOut = socket.getOutputStream();
        } catch (IOException e) {

        }
        mInStream = temIn;
        mOutStream = temOut;
    }

    @Override
    public void run() {
        try {
            mSocket.connect();
            mHandler.sendEmptyMessage(MESSAGE_SUCCESS);
        } catch (IOException e) {
            e.printStackTrace();
            mHandler.sendEmptyMessage(MESSAGE_EXCEPTIONS);
            try {
                mSocket.close();
            } catch (IOException e1) {
                e1.printStackTrace();
            }
        }
        int bytes;
        //对输入流保持监听直至一个异常发生
        while (true) {
            byte[] buffer = new byte[20];
            try {
                bytes = mInStream.read(buffer);
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }

    /**
     * 向蓝牙模块发射数据
     *
     * @param bytes
     */
    public void write(byte[] bytes) {
        try {
            mOutStream.write(bytes);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 关闭Socket的连接
     */
    public void cancel() {
        try {
            mSocket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

蓝牙在发送数据时有大小限制,一般为20字节,在6.0之后的版本可以进行设置大小。
如果有不正确的地方,可以在下面评论一起学习。

相关文章

  • Android手机蓝牙总结之传统蓝牙

    最近,公司有一个项目时关于手机蓝牙和硬件蓝牙相互通信的需求。基于之前很久没有学习硬件的知识,这次记录下来,以备下次...

  • Android手机蓝牙总结之低功耗蓝牙

    低功耗蓝牙也就是蓝牙4.0以后的版本,在android手机是4.3以后才支持。在项目中,开始使用了传统蓝牙去进行连...

  • android蓝牙专题

    深入了解Android蓝牙Bluetooth ——《总结篇》 安卓蓝牙应用程序编写步骤 蓝牙 bluetooth-...

  • <iOS开发>之蓝牙使用

    本文介绍了蓝牙的概念以及具体的使用步骤. 一.蓝牙概念 蓝牙2.0为传统蓝牙,传统蓝牙也称为经典蓝牙.蓝牙4.0因...

  • <iOS开发>之蓝牙使用

    本文介绍了蓝牙的概念以及具体的使用步骤. 一.蓝牙概念 蓝牙2.0为传统蓝牙,传统蓝牙也称为经典蓝牙.蓝牙4.0因...

  • Android蓝牙开发中电话音频(HSP,HFP)和媒体音频(A

    Android在蓝牙开发过程中,经常需要蓝牙成功连接后,控制像音箱,蓝牙灯之类的硬件。这时候,打开手机的蓝牙设置,...

  • Amdroid蓝牙开发基础

    Android蓝牙开发主要分为两大类,分别是传统蓝牙开发和BLE(Bluetooth Low Energy)低功耗...

  • 蓝牙驱动开发总结

    Android之蓝牙驱动开发总结 一[http://blog.csdn.net/manshq163com/arti...

  • 近场通信 蓝牙

    android应用层开发 近场通信 首选蓝牙 先了解一下:什么是蓝牙? 蓝牙是一种无线技术标准,可实现手机与手机,...

  • Android 上层蓝牙enable流程

    Android 蓝牙框架 基于Android9.0 Amlogic代码分析,蓝牙应用通过 Binder 与蓝牙进程...

网友评论

      本文标题:Android手机蓝牙总结之传统蓝牙

      本文链接:https://www.haomeiwen.com/subject/vbffdftx.html