android藍牙rssi
1. 如何讀取一次,我連接的多個設備的 rssi 值
我正在開發一個應用程序有連接到藍牙設備的 Android 4.3。
我可以連接到 BLE 設備和從設備中讀取 RSSI,通過使用 BluetoothGatt.readRemoteRssi()。
我想要讀的多個設備一次我已連接,但我可以只讀 BLE RSSI 設備 RSSI 的最後一次,我連接的設備。
如果有兩個 BLE 設備 A 和 B。我連接到A 的設備,並讀取該 RSSI。之後,我連接到B 的設備,和我可以從設備 B讀取 RSSI。但它並不讀取設備 A的 RSSI,它只能從設備 B讀取 RSSI。
在Main.java ,它列出已連接的位置的所有設備。
當我單擊該設備,在列表上,它把傳送的設備的名稱和地址到DeviceControl.java。
final Intent qintent = new Intent(this, DeviceControl.class);
devicelist.setOnItemClickListener(new OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
long arg3) {
// TODO Auto-generated method stub
HashMap<String, Object> select = (HashMap<String, Object>) devicelist.getItemAtPosition(arg2);
String name = (String) select.get(「name」);
String address = (String) select.get(「address」);
qintent.putExtra(DeviceControl.EXTRAS_DEVICE_NAME, name);
qintent.putExtra(DeviceControl.EXTRAS_DEVICE_ADDRESS, address);
startActivity(qintent);
}
});
DeviceControl.java將調用BluetoothLeService.java和連接到設備。
private final ServiceConnection mServiceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName componentName, IBinder service) {
// TODO Auto-generated method stub
mBluetoothLeService = ((BluetoothLeService.LocalBinder) service)。getService();
if(!mBluetoothLeService.initialize()) {
Log.e(TAG, 「Unable to initialize Bluetooth」);
finish();
}
registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter());
mBluetoothLeService.connect(mDeviceAddress);
}
@Override
public void onServiceDisconnected(ComponentName componentName) {
// TODO Auto-generated method stub
mBluetoothLeService = null;
}
};
BluetoothLeService.java將連接到該設備。
public boolean connect(final String address) {
if (mBluetoothAdapter == null || address == null) {
Log.w(TAG, 「BluetoothAdapter not initialized or unspecified address.」);
return false;
}
if(mBluetoothDeviceAddress != null && address.equals(mBluetoothDeviceAddress)
&& mBluetoothGatt != null) {
Log.d(TAG, 「Trying to use an existing mBluetoothGatt for connection.」);
if(mBluetoothGatt.connect()) {
mConnectionState = STATE_CONNECTING;
return true;
}else {
return false;
}
}
final BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(address);
if(device == null) {
Log.w(TAG, 「Device not found. Unable to connect」);
return false;
}
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
Log.d(TAG, 「Try to create a new connection」);
mBluetoothDeviceAddress = address;
mConnectionState =STATE_CONNECTING;
return true;
}
它連接到設備後,我可以使用 readRemoteRssi 來從設備中讀取 RSSI。
public void readRemoteRssi() {
mBluetoothGatt.readRemoteRssi();
}
但它只能讀取 RSSI 的最後一個設備的我已連接。
當我看到日誌時,它總是發送onCharacteristicWrite和readRemoteRssi()到我連接的最後一個設備。
我應該重新連接關貿總協定 》 或之前我想 RSSI 對讀取或寫入的 CharacteristicWrite 值的第一個設備重新連接到的第一個地址的設備概覽
它不會有其他的方法來讀取我已連接的所有設備的 RSSI 概覽
解決方法 1:
使多個 BluetoothGatt 對象來連接多個設備分開,並調用 readRemoteRssi 一個接一個。
懶的和壞的示例中,您應該能夠將那些 BluetoothGatt 對象放入數組
BluetoothGatt mBluetoothGatt1 = device1.connectGatt(this, false, mGattCallback);
BluetoothGatt mBluetoothGatt2 = device2.connectGatt(this, false, mGattCallback);
2. Android 藍牙測距離,兩部藍牙手機距離
/**
*功能:根據rssi計算距離
*Createdbyliuhuichaoon2017/1/17.
*/
publicclassRssiUtil{
//A和n的值,需要根據實際環境進行檢測得出
privatestaticfinaldoubleA_Value=50;/**A-發射端和接收端相隔1米時的信號強度*/
privatestaticfinaldoublen_Value=2.5;/**n-環境衰減因子*/
/**
*根據Rssi獲得返回的距離,返回數據單位為m
*@paramrssi
*@return
*/
publicstaticdoublegetDistance(intrssi){
intiRssi=Math.abs(rssi);
doublepower=(iRssi-A_Value)/(10*n_Value);
returnMath.pow(10,power);
}
}
/*監聽掃描過程中的變化*/
=newBroadcastReceiver(){
@Override
publicvoidonReceive(Contextcontext,Intentintent){
Stringaction=intent.getAction();
//Whendiscoveryfindsadevice
if(BluetoothDevice.ACTION_FOUND.equals(action))
{
//
//通過EXTRA_DEVICE附加域來得到一個BluetoothDevice設備
BluetoothDevicedevice=intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//Ifit'salreadypaired,skipit,becauseit'sbeenlistedalready
//如果這個設備是不曾配對過的,添加到list列表
/*if(device.getBondState()!=BluetoothDevice.BOND_BONDED)
{*/
//信號強度
intrssi=intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
掃描藍牙過程中獲得信號強度:
[java]view plain
3. android ble搜到一個藍牙怎麼跟特徵值通信的
Generic Attribute Profile (GATT)
通過BLE連接,讀寫屬性類小數據的Profile通用規范。現在所有的BLE應用Profile都是基於GATT的。
Attribute Protocol (ATT)
GATT是基於ATT Protocol的。ATT針對BLE設備做了專門的優化,具體就是在傳輸過程中使用盡量少的數據。每個屬性都有一個唯一的UUID,屬性將以characteristics and services的形式傳輸。
Characteristic
Characteristic可以理解為一個數據類型,它包括一個value和0至多個對次value的描述(Descriptor)。
Descriptor
對Characteristic的描述,例如范圍、計量單位等。
Service
Characteristic的集合。例如一個service叫做「Heart Rate Monitor」,它可能包含多個Characteristics,其中可能包含一個叫做「heart rate measurement"的Characteristic。
二、角色和職責:
Android設備與BLE設備交互有兩組角色:
中心設備和外圍設備(Central vs. peripheral);
GATT server vs. GATT client.
Central vs. peripheral:
中心設備和外圍設備的概念針對的是BLE連接本身。Central角色負責scan advertisement。而peripheral角色負責make advertisement。
GATT server vs. GATT client:
這兩種角色取決於BLE連接成功後,兩個設備間通信的方式。
舉例說明:
現 有一個活動追蹤的BLE設備和一個支持BLE的Android設備。Android設備支持Central角色,而BLE設備支持peripheral角 色。創建一個BLE連接需要這兩個角色都存在,都僅支持Central角色或者都僅支持peripheral角色則無法建立連接。
當 連接建立後,它們之間就需要傳輸GATT數據。誰做server,誰做client,則取決於具體數據傳輸的情況。例如,如果活動追蹤的BLE設備需要向 Android設備傳輸sensor數據,則活動追蹤器自然成為了server端;而如果活動追蹤器需要從Android設備獲取更新信息,則 Android設備作為server端可能更合適。
三、許可權及feature:
和經典藍牙一樣,應用使用藍牙,需要聲明BLUETOOTH許可權,如果需要掃描設備或者操作藍牙設置,則還需要BLUETOOTH_ADMIN許可權:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
除了藍牙許可權外,如果需要BLE feature則還需要聲明uses-feature:
<uses-feature android:name="android.hardware.bluetooth_le" android:required="true"/>
按時required為true時,則應用只能在支持BLE的Android設備上安裝運行;required為false時,Android設備均可正常安裝運行,需要在代碼運行時判斷設備是否支持BLE feature:
// 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)) {
Toast.makeText(this, R.string.ble_not_supported, Toast.LENGTH_SHORT).show();
finish();
}
四、啟動藍牙:
在使用藍牙BLE之前,需要確認Android設備是否支持BLE feature(required為false時),另外要需要確認藍牙是否打開。
如果發現不支持BLE,則不能使用BLE相關的功能。如果支持BLE,但是藍牙沒打開,則需要打開藍牙。
打開藍牙的步驟:
1、獲取BluetoothAdapter
BluetoothAdapter是Android系統中所有藍牙操作都需要的,它對應本地Android設備的藍牙模塊,在整個系統中BluetoothAdapter是單例的。當你獲取到它的示例之後,就能進行相關的藍牙操作了。
獲取BluetoothAdapter代碼示例如下:
// Initializes Bluetooth adapter.
final BluetoothManager bluetoothManager =
(BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
mBluetoothAdapter = bluetoothManager.getAdapter();
註:這里通過getSystemService獲取BluetoothManager,再通過BluetoothManager獲取BluetoothAdapter。BluetoothManager在Android4.3以上支持(API level 18)。
2、判斷是否支持藍牙,並打開藍牙
獲取到BluetoothAdapter之後,還需要判斷是否支持藍牙,以及藍牙是否打開。
如果沒打開,需要讓用戶打開藍牙:
private BluetoothAdapter mBluetoothAdapter;
// Ensures Bluetooth is available on the device and it is enabled. If not,
// displays a dialog requesting user permission to enable Bluetooth.
if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}
五、搜索BLE設備:
通過調用BluetoothAdapter的startLeScan()搜索BLE設備。調用此方法時需要傳入 BluetoothAdapter.LeScanCallback參數。
因此你需要實現 BluetoothAdapter.LeScanCallback介面,BLE設備的搜索結果將通過這個callback返回。
由於搜索需要盡量減少功耗,因此在實際使用時需要注意:
1、當找到對應的設備後,立即停止掃描;
2、不要循環搜索設備,為每次搜索設置適合的時間限制。避免設備不在可用范圍的時候持續不停掃描,消耗電量。
搜索的示例代碼如下:
/**
* Activity for scanning and displaying available BLE devices.
*/
public class DeviceScanActivity extends ListActivity {
private BluetoothAdapter mBluetoothAdapter;
private boolean mScanning;
private Handler mHandler;
// 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;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}, SCAN_PERIOD);
mScanning = true;
mBluetoothAdapter.startLeScan(mLeScanCallback);
} else {
mScanning = false;
mBluetoothAdapter.stopLeScan(mLeScanCallback);
}
}
}
如果你只需要搜索指定UUID的外設,你可以調用 startLeScan(UUID[], BluetoothAdapter.LeScanCallback)方法。
其中UUID數組指定你的應用程序所支持的GATT Services的UUID。
BluetoothAdapter.LeScanCallback的實現示例如下:
private LeDeviceListAdapter mLeDeviceListAdapter;
// 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() {
mLeDeviceListAdapter.addDevice(device);
mLeDeviceListAdapter.notifyDataSetChanged();
}
});
}
};
注意:搜索時,你只能搜索傳統藍牙設備或者BLE設備,兩者完全獨立,不可同時被搜索。
六、連接GATT Server:
兩個設備通過BLE通信,首先需要建立GATT連接。這里我們講的是Android設備作為client端,連接GATT Server。
連接GATT Server,你需要調用BluetoothDevice的connectGatt()方法。此函數帶三個參數:Context、autoConnect(boolean)和BluetoothGattCallback對象。調用示例:
mBluetoothGatt = device.connectGatt(this, false, mGattCallback);
函數成功,返回BluetoothGatt對象,它是GATT profile的封裝。通過這個對象,我們就能進行GATT Client端的相關操作。BluetoothGattCallback用於傳遞一些連接狀態及結果。
BluetoothGatt常規用到的幾個操作示例:
connect() :連接遠程設備。
discoverServices() : 搜索連接設備所支持的service。
disconnect():斷開與遠程設備的GATT連接。
close():關閉GATT Client端。
readCharacteristic(characteristic) :讀取指定的characteristic。
setCharacteristicNotification(characteristic, enabled) :設置當指定characteristic值變化時,發出通知。
getServices() :獲取遠程設備所支持的services。
等等。
註:
1、某些函數調用之間存在先後關系。例如首先需要connect上才能discoverServices。
2、 一些函數調用是非同步的,需要得到的值不會立即返回,而會在BluetoothGattCallback的回調函數中返回。例如 discoverServices與onServicesDiscovered回調,readCharacteristic與 onCharacteristicRead回調,setCharacteristicNotification與 onCharacteristicChanged回調等。
4. 怎麼用android獲取bluetooth的信號強度
要拿到藍牙信號指示值 rssi 分為兩個步驟。
1.在oncreate方法裡面增加 注冊掃描廣播
public void onCreate(Bundle savedInstanceState) {
// 注冊開始發現廣播。
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
this.registerReceiver(mReceiver, filter);
}
2.新建BroadcastReceiver廣播對象,並實現裡面的onreceive方法,在onreceive得到rssi(信號強度)。
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//當設備開始掃描時。
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//從Intent得到blueDevice對象
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//信號強度。
short rssi = intent.getExtras().getShort(
BluetoothDevice.EXTRA_RSSI);
}
}
}
};
5. android 藍牙室內定位 ibeacon 關於RSSI演算法
可以通過高斯權重法來對最終的位置進行加權計算。同時你也可以考慮採用濾波來進行修正。
6. 那種手機藍牙串口助手能接受漢字
藍牙串口助手 Bluetooth SPP是一款Android平台藍牙客戶端通信工具(即:藍牙從機模式),可進行藍牙串口通信測試。能連接單片機及PC的藍牙串口。
1.8重大更新(掃描設備時顯示rssi,class;增加鍵盤控制器模式)
7. android 藍牙連接後怎麼得到rssi值
要拿到藍牙信號指示值 rssi 分為兩個步驟。
1.在oncreate方法裡面增加 注冊掃描廣播
public void onCreate(Bundle savedInstanceState) {
// 注冊開始發現廣播。
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
this.registerReceiver(mReceiver, filter);
}
2.新建BroadcastReceiver廣播對象,並實現裡面的onreceive方法,在onreceive得到rssi(信號強度)。
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
8. Android 藍牙連接後怎麼得到rssi值 並且連續刷新 哪個大神幫我一下
要拿到藍牙信號指示值 rssi 分為兩個步驟。
1.在oncreate方法裡面增加 注冊掃描廣播
public void onCreate(Bundle savedInstanceState) {
// 注冊開始發現廣播。
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED);
this.registerReceiver(mReceiver, filter);
}
2.新建BroadcastReceiver廣播對象,並實現裡面的onreceive方法,在onreceive得到rssi(信號強度)。
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//當設備開始掃描時。
if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//從Intent得到blueDevice對象
BluetoothDevice device = intent
.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
//信號強度。
short rssi = intent.getExtras().getShort(
BluetoothDevice.EXTRA_RSSI);