首页 > 代码库 > Android蓝牙通信

Android蓝牙通信

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

   具体步骤:

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

mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);registerReceiver(mReceiver, filter);
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() + "\n" + 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),并设置蓝牙的可见性(可以被其它设备扫描到,客户端是主动发请求的,可不设置,服务端必须设置可见)。

               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()获取已经配对过的设备(可直接连接),避免不必要的消耗。

      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() + "\n" + device.getAddress(), true));
		        }
		    } else {
		        	list.add(new ChatMessage("No devices have been paired", true));
		        	clientAdapter.notifyDataSetChanged();
		    		mListView.setSelection(list.size() - 1);
		     }				
	             /* 开始搜索 */
	             mBluetoothAdapter.startDiscovery();
		}
	}

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

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

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

         客户端:主动发请求

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

        服务端:接受一个请求        

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

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

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

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

     

                        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
				}
                if (mBluetoothAdapter != null) {
			mBluetoothAdapter.cancelDiscovery();
			// 关闭蓝牙
			mBluetoothAdapter.disable();
		}
		unregisterReceiver(mReceiver);

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


Android蓝牙通信