zoukankan      html  css  js  c++  java
  • Android蓝牙通信

    Android为蓝牙设备之间的通信封装好了一些调用接口,使得实现Android的蓝牙通信功能并不困难。可通过UUID使两个设备直接建立连接。

    具体步骤:

    1. 获取BluetoothAdapter实例,注册一个BroadcastReceiver监听蓝牙扫描过程中的状态变化

    1
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
    1
    2
    IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
    registerReceiver(mReceiver, filter);
    1
     
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                String action = intent.getAction();
     
     
                // When discovery finds a device
                if (BluetoothDevice.ACTION_FOUND.equals(action))
                {
                    // Get the BluetoothDevice object from the Intent
                    // 通过EXTRA_DEVICE附加域来得到一个BluetoothDevice设备
                    BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                     
                    // If it's already paired, skip it, because it's been listed already
                    // 如果这个设备是不曾配对过的,添加到list列表
                    if (device.getBondState() != BluetoothDevice.BOND_BONDED)
                    {
                        list.add(new ChatMessage(device.getName() + " " + device.getAddress(), false));
                        clientAdapter.notifyDataSetChanged();
                        mListView.setSelection(list.size() - 1);
                    }
                // When discovery is finished, change the Activity title
                }
                else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
                {
                    setProgressBarIndeterminateVisibility(false);
                    if (mListView.getCount() == 0)
                    {
                        list.add(new ChatMessage("没有发现蓝牙设备", false));
                        clientAdapter.notifyDataSetChanged();
                        mListView.setSelection(list.size() - 1);
                    }
                }
            }
        };

    2. 打开蓝牙(enable),并设置蓝牙的可见性(可以被其它设备扫描到,客户端是主动发请求的,可不设置,服务端必须设置可见)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
           if (mBluetoothAdapter != null) {
        if (!mBluetoothAdapter.isEnabled()) {
            // 发送打开蓝牙的意图,系统会弹出一个提示对话框
            Intent enableIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(enableIntent, RESULT_FIRST_USER);
             
            // 设置蓝牙的可见性,最大值3600秒,默认120秒,0表示永远可见(作为客户端,可见性可以不设置,服务端必须要设置)
            Intent displayIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            displayIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 0);
            startActivity(displayIntent);
             
            // 直接打开蓝牙
            mBluetoothAdapter.enable();
        }
    }

    3. 扫描,startDiscovery()方法是一个很耗性能的操作,在扫描之前可以先使用getBondedDevices()获取已经配对过的设备(可直接连接),避免不必要的消耗。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
      private void scanDevice() {
        // TODO Auto-generated method stub
        if (mBluetoothAdapter.isDiscovering()) {
            mBluetoothAdapter.cancelDiscovery();
        } else {
             
            // 每次扫描前都先判断一下是否存在已经配对过的设备
            Set<bluetoothdevice> pairedDevices = mBluetoothAdapter.getBondedDevices();
            if (pairedDevices.size() > 0) {
                for (BluetoothDevice device : pairedDevices) {
                    list.add(new ChatMessage(device.getName() + " " + device.getAddress(), true));
                }
            } else {
                    list.add(new ChatMessage("No devices have been paired", true));
                    clientAdapter.notifyDataSetChanged();
                    mListView.setSelection(list.size() - 1);
             }             
                 /* 开始搜索 */
                 mBluetoothAdapter.startDiscovery();
        }
    }</bluetoothdevice>

    4. 通过Mac地址发送连接请求,在这之前必须使用cancelDiscovery()方法停止扫描。

    1
    2
    3
    4
            mBluetoothAdapter.cancelDiscovery();
     
    // 通过Mac地址去尝试连接一个设备
    BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(BluetoothMsg.BlueToothAddress);

    5. 通过UUID使两个设备之间建立连接。

    客户端:主动发请求

    1
    2
    3
    4
    BluetoothSocket socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
                    
    // 通过socket连接服务器,这是一个阻塞过程,直到连接建立或者连接失效
    socket.connect();

    服务端:接受一个请求

    1
    2
    3
    4
    5
    6
    7
    BluetoothServerSocket mServerSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(PROTOCOL_SCHEME_RFCOMM,
                       UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));      
                
    /* 接受客户端的连接请求 */
    // 这是一个阻塞过程,直到建立一个连接或者连接失效
    // 通过BluetoothServerSocket得到一个BluetoothSocket对象,管理这个连接
    BluetoothSocket socket = mServerSocket.accept();

    6. 通过InputStream/outputStream读写数据流,已达到通信目的。

    1
    2
    OutputStream os = socket.getOutputStream();
    os.write(msg.getBytes());
    1
    2
    3
    4
    5
    6
    7
    InputStream is = null;
    try {
        is = socket.getInputStream();
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }

    7. 关闭所有线程以及socket,并关闭蓝牙设备(disable)。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
            if (mClientThread != null) {
        mClientThread.interrupt();
        mClientThread = null;
    }
    if (mReadThread != null) {
        mReadThread.interrupt();
        mReadThread = null;
    }
    try {
        if (socket != null) {
            socket.close();
            socket = null;
        }
    } catch (IOException e) {
        // TODO: handle exception
    }
    1
    2
    3
    4
    5
    6
            if (mBluetoothAdapter != null) {
        mBluetoothAdapter.cancelDiscovery();
        // 关闭蓝牙
        mBluetoothAdapter.disable();
    }
    unregisterReceiver(mReceiver);


    主要步骤就是这些,为了能够更好的理解,我将服务器端和客户端的代码分开来写了两个程序,下载地址:http://download.csdn.net/detail/visionliao/8417235

    结伴旅游,一个免费的交友网站:www.jieberu.com

    推推族,免费得门票,游景区:www.tuituizu.com

  • 相关阅读:
    New starting
    Ubuntu中PyCharm中字体设置
    pyshp操作shapefile
    GIS的数学基础
    向mysql中插入Date类型的数据
    mysql多字段排序
    干掉命令行窗口下MySql乱码
    JavaWeb中读取文件资源的路径问题
    Java中9种IO的读取方式
    JavaIO 将数据写入到文件中去
  • 原文地址:https://www.cnblogs.com/rabbit-bunny/p/4283296.html
Copyright © 2011-2022 走看看