使用 android 应用程序扫描范围内的蓝牙设备
Scan for Bluetooth devices in range using android application
我正在开发一个 android 应用程序来在我单击按钮时发现我周围的蓝牙设备。下面我已经提到了它是如何工作的。
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 未显示任何错误消息,应用程序未显示任何蓝牙设备。我在这里做错了什么
我的 Android Studio 版本是 3.6.1。我的 minSdkVersion 是 18 而 compileSdkVersion 是 29.
您尚未请求执行扫描所需的位置或蓝牙权限。参见 https://developer.android.com/training/permissions/requesting#perm-check. Weirdly, it isn't mentioned on https://developer.android.com/guide/topics/connectivity/bluetooth。
特别是,您需要检查 ACCESS_FINE_LOCATION 运行时权限,如果未被授予,您需要请求权限。
好吧,您不必两次调用 mBluetoothAdapter.startDiscovery();
。需要一次。并确保您的清单中有 Location 和 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();
我正在开发一个 android 应用程序来在我单击按钮时发现我周围的蓝牙设备。下面我已经提到了它是如何工作的。
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 未显示任何错误消息,应用程序未显示任何蓝牙设备。我在这里做错了什么
我的 Android Studio 版本是 3.6.1。我的 minSdkVersion 是 18 而 compileSdkVersion 是 29.
您尚未请求执行扫描所需的位置或蓝牙权限。参见 https://developer.android.com/training/permissions/requesting#perm-check. Weirdly, it isn't mentioned on https://developer.android.com/guide/topics/connectivity/bluetooth。
特别是,您需要检查 ACCESS_FINE_LOCATION 运行时权限,如果未被授予,您需要请求权限。
好吧,您不必两次调用 mBluetoothAdapter.startDiscovery();
。需要一次。并确保您的清单中有 Location 和 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();