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

如何在android中以编程方式发现蓝牙设备并在Listview中显示,android,listview,bluetooth,Android,Listview,Bluetooth,我试着在网上学习了一些教程,但在新的安卓版本上却不起作用 我声明了所有蓝牙权限并使用了Dexter权限库。我遵循了几个答案,但它也没有显示可用的蓝牙设备名称 下面是我的代码: @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mBluetoothA

我试着在网上学习了一些教程,但在新的安卓版本上却不起作用

我声明了所有蓝牙权限并使用了Dexter权限库。我遵循了几个答案,但它也没有显示可用的蓝牙设备名称

下面是我的代码:

@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());

    }
}
}

您可以使用MAC地址作为唯一ID

你可以在官方文件中找到一个完整的例子

关于信号强度,我认为您应该使用RSSI接收信号强度指示器

编辑:实现这一点的一个简单方法是像下面的代码片段一样查找蓝牙设备

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);
希望能有帮助


快乐编码

要查找设备,首先通过调用BluetoothAdapter.getDefaultAdapter获取蓝牙适配器

要开始发现,只需从蓝牙适配器调用startDiscovery即可。此进程是异步的,因此它将立即返回。为了捕获发现过程,我们可以注册一个BroadcastReceiver,其中包含ACTION\u FOUND、ACTION\u discovery\u STARTED、ACTION\u discovery\u STARTED。对于找到的每个设备,intent将携带包含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();
接收人:

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());
            }
        }
    };
另外,不要忘记在Activity的onDestroy方法上注销接收器:

@Override
    public void onDestroy() {
        unregisterReceiver(mReceiver);

        super.onDestroy();
    }

尝试使用此代码,它对我有效

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();  
            } 



}

我忘了在清单文件中声明位置权限。要以编程方式发现蓝牙设备,您需要添加两个权限,即访问\u FINE\u LOCATION和访问\u rough\u LOCATION。

添加清单权限,如下所示

<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />`
然后尝试以下代码:

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);
}

我试了所有的答案,但你不能全部试。那么告诉我们你到底尝试了什么?到底是什么不起作用?我尝试了下面的答案,我的listview显示为空可能是因为您没有请求权限?我可以打开和关闭它,即使它显示成对的设备,但不能显示新发现的设备列表。请检查我的代码我编辑了我的问题您需要请求位置权限才能发现设备。感谢重播。我尝试使用您的代码,但listview显示为空
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);
}