[英]How to discover Bluetooth devices Programatically in android and display in Listview
I tried and followed some tutorial on web but it didn't work on new Android versions.我尝试并按照网络上的一些教程进行操作,但它不适用于新的 Android 版本。
I declared all Bluetooth permissions and used Dexter permission library.我声明了所有蓝牙权限并使用了 Dexter 权限库。 I followed few answers but it doesn't display available Bluetooth device name also我遵循了几个答案,但它也不显示可用的蓝牙设备名称
Below is my code:下面是我的代码:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
scan.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
toast("starts scanning...");
mBluetoothAdapter.startDiscovery();
}
});
mAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
mListView.setAdapter(mAdapter);
mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) {
String bluetoothDevice = mAdapter.getItem(i);
toast(bluetoothDevice);
}
});
}
public void pairedDevicesListView(View view){
mAdapter.clear();
pairedDevices = mBluetoothAdapter.getBondedDevices();
for (BluetoothDevice device : pairedDevices){
mAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
}
To discover a device, first get the bluetooth adapter by calling BluetoothAdapter.getDefaultAdapter()
要发现设备,首先通过调用BluetoothAdapter.getDefaultAdapter()
获取蓝牙适配器
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
To start discover, simply call the startDiscovery()
from bluetooth adapter.要开始发现,只需从蓝牙适配器调用startDiscovery()
。 This process is asynchronous so it will return immediately.这个过程是异步的,所以它会立即返回。 To catch the discovery process, we can register a BroadcastReceiver with ACTION_FOUND, ACTION_DISCOVERY_STARTED, ACTION_DISCOVERY_STARTED.要捕获发现过程,我们可以使用 ACTION_FOUND、ACTION_DISCOVERY_STARTED、ACTION_DISCOVERY_STARTED 注册 BroadcastReceiver。 For each device found, the intent will carry extra field EXTRA_DEVICE containg the BluetoothDevice object.对于找到的每个设备,意图将携带包含 BluetoothDevice 对象的额外字段 EXTRA_DEVICE。
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
registerReceiver(mReceiver, filter);
adapter.startDiscovery();
The receiver:收件人:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
//discovery starts, we can show progress dialog or perform other tasks
} else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
//discovery finishes, dismis progress dialog
} else if (BluetoothDevice.ACTION_FOUND.equals(action)) {
//bluetooth device found
BluetoothDevice device = (BluetoothDevice) intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
showToast("Found device " + device.getName());
}
}
};
And, don't forget to unregister the receiver on Activity's onDestroy method:而且,不要忘记在 Activity 的 onDestroy 方法上注销接收器:
@Override
public void onDestroy() {
unregisterReceiver(mReceiver);
super.onDestroy();
}
Add manifest permissions as follows添加清单权限如下
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />`
and try following code:并尝试以下代码:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
btnstart=findViewById(R.id.btnstart);
mListView=findViewById(R.id.listofdevices);
final ArrayAdapter mAdapter = new ArrayAdapter<String>(this,android.R.layout.simple_list_item_1);
mListView.setAdapter(mAdapter);
txt1=findViewById(R.id.txt1);
mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
setdevicevisible();
boolean hasBluetooth = getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH);
if(!hasBluetooth) {
AlertDialog dialog = new AlertDialog.Builder(MainActivity.this).create();
dialog.setTitle(getString(R.string.bluetooth_not_available_title));
dialog.setMessage(getString(R.string.bluetooth_not_available_message));
dialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// Closes the dialog and terminates the activity.
dialog.dismiss();
MainActivity.this.finish();
}
});
dialog.setCancelable(false);
dialog.show();
}
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity) this,
new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
1);
}
// If another discovery is in progress, cancels it before starting the new one.
if (mBluetoothAdapter.isDiscovering()) {
mBluetoothAdapter.cancelDiscovery();
}
mBluetoothAdapter.startDiscovery();
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//Finding devices
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
}
I forgot to declare Location permissions in the manifest file.我忘记在清单文件中声明位置权限。 To discover Bluetooth devices programmatically you need to add two permission ie ACCESS_FINE_LOCATION and ACCESS_COARSE_LOCATION.要以编程方式发现蓝牙设备,您需要添加两个权限,即 ACCESS_FINE_LOCATION 和 ACCESS_COARSE_LOCATION。
You could use the MAC address as unique ID.您可以使用 MAC 地址作为唯一 ID。
And you can find in the official doc here a complete example of it你可以在官方文档中找到一个完整的例子
https://developer.android.com/guide/topics/connectivity/bluetooth.html#FindingDevices https://developer.android.com/guide/topics/connectivity/bluetooth.html#FindingDevices
About signal strength i think you should use RSSI (Received Signal Strength Indicator)关于信号强度,我认为你应该使用 RSSI(接收信号强度指示器)
Edit: An easy way to accomplish this will be like this snippet to find bluetooth devices编辑:一个简单的方法来完成这个就像这个片段来找到蓝牙设备
mBluetoothAdapter.startDiscovery();
mReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//Finding devices
if (BluetoothDevice.ACTION_FOUND.equals(action))
{
// Get the BluetoothDevice object from the Intent
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
// Add the name and address to an array adapter to show in a ListView
mArrayAdapter.add(device.getName() + "\n" + device.getAddress());
}
}
};
IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(mReceiver, filter);
hope it helps希望能帮助到你
happy coding快乐编码
Try using this code, it worked for me.尝试使用此代码,它对我有用。
public class DeviceListActivity extends Activity {
private ListView pairedDevicesListView, newDevicesListView;
private ArrayList<DeviceData> dataList= new ArrayList<DeviceData>();
private ArrayList<BluetoothDevice> pairedDevices=new ArrayList<BluetoothDevice>();
private BluetoothAdapter bluetoothAdapter;
BluetoothDevice device;
private ArrayAdapter newDeviceAdapter;
private DeviceListAdapter pairedDeviceAdapter;
public static String DEVICE_ADDRESS = "device_address";
private IntentFilter filter;
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.e("action", action);
// Toast.makeText(DeviceListActivity.this, action, Toast.LENGTH_SHORT).show();
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (action.equals(BluetoothDevice.ACTION_FOUND)) {
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if (device.getBondState() != BluetoothDevice.BOND_BONDED) {
newDeviceAdapter.add(device.getName() + "\n" + device.getAddress());
pairedDevices.add(device);
newDeviceAdapter.notifyDataSetChanged();
}
} else if (action.equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
if (newDeviceAdapter.getCount() == 0) {
Toast.makeText(DeviceListActivity.this, "No devices found", Toast.LENGTH_SHORT).show();
newDeviceAdapter.add("No new device found");
newDeviceAdapter.notifyDataSetChanged();
}
}
}
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
setContentView(R.layout.activity_device_list);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDevicesListView = (ListView) findViewById(R.id.avail_devices);
newDevicesListView=(ListView)findViewById(R.id.new_devices);
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
pairedDeviceAdapter = new DeviceListAdapter(this,dataList, pairedDevices);
pairedDevicesListView.setAdapter(pairedDeviceAdapter);
pairedDeviceAdapter.notifyDataSetChanged();
//-----------------------------------------------
newDeviceAdapter=new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1);
newDevicesListView.setAdapter(newDeviceAdapter);
newDeviceAdapter.notifyDataSetChanged();
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
bluetoothAdapter.startDiscovery();
// get paired devices
Set<BluetoothDevice> pairedDevice = bluetoothAdapter.getBondedDevices();
if(pairedDevice.size()>0)
{
// pairedDeviceAdapter.clear();
for(BluetoothDevice device : pairedDevice)
{
// pairedDeviceAdapter.add(device.getName()+ "\n" +device.getAddress());
dataList.add(new DeviceData(device.getName(),device.getAddress()));
pairedDevices.add(device);
}
pairedDeviceAdapter.notifyDataSetChanged();
}
// register broadcast receiver
filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
registerReceiver(broadcastReceiver, filter);
pairedDevicesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
String data = ((TextView) view).getText().toString();
String address = data.substring(data.length() - 17);
Intent intent = new Intent();
intent.putExtra("device_address", address);
intent.putExtra("info", data);
setResult(Activity.RESULT_OK, intent);
finish();
}
});
newDevicesListView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
bluetoothAdapter.cancelDiscovery();
Boolean isBonded = false;
try {
isBonded = createBond(device);
if(isBonded)
{
Log.i("Log","Paired");
// pairedDeviceAdapter.add(device.getName() + "\n" + device.getAddress());
dataList.add(new DeviceData(device.getName(),device.getAddress()));
newDeviceAdapter.remove(device.getName() + "\n" + device.getAddress());
pairedDeviceAdapter.notifyDataSetChanged();
newDeviceAdapter.notifyDataSetChanged();
// Toast.makeText(DeviceListActivity.this, "paired to:" +device.getName(), Toast.LENGTH_SHORT).show();
// ------------------------
// Intent intent = new Intent();
// intent.putExtra("device_address", device.getAddress());
// intent.putExtra("info", device.getName());
// setResult(Activity.RESULT_OK, intent);
// finish();
}
} catch (Exception e)
{
e.printStackTrace();
}
}
});
}
@Override
protected void onStart() {
super.onStart();
registerReceiver(broadcastReceiver, filter);
}
@Override
protected void onPostResume() {
super.onPostResume();
registerReceiver(broadcastReceiver, filter);
}
@Override
protected void onDestroy() {
super.onDestroy();
if (bluetoothAdapter != null) {
bluetoothAdapter.cancelDiscovery();
}
this.unregisterReceiver(broadcastReceiver);
}
public boolean createBond(BluetoothDevice btDevice)
throws Exception
{
Class class1 = Class.forName("android.bluetooth.BluetoothDevice");
Method createBondMethod = class1.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.