android獲取ibeacon列表的方法
更新時間:2018年10月31日 08:32:32 作者:fulushan的技術專欄
這篇文章主要為大家詳細介紹了android獲取ibeacon列表的方法,具有一定的參考價值,感興趣的小伙伴們可以參考一下
android獲取ibeacon列表,供大家參考,具體內容如下
最近公司有需要做ibeacon需求。
因為涉及掃碼的時間。特意寫一個service實現(xiàn)獲取列表 可以根據(jù)掃描時間掃描出ibeacon列表
包含 uuid,設備名稱,單位(米),電量等。
請根據(jù)自己的項目進行改造代碼。
核心代碼如下:
/** * * <ibeaon服務> * * @author fulushan * @date 創(chuàng)建時間:2018年4月5日 下午11:34:04 */ public class IbeaconService extends Service { private static final String TAG = IbeaconService.class.getName(); ArrayList<IBeaconClass.iBeacon> mLeDevices; private boolean mScanning; private final static int DATA_COMPLETE = 0; private final static int DATA_FAIL = 1; /**搜索BLE終端*/ private BluetoothAdapter mBluetoothAdapter; // Stops scanning after 10 seconds. private static long SCAN_PERIOD = 10000; ResponseResult responseResult = new ResponseResult(); public class IbeaconBinder extends Binder{ public ResponseResult getResponseResult(){ return responseResult; } } @Override public IBinder onBind(Intent arg0) { // TODO Auto-generated method stub return null; } @Override public void onStart(Intent intent, int startId) { super.onStart(intent, startId); if (intent != null) { SCAN_PERIOD = intent.getIntExtra("time",10)*1000; mLeDevices = new ArrayList<>(); //開啟一個新的線程,如果使用Service,會導致ANR問題,Service本身也會阻塞 new Thread(new IbeaconRunnable()).start(); } } @Override public void onDestroy() { super.onDestroy(); stopUpdateService(); scanLeDevice(false); } class IbeaconRunnable implements Runnable { Message message = handler.obtainMessage(); public void run() { try { //獲取藍牙數(shù)據(jù) //開始判斷 // Use this check to determine whether BLE is supported on the device. Then you can // selectively disable BLE-related features. if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { message.what = DATA_FAIL; responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode()); responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg()); message.obj = responseResult; handler.sendMessage(message); return; } if(Build.VERSION.SDK_INT<JELLY_BEAN_MR2){ responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode()); responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg()); message.obj = responseResult; handler.sendMessage(message); return; } // Initializes a Bluetooth adapter. For API level 18 and above, get a reference to // BluetoothAdapter through BluetoothManager. final BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) { mBluetoothAdapter = bluetoothManager.getAdapter(); } if(!mBluetoothAdapter.isEnabled()){ responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode()); responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg()); message.obj = responseResult; handler.sendMessage(message); return; } // Checks if Bluetooth is supported on the device. if (mBluetoothAdapter == null) { responseResult.setStatus(BlueToothEnum.BLU_SERVICE_UNAVAI.getCode()); responseResult.setMsg(BlueToothEnum.BLU_SERVICE_UNAVAI.getMsg()); message.obj = responseResult; handler.sendMessage(message); return; } //開啟藍牙 mBluetoothAdapter.enable(); scanLeDevice(true); } catch (Exception ex) { ex.printStackTrace(); message.what = DATA_FAIL; //下載失敗 handler.sendMessage(message); } } } @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) private void scanLeDevice(final boolean enable) { if (enable) { // Stops scanning after a pre-defined scan period. handler.postDelayed(new Runnable() { @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2) @Override public void run() { LogUtil.e(TAG,"scanLeDeviceStop"); mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); Message message = handler.obtainMessage(); message.what = DATA_COMPLETE; responseResult.setStatus(BlueToothEnum.SUCCESS.getCode()); responseResult.setMsg(BlueToothEnum.SUCCESS.getMsg()); responseResult.setData(mLeDevices); message.obj = responseResult; //數(shù)據(jù)數(shù)據(jù)完畢 更新數(shù)據(jù)列表 handler.sendMessage(message); } }, SCAN_PERIOD); mScanning = true; mBluetoothAdapter.startLeScan(mLeScanCallback); } else { mScanning = false; mBluetoothAdapter.stopLeScan(mLeScanCallback); } } public void addDevice(IBeaconClass.iBeacon device) { if(device==null) return; for(int i=0;i<mLeDevices.size();i++){ String btAddress = mLeDevices.get(i).bluetoothAddress; if(btAddress.equals(device.bluetoothAddress)){ mLeDevices.add(i+1, device); mLeDevices.remove(i); return; } } mLeDevices.add(device); } // Device scan callback. private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() { @Override public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { final IBeaconClass.iBeacon ibeacon = IBeaconClass.fromScanData(device,rssi,scanRecord); LogUtil.e(TAG,"onLeScan"); addDevice(ibeacon); if(!mScanning){ LogUtil.e(TAG,"!mScanning"); } } }; private Handler handler = new Handler() { @Override public void handleMessage(Message msg) { switch (msg.what) { case DATA_COMPLETE: EventBus.getDefault().post(new BlueTeethEvent(responseResult)); //停止服務 stopUpdateService(); break; case DATA_FAIL: responseResult.setStatus(BlueToothEnum.OTHER_ERROR.getCode()); responseResult.setMsg(BlueToothEnum.OTHER_ERROR.getMsg()); EventBus.getDefault().post(new BlueTeethEvent(responseResult)); stopUpdateService(); break; default: // stopService(updateIntent); // stopService(updateIntent); // stopService(new Intent(UpdateService.this,UpdateService.class)); break; } } }; private void stopUpdateService() { Intent updateIntent = new Intent(getBaseContext(),IbeaconService.class); updateIntent.setAction(ServiceHelper.IBEACON_SERVICE); updateIntent.setPackage(getBaseContext().getPackageName());//這里你需要設置你應用的包名 stopService(updateIntent); } }
調用方式:
/** * 開啟藍牙服務UpdateService */ public static void startIbeacon(Context context,int time) { Intent intent = new Intent(context,IbeaconService.class); intent.putExtra("time", time);//掃描ibeacon時間 intent.setAction(IBEACON_SERVICE); intent.setPackage(context.getPackageName());//這里你需要設置你應用的包名 context.startService(intent); }
其中IBeacon類
/** * 代碼改自https://github.com/RadiusNetworks/android-ibeacon-service/blob/master/src/main/java/com/radiusnetworks/ibeacon/IBeacon.java * @author gvzhang * */ public class IBeaconClass { static public class iBeacon implements Serializable{ public String beaconName; public int major; public int minor; public String uuid; public String bluetoothAddress; public int txPower; public int rssi; public double distance; } 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.uuid = "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.uuid = "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; iBeacon.distance = calculateAccuracy(iBeacon.txPower,iBeacon.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.uuid = sb.toString(); if (device != null) { iBeacon.bluetoothAddress = device.getAddress(); iBeacon.beaconName = device.getName(); } return iBeacon; } private 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(); } /** * 估算用戶設備到ibeacon的距離 * * @param txPower * @param rssi * @return */ public static double calculateAccuracy(int txPower, double rssi) { if (rssi == 0) { return -1.0; // if we cannot determine accuracy, return -1. } double ratio = rssi * 1.0 / txPower; if (ratio < 1.0) { return Math.pow(ratio, 10); } else { double accuracy = (0.89976) * Math.pow(ratio, 7.7095) + 0.111; return accuracy; } } }
缺少的類請自己補全。請根據(jù)自己的項目進行改造代碼。
{ "msg": "獲取數(shù)據(jù)成功", "data": [{ "uuid": "11111", "beaconName": "設備A", "distance": 0.56 }, { "uuid": "2222", "beaconName": "設備B", "distance": 1.56 } ], "status": 100 }
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
您可能感興趣的文章:
相關文章
Android使用SQLite數(shù)據(jù)庫的示例
本篇文章主要介紹了Android使用SQLite數(shù)據(jù)庫的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-01-01利用Kotlin實現(xiàn)破解Android版的微信小游戲--跳一跳
這篇文章主要給大家介紹了關于利用Kotlin實現(xiàn)破解Android版微信小游戲--跳一跳的相關資料,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧。2017-12-12Android 開發(fā)中根據(jù)搜索內容實現(xiàn)TextView中的文字部分加粗
最近遇到一個需求,需要做一個搜索功能。搜索的內容需要加粗顯示。實現(xiàn)方法很簡單,下面通過本文給大家分享Android 開發(fā)中根據(jù)搜索內容實現(xiàn)TextView中的文字部分加粗樣式,非常不錯,需要的朋友參考下2017-03-03