这一篇是代码篇之蓝牙连接,主要讲如何开启蓝牙,搜索蓝牙设备,连接蓝牙设备。
- 大致的步骤就是,首先是权限,用到蓝牙的那些权限就那几个,但是要特别注意的是在android7.0的系统上,如果要用到蓝牙,必须加入地理位置授权(谷歌那边的规定),然后我们注册广播,来监视我们需要的广播,比如BluetoothDevice.ACTION_FOUND,这条广播就是我们开启蓝牙搜索的时候,一些被我们发现的蓝牙就会自动发送这条广播,然后我们通过监视这条广播来得到这些被发现的蓝牙。也就是说我们首先要注册蓝牙广播,然后创建一个蓝牙接收器来监视一些我们要的广播。最后我们在ListView表上选择我们要连接的蓝牙设备,点击连接,这也就是列表点击事件来处理啦。
实战部分----------------------------------------------------------------------------------------------------------
首先定义一些我们需要用到的变量(包括后面我们发送数据那一篇文章也需要用到)
private BluetoothAdapter bluetoothAdapter; //本地蓝牙适配器
private BluetoothSocket bluetoothSocket;
private BluetoothDevice bluetoothDevice;
private BlueReceiver blueReceiver;
private Button send;
private List <String> list =new ArrayList<>();
private ListView listView;
private EditText editText;
private ArrayAdapter<String> adapter;
private final UUID MY_UUID = UUID
.fromString("00001101-0000-1000-8000-00805F9B34FB");
private final String NAME = "Bluetooth_Socket";
private IntentFilter filter;
一:首先我们的想法是在菜单上面的蓝牙连接按钮上实现蓝牙开启,蓝牙搜索,加载布局,然后在列表上实现连接功能。
①:首先显示菜单
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main,menu);
return true;
}
②:菜单点击事件
@Override
public boolean onOptionsItemSelected(MenuItem item) {
if (item.getItemId() == R.id.bluetooth) {
if (!bluetoothAdapter.isEnabled()) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(intent, 200);
//
}
bluetoothPermissions();//地理位置授权
bluetoothAdapter.startDiscovery();//蓝牙开始搜索
setContentView(R.layout.bluetooth);//加载RecycleView布局
listView = findViewById(R.id.list_item1);
listView.setOnItemClickListener(this);//列表点击事件
}
return true;
}
首先,我们开启蓝牙,需要各种权限,在文件中AndroidManifest.xml中加入权限,如下:
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
在这里要注意的是,在Android7.0版本后,我们蓝牙搜索的前提是要添加一个关于地理位置的权限(上面代码的bluetoothPermissions()就是地理位置授权方法
:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
③:注册蓝牙广播
注册蓝牙广播接收器,我们可以在onStart()方法中实现,也是在打开这个程序的时候实现蓝牙注册。代码如下:
@Override
protected void onStart() {
super.onStart();
blueReceiver = new BlueReceiver();
filter = new IntentFilter();
filter.addAction(BluetoothDevice.ACTION_FOUND);//发现蓝牙动作
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束动作
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//搜素开始动作
registerReceiver(blueReceiver, filter);//注册
Log.d("CZK", "蓝牙广播接受器注册完毕");
}
然后我们还得在onStop()方法上取消注册:
@Override
protected void onStop() {
super.onStop();
unregisterReceiver(blueReceiver);
Log.d("CZK", "取消注册");
}
④:注册完毕,接下来我们需要一个广播接收器。代码如下:
/*******************************************蓝牙接收器**************************************/
public class BlueReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
//发现其他蓝牙设备,如果该蓝牙设备没有被连接,则显示在列表上。
if (intent.getAction().equals(BluetoothDevice.ACTION_FOUND)) {
//发现蓝牙设备
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//获取该蓝牙设备
if(device.getBondState()!=BluetoothDevice.BOND_BONDED){
//通过getBondState获取状态,判断是否匹配
list.add(device.getName()+":"+device.getAddress()+"\n");
adapter = new ArrayAdapter<>(MainActivity.this,android.R.layout.simple_list_item_1,android.R.id.text1,list);
listView.setAdapter(adapter);
adapter.notifyDataSetChanged();
//显示在列表上面
Log.d("CZK", "蓝牙发现目标");
}
}
if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_STARTED)) {
setTitle("开始搜索");
Log.d("CZK","蓝牙搜索开始");
Toast.makeText(MainActivity.this,"开始搜素",Toast.LENGTH_SHORT).show();
}
if (intent.getAction().equals(BluetoothAdapter.ACTION_DISCOVERY_FINISHED)) {
setTitle("搜索完成(请选择配对设备)");
Log.d("CZK","蓝牙搜索结束");
Toast.makeText(MainActivity.this,"搜素结束",Toast.LENGTH_SHORT).show();
}
}
}
⑤:地理位置授权,蓝牙可见:
*************************************蓝牙discoverable************************/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode==200){
Intent dis=new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
dis.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);
startActivity(dis);
Log.d("CZK", "discoverable");//刷新
}
}
/*************************************地理位置授权请求************************/
private void bluetoothPermissions() {
if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{
android.Manifest.permission.ACCESS_COARSE_LOCATION}, 1);
Log.d("CZK", "地理位置授权成功 ");
}
}
/*************************************地理位置授权处理******************************************/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode){
case 1:
if(grantResults.length > 0&& grantResults[0]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this,"地理授权成功",Toast.LENGTH_SHORT);
}
else {
Toast.makeText(MainActivity.this,"地理授权失败",Toast.LENGTH_SHORT);
}
}
}
⑥:连接蓝牙:
@Override
/*****************************************列表点击事件**************************************/
public void onItemClick(final AdapterView<?> adapterView, View view, int i, long l) {
if(bluetoothAdapter.isDiscovering()){
//如果还在搜索,则停止搜索
bluetoothAdapter.cancelDiscovery();
}
String s = adapter.getItem(i);
String address = s.substring(s.indexOf(":")+1).trim();
if (bluetoothDevice == null){
bluetoothDevice = bluetoothAdapter.getRemoteDevice(address);
//getRemoteDevice()得到指定蓝牙的BluetoothDevice
}
try {
if (bluetoothSocket == null){
// 获取到客户端接口(获得对象)
bluetoothSocket = bluetoothDevice
.createRfcommSocketToServiceRecord(MY_UUID);
// 向服务端发送连接
bluetoothSocket.connect();
Log.d("CZK", "连接成功");
}else {
Log.d("CZK","bluetoothSocket != null");
}
} catch (IOException e) {
e.printStackTrace();
}