Android 经典蓝牙开发
误区:接受第一个蓝牙项目时,想当然地认为传统蓝牙与低功耗蓝牙协议和工作方式是一样的,只是低功耗蓝牙更省电而已。其实这两者不仅工作方式不同,通信协议也是不同的。
一、权限申请
Android6.0搜索周围的蓝牙设备,需要位置权限 ACCESS_COARSE_LOCATION 和ACCESS_FINE_LOCATION 其中的一个,并且将手机的位置服务(定位 GPS)打开。
1、清单文件
<!-- 使用蓝牙的权限 -->
<uses-permission android:name="android.permission.BLUETOOTH" />
<!-- 扫描蓝牙设备或者操作蓝牙设置 -->
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!--模糊定位权限,仅作用于6.0+-->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<!--精准定位权限,仅作用于6.0+-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2、权限申请工具类(LocalUtils.java)
这个类用来检查GPS和定位权限,回调在Activity里面。
public class LocalUtils {
//申请权限
public static final int permission_LocationCode = 101;
//打开gps定位
public static final int open_GPSCode = 102;
static String[] permissionsIndex;
/**
* 此方法用来检查gps和定位权限,先检查gps是否打开,在检查是否有定位权限
* @param activity 上下文对象
* @param permissions 权限的名称
* @return
*/
public static boolean checkLocalPermissiion(Activity activity, String[] permissions) {
permissionsIndex = permissions;
if (checkGPSIsOpen(activity)) {
return checkPermissions(activity);
} else {
Toast.makeText(activity, "需要打开GPS", Toast.LENGTH_SHORT).show();
goToOpenGPS(activity);
}
return false;
}
/**
* 检查GPS是否打开
*
*/
public static boolean checkGPSIsOpen(Activity activity) {
LocationManager locationManager = (LocationManager) activity.getSystemService(Context.LOCATION_SERVICE);
if (locationManager == null)
return false;
return locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
}
/**
* 检查权限并申请权限
*/
public static boolean checkPermissions(final Activity activity) {
List<String> permissionDeniedList = new ArrayList<>();
for (String permission : permissionsIndex) {
int permissionCheck = ContextCompat.checkSelfPermission(activity, permission);
if (permissionCheck == PackageManager.PERMISSION_GRANTED) {
return true;
} else {
permissionDeniedList.add(permission);
}
}
if (!permissionDeniedList.isEmpty()) {
String[] deniedPermissions = permissionDeniedList.toArray(new String[permissionDeniedList.size()]);
ActivityCompat.requestPermissions(activity, deniedPermissions, permission_LocationCode);
}
return false;
}
/**
* 去手机设置打开GPS
*
* @param activity
*/
public static void goToOpenGPS(Activity activity) {
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
activity.startActivityForResult(intent, open_GPSCode);
}
}
在Activity里面回调:
//GPS
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case LocalUtils.open_GPSCode://检查是否手机打开定位
if (LocalUtils.checkGPSIsOpen(this)) {
LocalUtils.checkLocalPermissiion(this, permissions);//检查定位权限
} else {
LocalUtils.goToOpenGPS(this);//打开GPS
}
break;
}
}
/**
* 权限回调
*/
@Override
public final void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case LocalUtils.permission_LocationCode://是否打开允许定位权限
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
initClassica();//初始化经典蓝牙
}
}
}
break;
}
}
二、开启蓝牙
1、获取BluetoothAdapter
获取BluetoothAdapter两种方式:
方式一:
BluetoothManager systemService = (BluetoothManager) getSystemService(Context.BLUETOOTH_SERVICE);
BluetoothAdapter bluetoothAdapter = systemService.getAdapter();
方式二:
BluetoothAdapter bluetoothAdapter =BluetoothAdapter.getDefaultAdapter();
2、判断设备是否支持蓝牙
如果 BluetoothAdapter.getDefaultAdapter()==null,不支持,否则支持。
3、开启蓝牙
/**
* 自动打开蓝牙(同步)
* 这个方法打开蓝牙会弹出提示
* 需要在onActivityResult 方法中判断resultCode == RESULT_OK true为成功
*/
public void openBlueSync(Activity activity, int requestCode) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(intent, requestCode);
}
三、扫描蓝牙
1、扫描蓝牙
/**
* 扫描的方法 返回true 扫描成功
* 通过接收广播获取扫描到的设备
* @return
*/
public boolean scanBlueTooth() {
//当前是否在扫描,如果是就取消当前的扫描,重新扫描
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
//此方法是个异步操作,一般搜索12秒
return bluetoothAdapter.startDiscovery();
}
2、取消扫描
/**
* 取消扫描蓝牙
* @return true 为取消成功
*/
public boolean cancelScanBule() {
return bluetoothAdapter.cancelDiscovery();
}
3、广播接收扫描的结果
系统自动回发送广播,告诉我们,扫描出来的蓝牙设备。定义接口回调广播中的结果(ClientCallBack.java)
public interface ClientCallBack {
//开始扫描
void onScanStarted();
//扫描结束
void onScanFinished();
//扫描中
void onScanning(BluetoothDevice device);
//配对请求
void onBondRequest();
//配对成功
void onBondSuccess(BluetoothDevice device);
//正在配对
void onBonding(BluetoothDevice device);
//配对失败
void onBondFail(BluetoothDevice device);
//连接成功
void onConnectSuccess();
//连接失败
void onConnectFail(String errorMsg);
//连接关闭
void onConnectClose();
}
BlueReceiver.java
public class BlueReceiver extends BroadcastReceiver {
private String pin = "0000"; //此处为你要连接的蓝牙设备的初始密钥,一般为1234或0000
private static final String TAG = "mcy_Receiver";
private ClientCallBack callBack;
public BlueReceiver(ClientCallBack callBack) {
this.callBack = callBack;
}
public void setCallBack(ClientCallBack callBack){
this.callBack=callBack;
}
//广播接收器,当远程蓝牙设备被发现时,回调函数onReceiver()会被执行
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
Log.d(TAG, "action:" + action);
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(callBack==null){
return;
}
switch (action) {
case BluetoothAdapter.ACTION_DISCOVERY_STARTED:
callBack.onScanStarted();
break;
case BluetoothAdapter.ACTION_DISCOVERY_FINISHED:
callBack.onScanFinished();
break;
case BluetoothDevice.ACTION_FOUND:
callBack.onScanning(device);
break;
case BluetoothDevice.ACTION_PAIRING_REQUEST:
callBack.onBondRequest();
break;
case BluetoothDevice.ACTION_BOND_STATE_CHANGED:
switch (device.getBondState()) {
case BluetoothDevice.BOND_NONE:
callBack.onBondFail(device);
break;
case BluetoothDevice.BOND_BONDING:
callBack.onBonding(device);
break;
case BluetoothDevice.BOND_BONDED:
callBack.onBondSuccess(device);
break;
}
break;
}
}
}
为了方便统一管理,把蓝牙的操作写在服务里面,ClassicsBlueToothService.java,因此,把广播注册在服务里面。
public class ClassicsBlueToothService extends Service {
private IntentFilter filter;
private BlueReceiver pinBlueReceiver;
@Override
public void onCreate() {
super.onCreate();
//获取蓝牙适配器
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//注册广播
//蓝牙广播,系统自动发送广播,只要设置制定的 action 即可
filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//结束扫描
filter.addAction(BluetoothDevice.ACTION_FOUND);//发现设备
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);//发起配对请求
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配对状态
pinBlueReceiver = new BlueReceiver(blueCallBack);
registerReceiver(pinBlueReceiver, filter);//注册广播
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(pinBlueReceiver);
}
... ... ...
}
四、配对蓝牙
配对:
/**
* 配对(配对成功与失败通过广播返回)
* @param device
*/
public void pinBlueTooth(BluetoothDevice device) {
if (device == null) {
Log.e("mcy", "设备不可以为空");
return;
}
//配对之前把扫描关闭
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
//判断设备是否配对,没有配对在配,配对了就不需要配了
if (device.getBondState() == BluetoothDevice.BOND_NONE) {//BOND_NONE 没有配对状态
Log.d("mcy", "attemp to bond:" + device.getName());
try {
boolean returnValue = device.createBond();
Log.e("是否配对成功:", "" + returnValue);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("mcy", "配对失败");
}
}
}
取消配对:
/**
* 取消配对(取消配对成功与失败通过广播返回 也就是配对失败)
*
* @param device
*/
public void cancelPinBuleTooth(BluetoothDevice device) {
if (device == null) {
Log.d("mcy", "设备不可以为空");
return;
}
//判断设备是否配对,没有配对就不用取消了
if (device.getBondState() != BluetoothDevice.BOND_NONE) {
Log.d("mcy", "配对--" + device.getName());
try {
Method removeBondMethod = device.getClass().getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(device);
returnValue.booleanValue();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("mcy", "取消配对失败");
}
}
}
五、连接蓝牙
这里说一下 uuid 的问题,要想进行通信,客户端和服务端必须一致,否则连接失败,因为我用的手机进行的通讯,所以写了双向通信,既可以写也可以读。
连接蓝牙
注意:在连接蓝牙的同时,开启一个子线程,用来写入数据。
/**
* @param uuid 用户指定的 uuid ,可随意写,只要格式对就行
* @param device 连接的设备
*/
public void connectionBlueTooth(String uuid, BluetoothDevice device) {
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
if (bluetoothSocket != null && !bluetoothSocket.isConnected()) {
sendDataThread = new ClientThread(bluetoothSocket, blueCallBack);
sendDataThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
ClientThread.java
public class ClientThread extends Thread {
private static final String TAG = "mcy";
private ClientCallBack callBack;
private BluetoothSocket bluetoothSocket = null;
private Handler handler;
private OutputStream outputStream;
public ClientThread(BluetoothSocket bluetoothSocket, ClientCallBack callBack) {
this.callBack = callBack;
this.bluetoothSocket = bluetoothSocket;
}
/**
* 写数据
*
* @param data
*/
public void write(byte[] data) {
Message message = new Message();
message.obj = data;
handler.sendMessage(message);
}
/**
* 关闭各种连接连接
*/
public void closeSocket() {
try {
outputStream.close();
bluetoothSocket.close();
callBack.onConnectClose();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
bluetoothSocket.connect();
outputStream = bluetoothSocket.getOutputStream();//读取需要发送的的数据
Looper.prepare();
handler = new Handler() {
@Override
public void handleMessage(Message msg) {
try {
byte[] data = (byte[]) msg.obj;
outputStream.write(data);
outputStream.flush();
} catch (IOException e) {
e.printStackTrace();
}
}
};
callBack.onConnectSuccess();
Looper.loop();
} catch (IOException e) {
callBack.onConnectFail(e.getMessage());
}
}
}
六、通信(实现双向通信)
1、客户端发送数据
/**
* 写数据
*/
public void sendData(byte[] data) {
if (sendDataThread != null) {
sendDataThread.write(data);
}
}
2、客户端接收数据
/**
* 读数据
*/
public void readListern(String name, String uuid, ServiceCallback callBack) {
acceptThread = new AcceptThread(name, uuid, bluetoothAdapter, callBack);
acceptThread.start();
}
定义一个接口,来监听,收到数据的状态
public interface ServiceCallback {
//连接成功
void onConnectSuccess();
//连接失败
void onConnectFail(String errorMsg);
//连接关闭
void onConnectClose();
//接收到的数据
void onResultMessage(byte[] data);
}
开启一个子线程,用来监听服务端发过来的数据
public class AcceptThread extends Thread {
private static final String TAG = "mcy";
private ServiceCallback callBack;
private BluetoothServerSocket serverSocket = null;
private InputStream inputStream;
private BufferedInputStream bufferedInputStream;
private byte[] data;
public AcceptThread(String name, String uuid, BluetoothAdapter bluetoothAdapter, ServiceCallback callBack) {
this.callBack = callBack;
try {
serverSocket = bluetoothAdapter.listenUsingRfcommWithServiceRecord(name, UUID.fromString(uuid));
} catch (IOException e) {
e.printStackTrace();
callBack.onConnectFail(e.getMessage());
}
}
/**
* 关闭各种流和通信的socket
*/
public void closeSocket() {
try {
inputStream.close();
bufferedInputStream.close();
serverSocket.close();
callBack.onConnectClose();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
try {
final BluetoothSocket bluetoothSocket = serverSocket.accept();
callBack.onConnectSuccess();
inputStream = bluetoothSocket.getInputStream();//获取服务端发来的消息
bufferedInputStream = new BufferedInputStream(inputStream);
while (true) {
int available =0;
wh:
lable==0){
available=inputStream.available();
}
data = new byte[available];
bufferedInputStream.read(data);
callBack.onResultMessage(data);//回传数据
}
} catch (IOException e) {
callBack.onConnectFail(e.getMessage());
e.printStackTrace();
}
}
}
七、关闭各种通信
在第五步和第六步的子线程里均有关闭通信的方法
/**
* 写数据断开连接
*
* @return
*/
public void cancleConnecion() {
sendDataThread.closeSocket();
}
/**
* 写数据断开连接
*
* @return
*/
public void cancleServiceConnecion() {
acceptThread.closeSocket();
}
MainActivity.java
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = "mcy";
private TextView textView;
private TextView textView2;
private TextView textView3;
private EditText editTxt;
String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
private final int openBTCode = 100;
// ----------------经典蓝牙------------------
private ClassicsBlueToothService.ClassicaBlueToothBind classicaBTBind;
private ServiceConnection classicaConnection;
private List<BluetoothDevice> devicesList = new ArrayList<>();
private ClientCallBack blueCallBack;
private String text = "";
private String uuid = "6db14d27-04f1-4df8-98ca-356dfc16ee43";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initView();
//检查权限 >6.0以上版本需要动态的申请定位权限,< 6.0 清单文件声明了即可
if (LocalUtils.checkLocalPermissiion(this, permissions)) {
initClassica();
}
}
private void initView() {
textView = findViewById(R.id.textView);
textView2 = findViewById(R.id.textView2);
textView3 = findViewById(R.id.textView3);
editTxt = findViewById(R.id.editTxt);
findViewById(R.id.button5).setOnClickListener(this);
findViewById(R.id.button11).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.button5://经典--写数据
text = editTxt.getText().toString();
classicaBTBind.sendData(text.getBytes());
break;
case R.id.button11://低功耗--发送数据
break;
}
}
private void initClassica() {
blueCallBack = new ClientCallBack() {
@Override
public void onScanStarted() {
Log.e("mcy", "开始扫描");
}
@Override
public void onScanFinished() {
Log.e("mcy", "结束扫描");
}
@Override
public void onScanning(BluetoothDevice device) {
Log.e("mcy", "扫描到设备-->" + device.getName());
if (!devicesList.contains(device)) {
//将设备加入列表数据中
devicesList.add(device);
}
textView.setText(textView.getText() + "\n" + device.getName());
Log.e(TAG, "" + device.getName());
//已配对的蓝牙
if (device.getBondState() == BluetoothDevice.BOND_BONDED) {//BOND_BONDED 已经配对状态
textView2.setText(textView2.getText() + "\n" + device.getName());
} else {
classicaBTBind.pinBlueTooth(devicesList.get(0));
}
}
@Override
public void onBondRequest() {
Log.e("mcy", "开始配对");
}
@Override
public void onBondFail(BluetoothDevice device) {
Log.e("mcy", "取消配对");
}
@Override
public void onBonding(BluetoothDevice device) {
Log.e("mcy", "配对中");
}
@Override
public void onBondSuccess(BluetoothDevice device) {
Log.e("mcy", "配对成功");
classicaBTBind.connectionBlueTooth(uuid, device);
//registReadListener(); //测试使用,双端通讯
}
@Override
public void onConnectSuccess() {
Log.e("mcy", "连接成功");
}
@Override
public void onConnectFail(String errorMsg) {
Log.e("mcy", "连接失败" + errorMsg);
}
@Override
public void onConnectClose() {
Log.e("mcy", "连接关闭");
}
};
classicaConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
classicaBTBind = ((ClassicsBlueToothService.ClassicaBlueToothBind) service);
if (blueCallBack != null) {
classicaBTBind.setBlueCallback(blueCallBack);//设置广播监听
}
if (classicaBTBind.getAdapter() != null) {
//判断蓝牙是否开启
if (!classicaBTBind.getAdapter().isEnabled()) {
//打开蓝牙
openBlueSync(MainActivity.this, openBTCode);
} else {
//========================开始执行工作=============================
classicaBTBind.scanBlueTooth();//扫描蓝牙
registReadListener();//注册读数据事件
}
} else {
Toast.makeText(MainActivity.this, "此设备不支持蓝牙", Toast.LENGTH_SHORT).show();
}
}
@Override
public void onServiceDisconnected(ComponentName name) {
classicaBTBind = null;
}
};
bindService(new Intent(this, ClassicsBlueToothService.class), classicaConnection, BIND_AUTO_CREATE);
}
//经典蓝牙注册读数据事件
private void registReadListener() {
classicaBTBind.readListern("Demo", uuid, new ServiceCallback() {
@Override
public void onConnectSuccess() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("mcy", "读数据连接成功~");
}
});
}
@Override
public void onConnectFail(final String errorMsg) {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("mcy", "读数据连接失败" + errorMsg);
}
});
}
@Override
public void onConnectClose() {
runOnUiThread(new Runnable() {
@Override
public void run() {
Log.e("mcy", "读数据连接关闭");
}
});
}
@Override
public void onResultMessage(final byte[] data) {
runOnUiThread(new Runnable() {
@Override
public void run() {
textView3.setText(new String(data));
}
});
}
});
}
/**
* 自动打开蓝牙(同步)
* 这个方法打开蓝牙会弹出提示
* 需要在onActivityResult 方法中判断resultCode == RESULT_OK true为成功
*/
public void openBlueSync(Activity activity, int requestCode) {
Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
activity.startActivityForResult(intent, requestCode);
}
//GPS
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case LocalUtils.open_GPSCode://检查是否手机打开定位
if (LocalUtils.checkGPSIsOpen(this)) {
LocalUtils.checkLocalPermissiion(this, permissions);
} else {
LocalUtils.goToOpenGPS(this);
}
break;
}
}
/**
* 权限回调
*/
@Override
public final void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case LocalUtils.permission_LocationCode://是否打开允许定位权限
if (grantResults.length > 0) {
for (int i = 0; i < grantResults.length; i++) {
if (grantResults[i] == PackageManager.PERMISSION_GRANTED) {
initClassica();//初始化经典蓝牙
}
}
}
break;
}
}
@Override
protected void onDestroy() {
super.onDestroy();
unbindService(classicaConnection);
}
}
ClassicsBlueToothService.java:
public class ClassicsBlueToothService extends Service {
private IntentFilter filter;
private BlueReceiver pinBlueReceiver;
private BluetoothAdapter bluetoothAdapter;
private ClientThread sendDataThread;
private BluetoothSocket bluetoothSocket;
private ClientCallBack blueCallBack;
private AcceptThread acceptThread;
@Override
public void onCreate() {
super.onCreate();
//获取蓝牙适配器
bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
//注册广播
//蓝牙广播,系统自动发送广播,只要设置制定的 action 即可
filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);//开始扫描
filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);//结束扫描
filter.addAction(BluetoothDevice.ACTION_FOUND);//发现设备
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);//发起配对请求
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);//配对状态
pinBlueReceiver = new BlueReceiver(blueCallBack);
registerReceiver(pinBlueReceiver, filter);
}
@Override
public void onDestroy() {
super.onDestroy();
unregisterReceiver(pinBlueReceiver);
}
public class ClassicaBlueToothBind extends Binder {
public BluetoothAdapter getAdapter() {
return bluetoothAdapter;
}
public void setBlueCallback(ClientCallBack callback) {
ClassicsBlueToothService.this.blueCallBack = callback;
pinBlueReceiver.setCallBack(callback);
}
/**
* 扫描的方法 返回true 扫描成功
* 通过接收广播获取扫描到的设备
*
* @return
*/
public boolean scanBlueTooth() {
//当前是否在扫描,如果是就取消当前的扫描,重新扫描
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
//此方法是个异步操作,一般搜索12秒
return bluetoothAdapter.startDiscovery();
}
/**
* 取消扫描蓝牙
*
* @return true 为取消成功
*/
public boolean cancelScanBule() {
return bluetoothAdapter.cancelDiscovery();
}
/**
* 配对(配对成功与失败通过广播返回)
* 弹出配对框
*
* @param device
*/
public void pinBlueTooth(BluetoothDevice device) {
if (device == null) {
Log.e("mcy", "设备不可以为空");
return;
}
//配对之前把扫描关闭
if (bluetoothAdapter.isDiscovering()) {
bluetoothAdapter.cancelDiscovery();
}
//判断设备是否配对,没有配对在配,配对了就不需要配了
if (device.getBondState() == BluetoothDevice.BOND_NONE) {//BOND_NONE 没有配对状态
Log.d("mcy", "attemp to bond:" + device.getName());
try {
boolean returnValue = device.createBond();
Log.e("是否配对成功:", "" + returnValue);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("mcy", "配对失败");
}
}
}
/**
* 取消配对(取消配对成功与失败通过广播返回 也就是配对失败)
*
* @param device
*/
public void cancelPinBuleTooth(BluetoothDevice device) {
if (device == null) {
Log.d("mcy", "设备不可以为空");
return;
}
//判断设备是否配对,没有配对就不用取消了
if (device.getBondState() != BluetoothDevice.BOND_NONE) {
Log.d("mcy", "配对--" + device.getName());
try {
Method removeBondMethod = device.getClass().getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(device);
returnValue.booleanValue();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.d("mcy", "取消配对失败");
}
}
}
/**
* @param uuid 用户指定的 uuid ,可随意写,只要格式对就行,客户端和服务端保持一致即可。
* @param device 连接的设备
*/
public void connectionBlueTooth(String uuid, BluetoothDevice device) {
try {
bluetoothSocket = device.createRfcommSocketToServiceRecord(UUID.fromString(uuid));
if (bluetoothSocket != null && !bluetoothSocket.isConnected()) {
sendDataThread = new ClientThread(bluetoothSocket, blueCallBack);
sendDataThread.start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 写数据
*/
public void sendData(byte[] data) {
if (sendDataThread != null) {
sendDataThread.write(data);
}
}
/**
* 写数据断开连接
*
* @return
*/
public void cancleConnecion() {
sendDataThread.closeSocket();
}
/**
* 读数据
*/
public void readListern(String name, String uuid, ServiceCallback callBack) {
acceptThread = new AcceptThread(name, uuid, bluetoothAdapter, callBack);
acceptThread.start();
}
/**
* 写数据断开连接
*
* @return
*/
public void cancleServiceConnecion() {
acceptThread.closeSocket();
}
}
@Override
public IBinder onBind(Intent intent) {
return new ClassicaBlueToothBind();
}
}
八、小结
假设有两个经典蓝牙设备A和B,相互进行通信,根据以上过程,简单总结如下图: