Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Android 開發中 iBeacon的使用

Android 開發中 iBeacon的使用

編輯:關於Android編程

 

 

iBeacon的工作原理是基於Bluetooth Low Energy(BLE)低功耗藍牙傳輸技術,iBeacon基站不斷向四周發送藍牙信號,當智能設備進入設定區域時,就能夠收到信號。只要滿足iBeacon技術標准的都可以使用,所以Android也能夠支持iBeacon。Google在Android4.3中支持BLE技術

定位一直是非常關鍵的功能。通過iBeacon基站的部署能夠實現室內導航,同時通過藍牙推送信息,iBeacon在商場零售或者一些公共服務領域如體育館、博物館能提供非常棒的體驗。尤其是藍牙不錯傳輸距離、低功耗、以及信號加密使得iBeacon在移動支付領域也非常有前景。總之,iBeacon的潛力似乎是無窮大,也受到了越來越多的關注。

要了解iBeacon是如何工作首先我們要了解BLE。BLE(也稱為Bluetooth Smart)最早追溯到Nokia於2006年提出的Wibree,後來融合進了藍牙標准,成為Bluetooth4.0的一部分。目前我們經常能看到3種藍牙設備:

  • Bluetooth:只支持傳統模式的藍牙設備
  • Bluetooth Smart Ready:支持傳統和低功耗兩種模式設備
  • Bluetooth Smart:只支持低功耗藍牙設備

    estimote-ibeacon-teardown2

     

    BLE與傳統的藍牙相比最大的優勢是功耗降低90%,同時傳輸距離增大(超過100米)、安全和穩定性提高(支持AES加密和CRC驗證)。iBeacon同時有一些自己的特點:

    • 無需配對,一般藍牙設備印象中都需要配對工作。iBeacon無需配對,因為它是采用藍牙的廣播頻道傳送信號。
    • 程序可以後台喚醒,iBeacon的信息推送需要App支持。但是我們接收iBeacon信號無需打開App,只要保證安裝了,同時手機藍牙打開。

      iBeacon是如何工作呢?實際上iBeacon基站通過藍牙的廣播頻道不斷向外發送位置信息,發送頻率越快越耗電。也就是說iBeacon並不推送消息,而只是用於定位,推送消息的功能必須由App來完成。蘋果定義了iBeacon 其中32位廣播的數據格式。

      estimote-ibeacon-teardown3
      • UUID:廠商識別號
        
        
      • Major:相當於群組號,同一個組裡Beacon有相同的Major
      • Minor:相當於識別群組裡單個的Beacon
      • TX Power:用於測量設備離Beacon的距離

         

        UUID+Major+Minor就構成了一個Beacon的識別號,有點類似於網絡中的IP地址。TX Power用於測距,iBeacon目前只定義了大概的3個粗略級別:

        • 非常近(Immediate): 大概10厘米內
        • 近(Near):1米內
        • 遠(Far):1米外

          這裡主要是對其用法做一個介紹:

          首先是獲取BluetoothAdapter對象:

           

          final BluetoothManager bluetoothManager =
                          (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
                  mBluetoothAdapter = bluetoothManager.getAdapter();
                  mBluetoothAdapter.startLeScan(mLeScanCallback);

           

          
          然後就是它的回調,在這裡對搜索到的iBeacon設備距手機的距離做了一個排序
          

           

           

          private BluetoothAdapter.LeScanCallback mLeScanCallback =
                      new BluetoothAdapter.LeScanCallback() {
          
                  @Override
                  public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) {
                  	final iBeacon ibeacon = iBeaconClass.fromScanData(device,rssi,scanRecord);
                  	addDevice(ibeacon);
                  	Collections.sort(mLeDevices, new Comparator() {
              			@Override
              			public int compare(iBeacon h1, iBeacon h2) {
              				return h2.rssi - h1.rssi;
              			}
              		});
                  }
              };
          最後把搜索到的數據添加到集合中去

           

           

          private ArrayList mLeDevices = new ArrayList();
              private void addDevice(iBeacon device) { //更新beacon信息
          		if(device==null) {
          			Log.d(DeviceScanActivity , device==null );
          			return;
          		}
          		
          		for(int i=0;i
          
          

           

          我們在iBbeaconClass類中對其進行數據的解析處理,參考:https://github.com/AltBeacon/android-beacon-library

           

          public class iBeaconClass {
          
              static public  class iBeacon{
              	public String name;
              	public int major;
              	public int minor;
              	public String proximityUuid;
              	public String bluetoothAddress;
              	public int txPower;
              	public int rssi;
              }
              public static iBeacon fromScanData(BluetoothDevice device, int rssi,byte[] scanData) {
          
              	int startByte = 2;
          		boolean patternFound = false;
          		while (startByte <= 5) {
          			if (((int)scanData[startByte+2] & 0xff) == 0x02 &&
          				((int)scanData[startByte+3] & 0xff) == 0x15) {			
          				// yes!  This is an iBeacon	
          				patternFound = true;
          				break;
          			}
          			else if (((int)scanData[startByte] & 0xff) == 0x2d &&
          					((int)scanData[startByte+1] & 0xff) == 0x24 &&
          					((int)scanData[startByte+2] & 0xff) == 0xbf &&
          					((int)scanData[startByte+3] & 0xff) == 0x16) {
                          iBeacon iBeacon = new iBeacon();
          				iBeacon.major = 0;
          				iBeacon.minor = 0;
          				iBeacon.proximityUuid = 00000000-0000-0000-0000-000000000000;
          				iBeacon.txPower = -55;
          				return iBeacon;
          			}
                      else if (((int)scanData[startByte] & 0xff) == 0xad &&
                               ((int)scanData[startByte+1] & 0xff) == 0x77 &&
                               ((int)scanData[startByte+2] & 0xff) == 0x00 &&
                               ((int)scanData[startByte+3] & 0xff) == 0xc6) {
                             
                              iBeacon iBeacon = new iBeacon();
                              iBeacon.major = 0;
                              iBeacon.minor = 0;
                              iBeacon.proximityUuid = 00000000-0000-0000-0000-000000000000;
                              iBeacon.txPower = -55;
                              return iBeacon;
                      }
          			startByte++;
          		}
          
          
          		if (patternFound == false) {
          			// This is not an iBeacon
          			return null;
          		}
          
          		iBeacon iBeacon = new iBeacon();
          
          		iBeacon.major = (scanData[startByte+20] & 0xff) * 0x100 + (scanData[startByte+21] & 0xff);
          		iBeacon.minor = (scanData[startByte+22] & 0xff) * 0x100 + (scanData[startByte+23] & 0xff);
          		iBeacon.txPower = (int)scanData[startByte+24]; // this one is signed
          		iBeacon.rssi = rssi;
          
          		// AirLocate:
          		// 02 01 1a 1a ff 4c 00 02 15  # Apple's fixed iBeacon advertising prefix
          		// e2 c5 6d b5 df fb 48 d2 b0 60 d0 f5 a7 10 96 e0 # iBeacon profile uuid
          		// 00 00 # major 
          		// 00 00 # minor 
          		// c5 # The 2's complement of the calibrated Tx Power
          
          		// Estimote:		
          		// 02 01 1a 11 07 2d 24 bf 16 
          		// 394b31ba3f486415ab376e5c0f09457374696d6f7465426561636f6e00000000000000000000000000000000000000000000000000
          
          		byte[] proximityUuidBytes = new byte[16];
          		System.arraycopy(scanData, startByte+4, proximityUuidBytes, 0, 16); 
          		String hexString = bytesToHexString(proximityUuidBytes);
          		StringBuilder sb = new StringBuilder();
          		sb.append(hexString.substring(0,8));
          		sb.append(-);
          		sb.append(hexString.substring(8,12));
          		sb.append(-);
          		sb.append(hexString.substring(12,16));
          		sb.append(-);
          		sb.append(hexString.substring(16,20));
          		sb.append(-);
          		sb.append(hexString.substring(20,32));
          		iBeacon.proximityUuid = sb.toString();
          
                  if (device != null) {
                      iBeacon.bluetoothAddress = device.getAddress();
                      iBeacon.name = device.getName();
                  }
          
          		return iBeacon;
          	}
          
              public static String bytesToHexString(byte[] src){  
                  StringBuilder stringBuilder = new StringBuilder();  
                  if (src == null || src.length <= 0) {  
                      return null;  
                  }  
                  for (int i = 0; i < src.length; i++) {  
                      int v = src[i] & 0xFF;  
                      String hv = Integer.toHexString(v);  
                      if (hv.length() < 2) {  
                          stringBuilder.append(0);  
                      }  
                      stringBuilder.append(hv);  
                  }  
                  return stringBuilder.toString();  
              }  
          }

           

           

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved