使用蓝牙信号强度如何计算两个安卓设备之间的距离?

9

我正在开发安卓应用程序。在我的项目中,我想展示蓝牙扫描设备、MAC地址、蓝牙信号强度以及两个安卓设备之间的距离。

我已经完成了前三个需求,但是我不知道如何使用信号强度获取距离。

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();
    }
 }
  };
 }
3个回答

2
尝试使用Google Play商店中的“b and l bluetooth le scanner”应用程序,可视化多个蓝牙低功耗设备的信号。当有多个设备存在时,您会立即发现RSSI信号强度是“嘈杂”的。墙壁、带金属组件的家具和Wi-Fi源也会导致信号变化。最好的解决方案是为您的距离读数创建“区域”,例如:远、近、靠近等等。

1

你可以使用txPower来计算距离。以下是一种数学方法来计算这个。

 double getDistance(int rssi, int txPower) {
        return Math.pow(10d, ((double) txPower - rssi) / (10 * 2));
 }

3
我在哪里可以找到简单蓝牙(非BLE)的txPower值? - Paul Freez

1

仅通过蓝牙信号强度计算距离实际上是不可能的。但是您可以使用三角测量技术来获取两个设备之间的距离,或者完全可以使用GPS概念来找出距离。 仅使用蓝牙无法找到距离。 即使如此,您可以像这样以易于理解的方式表示信号强度。

https://play.google.com/store/apps/details?id=com.bluetoothFinder

请查看此链接。

我认为使用低功耗蓝牙是可能的,例如iBeacons可以估算距离。 - shkschneider
我们如何将安卓设备用作信标? - atasoyh
1
@akash89 老回答了,但您介意评论一下为什么这几乎是不可能的吗?是因为信号有可能会反弹或被其他材料吸收吗? - user749127

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接