如何使用蓝牙信号强度计算两个安卓设备之间的距离?
Posted
技术标签:
【中文标题】如何使用蓝牙信号强度计算两个安卓设备之间的距离?【英文标题】:How to calculate distance between two android device using Bluetooth signal strength? 【发布时间】:2014-04-22 11:44:33 【问题描述】:我正在开发安卓应用程序。在我的项目中,我想显示蓝牙扫描设备、MAC 地址、蓝牙信号强度和两个 android 设备之间的距离。
我已经完成了 3 个要求,但我不知道如何使用信号强度来获取距离。
package com.example.bluetoothdemo;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.os.Bundle;
import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.view.Menu;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.TextView;
import android.widget.Toast;
import android.content.BroadcastReceiver;
public class MainActivity extends Activity
private BluetoothAdapter BTAdapter = BluetoothAdapter.getDefaultAdapter();
private static final int REQUEST_ENABLE_BT = 1;
ListView listDevicesFound;
Button btnScanDevice;
TextView stateBluetooth;
BluetoothAdapter bluetoothAdapter;
ArrayAdapter<String> btArrayAdapter;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
btnScanDevice = (Button)findViewById(R.id.scan_device);
stateBluetooth = (TextView)findViewById(R.id.textView1);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
listDevicesFound = (ListView)findViewById(R.id.listView1);
btArrayAdapter = new ArrayAdapter<String>(MainActivity.this,
android.R.layout.simple_list_item_1);
listDevicesFound.setAdapter(btArrayAdapter);
CheckBlueToothState();
btnScanDevice.setOnClickListener(btnScanDeviceOnClickListener);
registerReceiver(ActionFoundReceiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
registerReceiver(receiver, new IntentFilter(BluetoothDevice.ACTION_FOUND));
@Override
protected void onDestroy()
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(ActionFoundReceiver);
private void CheckBlueToothState()
if (bluetoothAdapter == null)
stateBluetooth.setText("Bluetooth NOT support");
else
if (bluetoothAdapter.isEnabled())
if(bluetoothAdapter.isDiscovering())
stateBluetooth.setText("Bluetooth is currently in device discovery process.");
else
stateBluetooth.setText("Bluetooth is Enabled.");
btnScanDevice.setEnabled(true);
else
stateBluetooth.setText("Bluetooth is NOT Enabled!");
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
private Button.OnClickListener btnScanDeviceOnClickListener = new Button.OnClickListener()
@Override
public void onClick(View arg0)
// TODO Auto-generated method stub
btArrayAdapter.clear();
bluetoothAdapter.startDiscovery();
;
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
// TODO Auto-generated method stub
if(requestCode == REQUEST_ENABLE_BT)
CheckBlueToothState();
private final BroadcastReceiver ActionFoundReceiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
// TODO Auto-generated method stub
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action))
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
btArrayAdapter.add(device.getName() + "\n" + device.getAddress()+ "
\n "+intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE));
btArrayAdapter.notifyDataSetChanged();
;
@Override
public boolean onCreateOptionsMenu(Menu menu)
getMenuInflater().inflate(R.menu.main, menu);
return true;
private final BroadcastReceiver receiver = new BroadcastReceiver()
@Override
public void onReceive(Context context, Intent intent)
String action = intent.getAction();
if(BluetoothDevice.ACTION_FOUND.equals(action))
int rssi = intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);
String name = intent.getStringExtra(BluetoothDevice.EXTRA_NAME);
TextView rssi_msg = (TextView) findViewById(R.id.listView1);
Toast.makeText(getApplicationContext()," RSSI: " + rssi + "dBm",
Toast.LENGTH_SHORT).show();
;
【问题讨论】:
【参考方案1】:尝试使用 Google Play 商店中的“b 和 l 蓝牙 le 扫描仪”应用,以可视化来自多个蓝牙 LE 设备的信号。当存在多个设备时,您会立即发现 rssi 信号强度“嘈杂”。墙壁、带有金属部件的家具和 Wi-Fi 信号源也会导致信号变化。最好的解决方案是为您的距离读数创建“区域”...例如:远、近、旁边等。
【讨论】:
【参考方案2】:这实际上是不可能仅根据蓝牙信号强度计算距离的。但是,您可以使用三角测量技术来获取两个设备之间的距离,或者完全可以使用 GPS 概念来找出距离。 仅使用蓝牙,无法找到距离。 即使您可以通过这样的方式以易于理解的方式表示信号强度。
https://play.google.com/store/apps/details?id=com.bluetoothFinder
查看此链接。
【讨论】:
我看到低能耗蓝牙可以实现,例如估计距离的 iBeacons。 我们如何使用像 Beacon 这样的安卓设备? @akash89 旧答案,但您介意评论一下为什么它实际上是不可能的吗?是因为信号有可能从其他材料反弹或被其他材料吸收吗?【参考方案3】:您可以使用 txPower 计算距离。以下是计算此值的数学方法。
double getDistance(int rssi, int txPower)
return Math.pow(10d, ((double) txPower - rssi) / (10 * 2));
【讨论】:
在哪里可以找到简单蓝牙(不是 BLE)的 txPower 值?以上是关于如何使用蓝牙信号强度计算两个安卓设备之间的距离?的主要内容,如果未能解决你的问题,请参考以下文章