1. 程式人生 > >藍芽技術(BlueTooth)——(一)

藍芽技術(BlueTooth)——(一)

一,概述

    藍芽是一種短距離的無線通訊技術標準。

    藍芽協議分為4層,即核心協議層,電纜替代協議層,電話控制協議層,和      採納的其它協議層。

    這4中協議中最重要的是核心協議。藍芽的核心協議包括基帶,鏈路管理,邏輯鏈路控制和適應協議四部分。其中鏈路管理(LMP)負責藍芽元件間連線的建立。邏輯鏈路控制與適應協議(L2CAP)位於基帶協議層上,屬於資料鏈路層,是一個為高層傳輸和應用層協議遮蔽基帶協議的適配協議。

二,程式碼開啟藍芽的方式

  方式一:  

  if(bluetoothAdapter==null || !bluetoothAdapter.isEnabled()){
                    Intent enableBtIntent=new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
                    startActivityForResult(enableBtIntent,1);
                }

   第二種方式:

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

 BluetoothAdapter bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
        bluetoothAdapter.enable();
        bluetoothAdapter.disable();


三,通過程式碼搜尋藍芽裝置

1,搜尋普通藍芽裝置

//3,掃描附近的裝置

                if(bluetoothAdapter.isDiscovering()){
                    bluetoothAdapter.cancelDiscovery();
                }else{
                    //每次掃描之前都先判斷一下是否存在已久配對的裝置
                    Set<BluetoothDevice> paireDevices=bluetoothAdapter.getBondedDevices();
                    if(paireDevices.size()>0){
                        for(BluetoothDevice device :paireDevices){
                            Map map=new HashMap();
                            map.put("deviceName",device.getName());
                            map.put("deviceAddress",device.getAddress());
                            map.put("bluetooth_status","已配對");

                            deviceList.add(map);


                        }
                        Log.i("之前已經繫結過的裝置:",deviceList.toString());
                    }
                    bluetoothAdapter.startDiscovery();//開始搜尋

/*監聽掃描過程中的變化*/
    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)
                {
                    Message msg=new Message();
                    msg.what=1;
                    Bundle bundle=new Bundle();
                    bundle.putString("deviceName",device.getName());
                    bundle.putString("deviceAddress",device.getAddress());
                    msg.setData(bundle);
                    handler.sendMessage(msg);

                    Map map=new HashMap();
                    map.put("deviceName",device.getName());
                    map.put("deviceAddress",device.getAddress());
                    Log.i("掃描到的新裝置:",map.toString());
                    Log.i("加入新裝置之後,掃描到的總裝置:",deviceList.toString());
                }
                // When discovery is finished, change the Activity title
            }
            else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action))
            {
                Log.i("掃描結束------掃描到的總裝置:",deviceList.toString());
               handler.obtainMessage(0).sendToTarget();
            }
        }
    };

2,搜尋BLE裝置

 // Device scan callback.
    private BluetoothAdapter.LeScanCallback mLeScanCallback =
            new BluetoothAdapter.LeScanCallback() {
                @Override
                public void onLeScan(final BluetoothDevice device, int rssi,
                                     byte[] scanRecord) {
                    runOnUiThread(new Runnable() {
                        @Override
                        public void run() {
                            Map map=new HashMap();
                            map.put("deviceName",device.getName());
                            map.put("deviceAddress",device.getAddress());
                            map.put("bluetooth_status","BLE裝置");
                            Log.i("掃描到新的BLE裝置:",map.toString());
                            deviceList.add(map);
                        }
                    });
                }
            };

    // Stops scanning after 10 seconds.
    private static final long SCAN_PERIOD = 10000;
    private void scanLeDevice(final boolean enable) {
        if (enable) {
            // Stops scanning after a pre-defined scan period.
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    mScanning = false;
                    bluetoothAdapter.stopLeScan(mLeScanCallback);
                }
            }, SCAN_PERIOD);

            mScanning = true;
            bluetoothAdapter.startLeScan(mLeScanCallback);
        } else {
            mScanning = false;
            bluetoothAdapter.stopLeScan(mLeScanCallback);
        }

    }

四,如何用藍芽進行資料傳輸

     通過藍芽傳輸資料與Socket類似。在網路中使用Socket和ServerSocket控制客戶端和服務端的資料讀寫。而藍芽通訊也由客戶端和服務端Socket來完成。藍芽客戶端Socket是BluetoothSocket,藍芽服務端Socket是BluetoothServerSocket。這兩個類都在android.bluetooth包中。

      無論是BluetoothSocket,還是BluetoothServerSocket,都需要一個UUID來標識,格式如下:

      此UUID是一個8-4-4-4-12的字串。

      UUID相當於Socket的埠,而藍芽地址相當於Socket的IP。

      兩個藍芽裝置進行連線時,需要使用同一個UUID。一些時候,很多型號的手機(可能是安卓機和水果機)之間使用了不同的程式也可以使用藍芽進行通訊。表面上看,他們之間幾乎不肯能使用同一個UUID。

      實際上,UUID和TCP的埠一樣,也有一些預設的值。例如,講藍芽模擬成串列埠的服務就使用了一個標準的UUID:00001101-0000-1000-8000-00805F9B34FB.除此之外,還有很多標準的UUID,比如:

    資訊同步服務:00001104-0000-1000-8000-00805F9B34FB.

    檔案傳輸服務:00001106-0000-1000-8000-00805F9B34FB。