Сканирование Bluetooth-устройств в радиусе действия с помощью приложения android - PullRequest
3 голосов
/ 25 апреля 2020

Я разрабатываю приложение android для обнаружения устройств Bluetooth вокруг меня, когда я нажимаю на кнопку. Ниже я упомянул, как это работает.

MainActivity. java

import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;

import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.Intent;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import java.util.ArrayList;
import java.util.Set;

public class MainActivity extends AppCompatActivity {
  private String LOG_TAG; // Just for logging purposes. Could be anything. Set to app_name
  private int REQUEST_ENABLE_BT = 99; // Any positive integer should work.
  private BluetoothAdapter mBluetoothAdapter;

  @Override
  protected void onCreate(Bundle savedInstanceState)
  {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    Button scanBt = (Button) findViewById(R.id.button_scanBT);

    LOG_TAG = getResources().getString(R.string.app_name);
    mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    scanBt.setOnClickListener(new View.OnClickListener() {
    @Override
    public void onClick(View v)
    {
        scanForBluetoothDevices();
        Log.d("TAG","testing");
    }
    });

  private void scanForBluetoothDevices()
  {
    // Start this on a new activity without passing any data to it
    Intent intent = new Intent(this, FoundBTDevices.class);
    startActivity(intent);
  }

}

FoundBTDevices. java

 import android.app.ListActivity;
 import android.bluetooth.BluetoothAdapter;
 import android.bluetooth.BluetoothDevice;
 import android.content.BroadcastReceiver;
 import android.content.Context;
 import android.content.Intent;
 import android.content.IntentFilter;
 import android.os.Build;
 import android.os.Bundle;
 import android.util.Log;

 import androidx.annotation.RequiresApi;
 import java.util.ArrayList;

public class FoundBTDevices extends ListActivity{

private ArrayList<BluetoothObject> arrayOfFoundBTDevices;

@Override
protected void onCreate(Bundle savedInstanceState)
{
    super.onCreate(savedInstanceState);

    if (!havePermissions()) {
        Log.d("TAG", "Requesting permissions needed for this app.");
        requestPermissions();
    }

IntentFilter bluetoothFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, bluetoothFilter);
final BluetoothAdapter mBluetoothAdapter = 
BluetoothAdapter.getDefaultAdapter();
mBluetoothAdapter.startDiscovery();


}


    // Create a BroadcastReceiver for ACTION_FOUND
    private final BroadcastReceiver mReceiver = new BroadcastReceiver()
    {

        @RequiresApi(api = Build.VERSION_CODES.JELLY_BEAN_MR2)
        @Override
        public void onReceive(Context context, Intent intent)
        {
            arrayOfFoundBTDevices = new ArrayList<BluetoothObject>();

            // start looking for bluetooth devices
            mBluetoothAdapter.startDiscovery();

            Log.d("TAG","This is onReceive()");
            String action = intent.getAction();
            // When discovery finds a device
            if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction()))
            {
                // Get the bluetoothDevice object from the Intent
                BluetoothDevice device = 
   intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

                // Get the "RSSI" to get the signal strength as 
   integer,
                // but should be displayed in "dBm" units
                int rssi = 
   intent.getShortExtra(BluetoothDevice.EXTRA_RSSI,Short.MIN_VALUE);

                // Create the device object and add it to the 
   arrayList of devices
                BluetoothObject bluetoothObject = new 
   BluetoothObject();
                bluetoothObject.setBluetooth_name(device.getName());

   bluetoothObject.setBluetooth_address(device.getAddress());

   bluetoothObject.setBluetooth_state(device.getBondState());
                bluetoothObject.setBluetooth_type(device.getType());    
  // requires API 18 or higher
                bluetoothObject.setBluetooth_uuids(device.getUuids());
                bluetoothObject.setBluetooth_rssi(rssi);

                arrayOfFoundBTDevices.add(bluetoothObject);

                // 1. Pass context and data to the custom adapter
                FoundBTDevicesAdapter adapter = new 
FoundBTDevicesAdapter(getApplicationContext(), arrayOfFoundBTDevices);

                // 2. setListAdapter
                setListAdapter(adapter);
            }
        }
    };


  private boolean havePermissions() {
    return ContextCompat.checkSelfPermission(this, 
  Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED;
  }
  private void requestPermissions() {
    ActivityCompat.requestPermissions(this,
            new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
  PERMISSIONS_REQUEST_CODE);
    Log.d("TAG", "requestPermissions");
  }

 @Override
  protected void onPause() {
    super.onPause();
    mBluetoothAdapter.cancelDiscovery();
  }
  }

