简体   繁体   English

如何在android中以编程方式发现蓝牙设备并在Listview中显示

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM