android:Bluetooth学习笔记

来源:互联网 发布:手机有透视软件吗 编辑:程序博客网 时间:2024/05/17 04:19

最近做一个项目,看了官方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 = newIntent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);//定时区间为[0,3600],不在区间内默认为1200sstartActivity(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) { }    }}







0 0
原创粉丝点击