android:Bluetooth学习笔记

最近做一个项目,看了官方API,学习了关于蓝牙的一些知识,分享一下,如果有错,欢迎指正。

一、权限设置

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

二、创建蓝牙

1、获得本地适配器

BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
    // 设备不支持蓝牙功能
}
2、a使能蓝牙

if (!mBluetoothAdapter.isEnabled()) {
    Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
    startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
REQUEST_ENABLE_BT,大于0的整型数,系统通过传递该参数回到onActivityResult()实现请求码参数,请求码有:RESULT_OK(成功使能蓝牙)和RESULT_CANCELED(使能蓝牙失败或者发生错误).
监听广播意图 ACTION_STATE_CHANGED ,包含两个属性EXTRA_STATE和EXTRA_PREVIOUS_STATE,可能取值有STATE_TURNING_ON、STATE_ON、STATE_TURNING_OFFSTATE_OFF,监听广播可以有效地检测蓝牙状态变化当运行APP时。
b定时使能蓝牙
Intent discoverableIntent = new
Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//定时区间为[0,3600],不在区间内默认为1200s
startActivity(discoverableIntent);
类似的,ACTION_SCAN_MODE_CHANGED广播意图包含两个属性:EXTRA_SCAN_MODE和EXTRA_PREVIOUS_SCAN_MODE。可能取值有:发现模式SCAN_MODE_CONNECTABLE_DISCOVERABLE 、非发现模式可连接SCAN_MODE_CONNECTABLE 、非发现模式不可连接SCAN_MODE_NONE。
3、发现设备                                                                                                                           a、查找配对设备                                                                                                             调用getBondedDevices()方法查找配对设备
Set<BluetoothDevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
// 如果有配对设备
if (pairedDevices.size() > 0) {
    // 遍历撇对设备
    for (BluetoothDevice device : pairedDevices) {
        // 在ListView显示存到数组适配器中的名字、地址
        mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
    }
}
b、搜索设备                                                                                                             调用startDiscovery()方法搜索设备                                                                                       为了ACTION_FOUND意图,注册广播接收器,以便于接受每个发现设备的信息,在每个设备,系统会广播ACTION_FOUND意图。ACTION_FOUND包含EXTRA_DEVICE、EXTRA_CLASS两个属性值。(包含了BluetoothDecice和BluetoothClass包)
// 为ACTION_FOUND注册广播接收机
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        // 当搜索到一个设备
        if (BluetoothDevice.ACTION_FOUND.equals(action)) {
            // 从意图中获得BluetoothDevice对象
            BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            // Add the name and address to an array adapter to show in a ListView
            mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
        }
    }
};
// 注册广播接收机
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter); // 记得在onDestroy取消注册
注意:当找到可连接设备,调用cancelDiscovery()方法在尝试连接之前停止搜索设备。连接时不要执行搜索。
4、连接设备                                                                                                         a作为服务器连接  建立server socket接受一个连接:                                                                    调用listenUsingRfcommWithServiceRecord(String, UUID)方法获得BluetoothServerSocket(UUID:Universally Unique Identifier通用唯一识别码)                                                                                                    b调用accept()方法监听连接请求                                                                                       c调用close()方法                                                                                                    注意:accept()是阻塞调用,不能用在主活动的UI线程。
private class AcceptThread extends Thread {
    private final BluetoothServerSocket mmServerSocket;
 
    public AcceptThread() {
        // Use a temporary object that is later assigned to mmServerSocket,
        // because mmServerSocket is final
        BluetoothServerSocket tmp = null;
        try {
            // MY_UUID is the app's UUID string, also used by the client code
            tmp = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(NAME, MY_UUID);
        } catch (IOException e) { }
        mmServerSocket = tmp;
    }
 
    public void run() {
        BluetoothSocket socket = null;
        // Keep listening until exception occurs or a socket is returned
        while (true) {
            try {
                socket = mmServerSocket.accept();
            } catch (IOException e) {
                break;
            }
            // If a connection was accepted
            if (socket != null) {
                // Do work to manage the connection (in a separate thread)
                manageConnectedSocket(socket);
                mmServerSocket.close();
                break;
            }
        }
    }
 
    /** Will cancel the listening socket, and cause the thread to finish */
    public void cancel() {
        try {
            mmServerSocket.close();
        } catch (IOException e) { }
    }
}
上述例子中,只需要传入一个连接,一旦连接,就需要Bluetooth分开线程,关闭BluetoothServerSocket,打断循环。 注意:当accept()方法返回BluetoothServerSocket时已连接,所以你不需要调用connect()方法。当完成对连接的监听后,总是关闭BluetoothServerSocket,如上述例子。你也可以提供一个公用方法在新线程中以关闭私有的BluetoothSocket在需要监听Sercer socket的事件中。
b作为客户端连接                                                                                                  1、调用createRfcommSocketToServiceRecord(UUID)获取BluetoothSocket对象,完成初始化。                             2、调用connect()初始化连接(阻塞,需分开线程)下面是一个初始化蓝牙连接的线程
rivate class ConnectThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final BluetoothDevice mmDevice;
 
    public ConnectThread(BluetoothDevice device) {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
        BluetoothSocket tmp = null;
        mmDevice = device;
 
        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
        } catch (IOException e) { }
        mmSocket = tmp;
    }
 
    public void run() {
        // Cancel discovery because it will slow down the connection
        mBluetoothAdapter.cancelDiscovery();
 
        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket.connect();
        } catch (IOException connectException) {
            // Unable to connect; close the socket and get out
            try {
                mmSocket.close();
            } catch (IOException closeException) { }
            return;
        }
 
        // Do work to manage the connection (in a separate thread)
        manageConnectedSocket(mmSocket);
    }
 
    /** Will cancel an in-progress connection, and close the socket */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}
注意:在连接之前调用cancelDiscovery()方法
c管理连接 ——传输任意数据
private class ConnectedThread extends Thread {
    private final BluetoothSocket mmSocket;
    private final InputStream mmInStream;
    private final OutputStream mmOutStream;
 
    public ConnectedThread(BluetoothSocket socket) {
        mmSocket = socket;
        InputStream tmpIn = null;
        OutputStream tmpOut = null;
 
        // Get the input and output streams, using temp objects because
        // member streams are final
        try {
            tmpIn = socket.getInputStream();
            tmpOut = socket.getOutputStream();
        } catch (IOException e) { }
 
        mmInStream = tmpIn;
        mmOutStream = tmpOut;
    }
 
    public void run() {
        byte[] buffer = new byte[1024];  // buffer store for the stream
        int bytes; // bytes returned from read()
 
        // Keep listening to the InputStream until an exception occurs
        while (true) {
            try {
                // Read from the InputStream
                bytes = mmInStream.read(buffer);
                // Send the obtained bytes to the UI activity
                mHandler.obtainMessage(MESSAGE_READ, bytes, -1, buffer)
                        .sendToTarget();
            } catch (IOException e) {
                break;
            }
        }
    }
 
    /* Call this from the main activity to send data to the remote device */
    public void write(byte[] bytes) {
        try {
            mmOutStream.write(bytes);
        } catch (IOException e) { }
    }
 
    /* Call this from the main activity to shutdown the connection */
    public void cancel() {
        try {
            mmSocket.close();
        } catch (IOException e) { }
    }
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值