編輯:關於Android編程
此文使用的ibeacon模塊是april beacon,至於什麼是ibeacon。本文不做解釋,具體請自查。
一個april beacon裡攜帶的信息如下
0201061AFF4C0002159069BDB88C11416BAC3F33468C2788A3044B0378C60C09417072696C426561636F6E051250002003020A0000000000000000000000
具體是什麼意思呢
02 Number of bytes that follow in first AD structure
01 Flags AD type
06
Flags value 0x1A = 000011010
bit 0 (OFF) LE Limited Discoverable Mode
bit 1 (ON) LE General Discoverable Mode
bit 2 (OFF) BR/EDR Not Supported
bit 3 (ON) Simultaneous LE and BR/EDR to Same Device Capable (controller)
bit 4 (ON) Simultaneous LE and BR/EDR to Same Device Capable (Host)
1a Number of bytes that follow in second (and last) AD structure
前面是常規智能硬件廣播包部分
ff (FF代表後面是Manufacture Data)
4c 00 (組織標識,0x4c00蘋果公司標識,https://www.bluetooth.org/en-us/specification/assigned-numbers/company-identifiers)
02 (0x02 ibeacon標識位)
15 (0x15,22個字節標識長度,uuid,major,minor總和的長度)
90 69 bd b8-8c 11-41 6b-ac 3f-33 46 8c 27 88 a3 (Proximity UUID)
04 4b(1099,major)
03 78(888,minor)
c6 (切記這裡是補碼,轉化為原碼就是-58,iBeacon的信號發出強度值,用來作為和RSSI一起測距的基准 ,txPower)
計算
C6
1100 0110 補碼
1100 0101 反碼
1011 1010 原碼
-(32+16+8+2)
-58
0c09 (未知)
417072696c426561636f6e(AprilBeacon字符串對應的十六進制)
051250002003020a0000000000000000000000(未知)
Proximity UUID :這是將你所有的beacon與其他人的beacon設備區別開的id!例如,目前在商店裡某個區域分布著多個beacon形成一條“鏈帶”,用於為顧客提供特定的服務,那麼歸屬於同一條“鏈帶”的beacon將分配到相同的proximity UUID。為這條“鏈帶”設計的專用應用程序將會在後台使用這個UUID掃描到這條“鏈帶”中的beacon設備。
major 編號:用於將相關的beacon標識為一組。例如,一個商店中的所有beacon將會分配到相同的major編號。通過這種方式,應用程序就能夠知道顧客位於哪一家商店。
minor 標號:用於標識特定的beacon設備。例如一個商店中的每一個beacon設備都擁有唯一的minor編號,這樣你才能夠知道顧客位於商店中的哪個位置。
Measuring distance(測量距離)
最後一個值, TX power ,用於確定你和beacon之間距離有多近。根據這個值不但可以獲得粗略的信息(比如靠近/遠離/不在范圍內等),也可以獲取精確到米的距離(當然你也可以轉換為以步為單位的距離)。那麼如何實現?
TX power (上面例子中為0xC6=198,根據2的補碼測得256-198=-58dBm)是距離設備1米測得的信號強度值(RSSI- Received Signal Strength Indication,接收到的信號強弱指標)。假如接收到的信號強度減弱了,那麼我們可能在遠離。只要知道1米距離的RSSI,以及當前的RSSI(我們可以從接收到的信號中一塊獲取到這些信息),那麼計算出當前的距離是可能的。IOS已經實現了個這個功能,對於其它平台需要自己手動編碼計算 。
一個簡單的測距函數
protected 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;
}
}
在使用藍牙時需要加權限
關鍵代碼如下
package cn.edu.zafu.ble;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothManager;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
public class MainActivity extends Activity {
private BluetoothAdapter mBluetoothAdapter;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BluetoothManager bluetoothManager = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBluetooth = new Intent(
BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBluetooth, 1);
}
mBluetoothAdapter.startLeScan(mLeScanCallback);
}
private BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
@Override
public void onLeScan(final BluetoothDevice device, final int rssi,
final byte[] scanRecord) {
int startByte = 2;
boolean patternFound = false;
// 尋找ibeacon
while (startByte <= 5) {
if (((int) scanRecord[startByte + 2] & 0xff) == 0x02 && // Identifies
// an
// iBeacon
((int) scanRecord[startByte + 3] & 0xff) == 0x15) { // Identifies
// correct
// data
// length
patternFound = true;
break;
}
startByte++;
}
// 如果找到了的話
if (patternFound) {
// 轉換為16進制
byte[] uuidBytes = new byte[16];
System.arraycopy(scanRecord, startByte + 4, uuidBytes, 0, 16);
String hexString = bytesToHex(uuidBytes);
// ibeacon的UUID值
String uuid = hexString.substring(0, 8) + "-"
+ hexString.substring(8, 12) + "-"
+ hexString.substring(12, 16) + "-"
+ hexString.substring(16, 20) + "-"
+ hexString.substring(20, 32);
// ibeacon的Major值
int major = (scanRecord[startByte + 20] & 0xff) * 0x100
+ (scanRecord[startByte + 21] & 0xff);
// ibeacon的Minor值
int minor = (scanRecord[startByte + 22] & 0xff) * 0x100
+ (scanRecord[startByte + 23] & 0xff);
String ibeaconName = device.getName();
String mac = device.getAddress();
int txPower = (scanRecord[startByte + 24]);
Log.d("BLE",bytesToHex(scanRecord));
Log.d("BLE", "Name:" + ibeaconName + "\nMac:" + mac
+ " \nUUID:" + uuid + "\nMajor:" + major + "\nMinor:"
+ minor + "\nTxPower:" + txPower + "\nrssi:" + rssi);
Log.d("BLE","distance:"+calculateAccuracy(txPower,rssi));
}
}
};
static final char[] hexArray = "0123456789ABCDEF".toCharArray();
private static String bytesToHex(byte[] bytes) {
char[] hexChars = new char[bytes.length * 2];
for (int j = 0; j < bytes.length; j++) {
int v = bytes[j] & 0xFF;
hexChars[j * 2] = hexArray[v >>> 4];
hexChars[j * 2 + 1] = hexArray[v & 0x0F];
}
return new String(hexChars);
}
protected 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;
}
}
}
至此,本文也就結束,所謂初步,就是獲取ibeacon模塊的基本信息。
源碼下載
http://download.csdn.net/detail/sbsujjbcy/8503507
Android有三個基礎組件Activity,Service和BroadcastReceiver,他們都是依賴Intent來啟動。本文介紹的是Activity的生命周期以
活動的啟動模式啟動模式一共有四種,分別是 standard、singleTop、singleTask 和singleInstance,可以在AndroidManifest
本文實例講述了Android編程之圖片顏色處理方法。分享給大家供大家參考,具體如下:你想做到跟美圖秀秀一樣可以處理自己的照片,美化自己的照片嗎?其實你也可以自己做一個這樣
轉載 原文鏈接:Introducing Fresco: A new image library for Android 作者 : tyrone Nichol