FoundBTDevicesAdapter. java

 import android.content.Context;
 import android.os.ParcelUuid;
 import android.view.LayoutInflater;
 import android.view.View;
 import android.view.ViewGroup;
 import android.widget.ArrayAdapter;
 import android.widget.TextView;

 import java.util.ArrayList;
 import java.util.UUID;

 public class FoundBTDevicesAdapter extends ArrayAdapter<BluetoothObject>
 {
  private Context context;
  private ArrayList<BluetoothObject> arrayFoundDevices;

  public FoundBTDevicesAdapter(Context context, ArrayList<BluetoothObject> arrayOfAlreadyPairedDevices)
{
    super(context, R.layout.row_bt_scan_new_devices, arrayOfAlreadyPairedDevices);

    this.context = context;
    this.arrayFoundDevices = arrayOfAlreadyPairedDevices;
}

@Override
public View getView(int position, View convertView, ViewGroup parent)
{
    BluetoothObject bluetoothObject = arrayFoundDevices.get(position);

    // 1. Create Inflater
    LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);

    // 2. Get rowView from inflater
    View rowView = inflater.inflate(R.layout.row_bt_scan_new_devices, parent, false);

    // 3. Get the widgets from the rowView
    TextView bt_name = (TextView) rowView.findViewById(R.id.textview_bt_scan_name);
    TextView bt_address = (TextView) rowView.findViewById(R.id.textview_bt_scan_address);
    TextView bt_bondState = (TextView) rowView.findViewById(R.id.textview_bt_scan_state);
    TextView bt_type = (TextView) rowView.findViewById(R.id.textview_bt_scan_type);
    TextView bt_uuid = (TextView) rowView.findViewById(R.id.textview_bt_scan_uuid);
    TextView bt_signal_strength = (TextView) rowView.findViewById(R.id.textview_bt_scan_signal_strength);

    // 4. Set the text for each widget
    bt_name.setText(bluetoothObject.getBluetooth_name());
    bt_address.setText("address: " + bluetoothObject.getBluetooth_address());
    bt_bondState.setText("state: " + bluetoothObject.getBluetooth_state());
    bt_type.setText("type: " + bluetoothObject.getBluetooth_type());
    bt_signal_strength.setText("RSSI: " + bluetoothObject.getBluetooth_rssi() + "dbm");

    ParcelUuid uuid[] = bluetoothObject.getBluetooth_uuids();
    if (uuid != null)
        bt_uuid.setText("uuid" + uuid[0]);


    // 5. return rowView
    return rowView;

}//end getView()

}

AndroidManifest. xml

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

Как я понимаю BroadcastReceiver не является пожарным. Logcat не показывает сообщение об ошибке и приложение не показывает Bluetooth-устройства. Что я тут неправильно сделал

Моя Android Studio версия 3.6.1. my minSdkVersion равно 18 и compileSdkVersion равно 29.

Ответы [ 2 ]

2 голосов
/ 29 апреля 2020

Ну, вам не нужно звонить mBluetoothAdapter.startDiscovery(); дважды. Это требуется один раз. И убедитесь, что у вас есть Местоположение и Bluetooth-разрешение в вашем манифесте. И убедитесь, что ваше устройство обнаружено для других устройств.

Хорошо, я размещаю некоторый код. Надеюсь, это поможет вам

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {

            //if you have found the devices
            if (BluetoothDevice.ACTION_FOUND.equals(intent.getAction())) {

                // Now that you have found the device. Get the Bluetooth Device
                // object and its info from the Intent.

                BluetoothDevice deviceInfo = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                String deviceName = deviceInfo.getName();

              //Make sure you update your arraylist/recyclerlist adapter from here. As it 
              //invokes for every found device once.

            }
        }
    };

А вот как это назвать

IntentFilter bluetoothFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        context.registerReceiver(mReceiver, bluetoothFilter);
        final BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
        mBluetoothAdapter.startDiscovery();
2 голосов
/ 27 апреля 2020

Вы не запросили местоположение или разрешения Bluetooth, необходимые для выполнения сканирования. См. https://developer.android.com/training/permissions/requesting#perm -check . Как ни странно, это не упоминается в https://developer.android.com/guide/topics/connectivity/bluetooth.

В частности, вам нужно проверить разрешение ACCESS_FINE_LOCATION во время выполнения, и, если оно не предоставлено, вам нужно запросить разрешение .

...