第一步动态申请权限,有两条
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
申请过程
implements EasyPermissions.PermissionCallbacks
private void initpers(){
if(!EasyPermissions.hasPermissions(this,pers)){
EasyPermissions.requestPermissions(this,"权限申请",RC_REQUEST_BLUETOOTH_NOR,pers);
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
EasyPermissions.onRequestPermissionsResult(requestCode,permissions,grantResults,this);
}
@Override
public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) {
toast("权限授予");
}
@Override
public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) {
toast("权限禁止");
}
申请完权限我们就可以开始干活了
先初始化数据
private void initView() {
btn_start = findViewById(R.id.btn_start);
btn_stop = findViewById(R.id.btn_stop);
btn_search = findViewById(R.id.btn_search);
btn_start.setOnClickListener(this);
btn_stop.setOnClickListener(this);
btn_search.setOnClickListener(this);
listView = findViewById(R.id.listView);
mainAdapter = new MainAdapter();
listView.setAdapter(mainAdapter);
}
private void initDate() {
bluetoothManager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE);
bluetoothAdapter = bluetoothManager.getAdapter();//蓝牙adapter
if (bluetoothAdapter == null) {
finish();
return;
}
bluetoothReceiver = new BluetoothReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);//可发现
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//搜索结束
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//绑定状态
registerReceiver(bluetoothReceiver, intentFilter);
}
然后设置功能(开启,关闭,搜索)
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
boolean flag = bluetoothAdapter.enable();
if (!flag) {
Intent intent = new Intent();
intent.setAction(BluetoothAdapter.ACTION_REQUEST_ENABLE);//启动蓝牙
intent.setAction(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);//开启本设备可被发现
intent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 200);//指定搜索设备时间
startActivityForResult(intent, 100);
bluetoothAdapter.startDiscovery();//开启搜索
}
break;
case R.id.btn_stop:
bluetoothAdapter.disable();//关闭蓝牙
list.clear();
mainAdapter.refresh(list);
break;
case R.id.btn_search:
bluetoothAdapter.startDiscovery();//开启搜索
break;
default:
break;
}
}
然后就是最后也是最终要的一步
接收广播
class MyReciver extends BroadcastReceiver{
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
switch (action){
case BluetoothDevice.ACTION_FOUND:
BluetoothDevice parcelableExtra = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
String address = parcelableExtra.getAddress();
String name = parcelableExtra.getName();
Log.i(TAG, "onReceive: "+name+"___"+address);
beans.add(new Bean(name,address));
devices.add(parcelableExtra);
myAdapter.fresh(beans);
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int state = device.getBondState();
if(state == BOND_NONE){
Log.i(TAG, "onReceive: 没有设备");
} else if (state == BOND_BONDING) {
Log.i(TAG, "onReceive: 正在匹配中");
} else if (state == BOND_BONDED) {
Log.i(TAG, "onReceive: 匹配成功");
ConnectManager connectManager = new ConnectManager(device);
}
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
break;
default:
break;
}
}
}
这样最基本的搜索附近蓝牙
在这样的基础上,我们需要一个可以与其他设备进行交互配对的方法
来自Adapter的createBond方法
来看一下
给列表添加条目点击监听,单独写一个集合用于存储搜索到的每一台设备,开个线程使其始终发生改变
然后通过反射拿到次方法,也可以直接通过devic对象去调用也行,但是不如反射稳定
‘最后则是开启一个线程与对方进行交互’信息
public class ConnectManager {
// 使用传输服务,用uuid
private String uuid = "00001101-0000-1000-8000-00805F9B34FB";
private BluetoothDevice device;
public ConnectManager(BluetoothDevice device) {
this.device = device;
new SendThread().start();
}
private BluetoothSocket socket;
class SendThread extends Thread{
@Override
public void run() {
super.run();
try {
socket = device.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
socket.connect();
OutputStream ops = socket.getOutputStream();
ops.write("蓝牙已连接".getBytes());
ops.flush();
ops.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
这里有使用到uuid,这是一个唯一的码,用以确定某种功能的(个人理解)再来个官方的
UUID 是 通用唯一识别码(Universally Unique Identifier)的缩写,是一种软件建构的标准,亦为开放软件基金会组织在分布式计算环境领域的一部分。其目的,是让分布式系统中的所有元素,都能有唯一的辨识信息,而不需要通过中央控制端来做辨识信息的指定。如此一来,每个人都可以创建不与其它人冲突的UUID。在这样的情况下,就不需考虑数据库创建时的名称重复问题。目前最广泛应用的UUID,是微软公司的全局唯一标识符(GUID),而其他重要的应用,则有Linux ext2/ext3文件系统、LUKS加密分区、GNOME、KDE、Mac OS X等等。另外我们也可以在e2fsprogs包中的UUID库找到实现。
交互也是通过socket和流实现的
简单的通讯就可以了