一. 蓝牙权限
<uses-permission android:name="android.permission.BLUETOOTH"/>
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN"/>
二.配对
代码走起~~ 会顺带加些常用的知识点。简书这个贴代码,格式都没了,将就的看吧,需要的时候自己再检查括号啥的,毕竟时间很紧张。
1.发起请求:
BluetoothAdapter mAdapter = BluetoothAdapter.getDefaultAdapter();
if(mAdapter!=null && mAdapter.isEnabled()){
try {
// pair before connect
BluetoothDevice Vdevice = mAdapter.getRemoteDevice(BTMAC);
if (Vdevice.getBondState() == BluetoothDevice.BOND_NONE) {
Method creMethod = BluetoothDevice.class.getMethod("createBond");
Log.e(TAG, "START pair");
creMethod.invoke(Vdevice);
} else {
Log.e(TAG, "paired!");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}else{
//;
}
2.如果需要固定码直接配对,可以使用方法:(此段代码在下面完整的广播例子中有)
if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,会等于PAIRING_REQUEST
{
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.e(TAG, action);
if(btDevice.getAddress().equals(BTMAC)) //btDevice.getName().contains("HC-05")
{
try {
//1.确认配对
ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);
//2.终止有序广播
Log.i(TAG, "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast());
abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。
//3.调用setPin方法进行配对...
boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, BTPIN);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Log.e(TAG, "NOT THE BT U WANT");
}
3.以上用到将相关方法封装的一个类,ClsUtils。也是参考网上的“轮子”,感谢热心分享的技术大牛。
public class ClsUtils
{
/**
* 与设备配对 参考源码:platform/packages/apps/Settings.git
* /Settings/src/com/android/settings/bluetooth/CachedBluetoothDevice.java
*/
static public boolean createBond(Class btClass, BluetoothDevice btDevice)
throws Exception
{
Method createBondMethod = btClass.getMethod("createBond");
Boolean returnValue = (Boolean) createBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
static public boolean removeBond(Class btClass, BluetoothDevice btDevice)
throws Exception
{
Method removeBondMethod = btClass.getMethod("removeBond");
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice);
return returnValue.booleanValue();
}
static public boolean setPin(Class btClass, BluetoothDevice btDevice,
String str) throws Exception
{
try
{
Method removeBondMethod = btClass.getDeclaredMethod("setPin",
new Class[]
{byte[].class});
Boolean returnValue = (Boolean) removeBondMethod.invoke(btDevice,
new Object[]
{str.getBytes()});
Log.e("returnValue", "" + returnValue);
}
catch (SecurityException e)
{
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
// 取消用户输入
static public boolean cancelPairingUserInput(Class btClass,
BluetoothDevice device) throws Exception
{
Method createBondMethod = btClass.getMethod("cancelPairingUserInput");
// cancelBondProcess(btClass, device);
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
// 取消配对
static public boolean cancelBondProcess(Class btClass,
BluetoothDevice device)
throws Exception
{
Method createBondMethod = btClass.getMethod("cancelBondProcess");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
}
//确认配对
static public void setPairingConfirmation(Class btClass,BluetoothDevice device,boolean isConfirm)throws Exception
{
Method setPairingConfirmation = btClass.getDeclaredMethod("setPairingConfirmation",boolean.class);
setPairingConfirmation.invoke(device,isConfirm);
}
/**
*
* @param clsShow
*/
static public void printAllInform(Class clsShow)
{
try
{
// 取得所有方法
Method[] hideMethod = clsShow.getMethods();
int i = 0;
for (; i < hideMethod.length; i++)
{
Log.e("method name", hideMethod[i].getName() + ";and the i is:"
+ i);
}
// 取得所有常量
Field[] allFields = clsShow.getFields();
for (i = 0; i < allFields.length; i++)
{
Log.e("Field name", allFields[i].getName());
}
}
catch (SecurityException e)
{
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
}
catch (IllegalArgumentException e)
{
// throw new RuntimeException(e.getMessage());
e.printStackTrace();
}
catch (Exception e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
4.配对的相关广播,查询配对状态,根据这些时机插入需要处理的事件,
顺便把广播的使用方式贴出来:
filter.addAction(UsbManager.ACTION_USB_DEVICE_ATTACHED);
filter.addAction(UsbManager.ACTION_USB_DEVICE_DETACHED);
//filter.addAction(Intent.ACTION_POWER_CONNECTED);
//filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
filter.addAction("android.bluetooth.device.action.PAIRING_REQUEST");
//filter.addAction("android.bluetooth.device.action.FOUND");
filter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
//filter.addAction("android.bluetooth.adapter.action.STATE_CHANGED");
registerReceiver(myReceiver, filter);
private BroadcastReceiver myReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if(action.equals(UsbManager.ACTION_USB_DEVICE_ATTACHED)){
Log.d(TAG, "ACTION_USB_DEVICE_ATTACHED");//这个广播是当Android系统作为host插入USB设备的时候发出的
}else if(action.equals(UsbManager.ACTION_USB_DEVICE_DETACHED)){
Log.d(TAG, "ACTION_USB_DEVICE_DETACHED");//拔出USB设备
}else if(action.equals(Intent.ACTION_POWER_CONNECTED)){
Log.d(TAG, "ACTION_POWER_CONNECTED");
}else if(action.equals(Intent.ACTION_POWER_DISCONNECTED)){
Log.d(TAG, "ACTION_POWER_DISCONNECTED");
}else if(action.equals("android.bluetooth.device.action.PAIRING_REQUEST")) //再次得到的action,会等于PAIRING_REQUEST
{
BluetoothDevice btDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
Log.e(TAG, action);
if(btDevice.getAddress().equals(BTMAC)) //btDevice.getName().contains("HC-05")
{
try {
//1.确认配对
ClsUtils.setPairingConfirmation(btDevice.getClass(), btDevice, true);
//2.终止有序广播
Log.i(TAG, "isOrderedBroadcast:"+isOrderedBroadcast()+",isInitialStickyBroadcast:"+isInitialStickyBroadcast());
abortBroadcast();//如果没有将广播终止,则会出现一个一闪而过的配对框。
//3.调用setPin方法进行配对...
boolean ret = ClsUtils.setPin(btDevice.getClass(), btDevice, BTPIN);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else{
Log.e(TAG, "NOT THE BT U WANT");
}
}else if(action.equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)) {
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
//String name = device.getName();
//Log.d("aaa", "device name: " + name);
int state = intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, -1);
switch (state) {
case BluetoothDevice.BOND_NONE:
Log.d(TAG, "BOND_NONE 删除配对");
break;
case BluetoothDevice.BOND_BONDING:
Log.d(TAG, "BOND_BONDING 正在配对");
break;
case BluetoothDevice.BOND_BONDED:
Log.d(TAG, "BOND_BONDED 配对成功");
break;
}
}else if(action.equals("android.bluetooth.adapter.action.STATE_CHANGED")){
int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE,
BluetoothAdapter.ERROR);
switch (state) {
case BluetoothAdapter.STATE_OFF:
//Log.d("aaa", "STATE_OFF 手机蓝牙关闭");
break;
case BluetoothAdapter.STATE_TURNING_OFF:
//Log.d("aaa", "STATE_TURNING_OFF 手机蓝牙正在关闭");
break;
case BluetoothAdapter.STATE_ON:
//Log.d(TAG, "STATE_ON"+s);
break;
case BluetoothAdapter.STATE_TURNING_ON:
//Log.d("aaa", "STATE_TURNING_ON 手机蓝牙正在开启");
break;
}
}else{
Log.d(TAG, action);
}
}
};
5.解配对方法:
try {
// pair before connect
BluetoothDevice Vdevice = mAdapter2.getRemoteDevice(BTMAC);
if (Vdevice.getBondState() == BluetoothDevice.BOND_BONDED) {
Method creMethod = BluetoothDevice.class.getMethod("removeBond");
Log.e(TAG, "removeBond");
creMethod.invoke(Vdevice);
} else {
Log.e(TAG, "un paired");
}
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
三.连接
private int connect(String mac) {//这个返回int状态只是因为个人项目需要,可以自行修改
Log.e("wwww", "start, was connect()? "+isConnection);
if (!this.isConnection ) {
mBluetoothDevice=mBluetoothAdapter.getRemoteDevice(mac);
try {
// 固定的UUID 串口通信profile
final String SPP_UUID = "00001101-0000-1000-8000-00805F9B34FB";
UUID uuid = UUID.fromString(SPP_UUID);
mBluetoothSocket = this.mBluetoothDevice.createRfcommSocketToServiceRecord(uuid);
mBluetoothSocket.connect();
outputStream = mBluetoothSocket.getOutputStream();
inputStream = mBluetoothSocket.getInputStream();
SocketReadThread rt = new SocketReadThread();//这个用来等待接收对方的数据
rt.setLocalSocket(inputStream, 1);
Thread thread = new Thread(rt);
thread.start();
this.isConnection = true;
} catch (Exception e) {
System.out.println("1" + e);
return -1;
}
Log.e("www", "连接成功!");
return 0;
} else {
return 0;
}
}
接收线程:
public class SocketReadThread implements Runnable
{
InputStream input;
int inum = 1;//预留
public void setLocalSocket(InputStream is, int num )
{
input = is;
inum = num;
}
public void run()
{
try {
DataInputStream dis = new DataInputStream(input);
byte[] bytes = new byte[1024];//1k
int readnum=0;
while ((readnum=dis.read(bytes)) != -1) {//阻塞
printHexString(TAG,bytes);//前面的文章有讲过这个方法
}
} catch (IOException e) {
Log.d(TAG, "read duankai");
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
四.发送数据
private boolean send(byte[] sendData) {//这个返回也是因为当时项目需要
if (this.isConnection) {
try {
//byte[] data = sendData.getBytes();//"GBK"
outputStream.write(sendData, 0, sendData.length);
outputStream.flush();
Log.e("com send", "send-flush");
} catch (IOException e) {
Log.e("com send", "send-", e);
return false;
}
return true;
} else {
Log.e("com send", "not connection");
return false;
}
}
五.关闭资源
这些不使用的时候,没关闭也是很耗资源的,不能忘记哈
private void closeBtconnect() {
// TODO Auto-generated method stub
try {
if(outputStream!=null){
outputStream.close();
outputStream=null;
}
if(inputStream!=null){
inputStream.close();
inputStream=null;
}
if(mBluetoothSocket!=null){
mBluetoothSocket.close();
mBluetoothSocket=null;
}
} catch (Exception e) {
// TODO: handle exception
}
this.isConnection = false;
}
几个主要的功能API使用大概如此。就是这个后台不适合代码编排,简书需要改进才是。
网友评论