android獲取ibeacon列表的方法
android獲取ibeacon列表,供大家參考,具體內(nèi)容如下
最近公司有需要做ibeacon需求。
因?yàn)樯婕皰叽a的時(shí)間。特意寫一個(gè)service實(shí)現(xiàn)獲取列表 可以根據(jù)掃描時(shí)間掃描出ibeacon列表
包含 uuid,設(shè)備名稱,單位(米),電量等。
請根據(jù)自己的項(xiàng)目進(jìn)行改造代碼。
核心代碼如下:
/**
*
* <ibeaon服務(wù)>
*
* @author fulushan
* @date 創(chuàng)建時(shí)間: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<>();
//開啟一個(gè)新的線程,如果使用Service,會導(dǎo)致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 {
//獲取藍(lán)牙數(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;
}
//開啟藍(lán)牙
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));
//停止服務(wù)
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());//這里你需要設(shè)置你應(yīng)用的包名
stopService(updateIntent);
}
}
調(diào)用方式:
/**
* 開啟藍(lán)牙服務(wù)UpdateService
*/
public static void startIbeacon(Context context,int time) {
Intent intent = new Intent(context,IbeaconService.class);
intent.putExtra("time", time);//掃描ibeacon時(shí)間
intent.setAction(IBEACON_SERVICE);
intent.setPackage(context.getPackageName());//這里你需要設(shè)置你應(yīng)用的包名
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();
}
/**
* 估算用戶設(shè)備到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;
}
}
}
缺少的類請自己補(bǔ)全。請根據(jù)自己的項(xiàng)目進(jìn)行改造代碼。
{
"msg": "獲取數(shù)據(jù)成功",
"data": [{
"uuid": "11111",
"beaconName": "設(shè)備A",
"distance": 0.56
},
{
"uuid": "2222",
"beaconName": "設(shè)備B",
"distance": 1.56
}
],
"status": 100
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
- Android檢測IBeacon熱點(diǎn)的方法
- Android提高之BLE開發(fā)Android手機(jī)搜索iBeacon基站
- Android藍(lán)牙開發(fā)深入解析
- 詳解Android——藍(lán)牙技術(shù) 帶你實(shí)現(xiàn)終端間數(shù)據(jù)傳輸
- Android Bluetooth藍(lán)牙技術(shù)使用流程詳解
- Android單片機(jī)與藍(lán)牙模塊通信實(shí)例代碼
- 分享Android 藍(lán)牙4.0(ble)開發(fā)的解決方案
- android實(shí)現(xiàn)藍(lán)牙文件發(fā)送的實(shí)例代碼,支持多種機(jī)型
- Android手機(jī)通過藍(lán)牙連接佳博打印機(jī)的實(shí)例代碼
- Android基于ibeacon實(shí)現(xiàn)藍(lán)牙考勤功能
相關(guān)文章
Flutter實(shí)現(xiàn)用視頻背景的登錄頁的示例代碼
這篇文章主要介紹了Flutter實(shí)現(xiàn)用視頻背景的登錄頁的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-08-08
Android開發(fā)之設(shè)置開機(jī)自動啟動的幾種方法
這篇文章主要介紹了Android開發(fā)之設(shè)置開機(jī)自動啟動的幾種方法的相關(guān)資料,這里提供三種方法幫助大家實(shí)現(xiàn)這樣的功能,需要的朋友可以參考下2017-08-08
Android使用SQLite數(shù)據(jù)庫的示例
本篇文章主要介紹了Android使用SQLite數(shù)據(jù)庫的示例,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-01-01
android SQLite數(shù)據(jù)庫總結(jié)
本文主要介紹了android SQLite數(shù)據(jù)庫的相關(guān)知識。具有一定的參考價(jià)值,下面跟著小編一起來看下吧2017-01-01
利用Kotlin實(shí)現(xiàn)破解Android版的微信小游戲--跳一跳
這篇文章主要給大家介紹了關(guān)于利用Kotlin實(shí)現(xiàn)破解Android版微信小游戲--跳一跳的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。2017-12-12
Android 開發(fā)中根據(jù)搜索內(nèi)容實(shí)現(xiàn)TextView中的文字部分加粗
最近遇到一個(gè)需求,需要做一個(gè)搜索功能。搜索的內(nèi)容需要加粗顯示。實(shí)現(xiàn)方法很簡單,下面通過本文給大家分享Android 開發(fā)中根據(jù)搜索內(nèi)容實(shí)現(xiàn)TextView中的文字部分加粗樣式,非常不錯(cuò),需要的朋友參考下2017-03-03

