事先说明:
安卓蓝牙需要定位权限申请,在安卓6.0需要用户手动确认权限后才能使用,各位可以自行查询资料实现,如果嫌麻烦,可以用第三方bmob集成好的工具类进行实现,详细可以看
蓝牙连接过程:
1、查询用户是否开启蓝牙。
2、搜索附近的可用的蓝牙。
3、进行蓝牙配对。
4、进行蓝牙连接。
5、获取输入流和输出流。
6、发送消息。
实现需要的权限:由于安卓4.x以上的版本使用蓝牙,需要开启定位权限才能搜索到附近的蓝牙设备
[Java] 查看源文件 复制代码
<uses-permission android:name="android.permission.bluetooth"/>
<uses-permission android:name="android.permission.bluetooth_admin"/>
<uses-permission android:name="android.permission.access_fine_location" />
<uses-permission android:name="android.permission.access_coarse_location" />
服务端
实现思路:
1、拿到本地蓝牙设备。
2、蓝牙之间的通讯需要一个唯一识别uuid来匹配正确的设备,使用uuid获取蓝牙的通讯socket。
3、开启获取数据的线程
public class mainactivity extends appcompatactivity implements view.onclicklistener {
bluetoothsocket btsocket;
bluetoothadapter btadapter;
button bt_start;
textview tv_msg;
stringbuilder sb;
@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);
bt_start = (button) findviewbyid(r.id.bt_start);
tv_msg = (textview) findviewbyid(r.id.tv_msg);
bt_start.setonclicklistener(this);
sb = new stringbuilder();
//拿到本地蓝牙设备
btadapter = bluetoothadapter.getdefaultadapter();
}
/**
* ui文本输出
*
* @param msg
*/
public void show(string msg) {
sb.append(msg + "\n");
runonuithread(new runnable() {
@override
public void run() {
tv_msg.settext(sb.tostring());
}
});
}
@override
public void onclick(view v) {
//开启服务器
serverthread startserverthread = new serverthread();
startserverthread.start();
}
/**
* 开启服务器
*/
private class serverthread extends thread {
public void run() {
try {
bluetoothserversocket mserversocket = btadapter.listenusingrfcommwithservicerecord("btspp",
uuid.fromstring("00001101-0000-1000-8000-00805f9b34fb"));
show("服务端:等待连接");
btsocket = mserversocket.accept();
show("服务端:连接成功");
readthread mreadthread = new readthread();
mreadthread.start();
show("服务端:启动接受数据");
} catch (ioexception e) {
e.printstacktrace();
}
}
}
/**
* 读取数据
*/
private class readthread extends thread {
public void run() {
byte[] buffer = new byte[1024];
int bytes;
inputstream mminstream = null;
try {
mminstream = btsocket.getinputstream();
show("服务端:获得输入流");
} catch (ioexception e1) {
e1.printstacktrace();
}
while (true) {
try {
if ((bytes = mminstream.read(buffer)) > 0) {
byte[] buf_data = new byte[bytes];
for (int i = 0; i < bytes; i++) {
buf_data[i] = buffer[i];
}
string s = new string(buf_data);
show("服务端:读取数据了~~" + s);
}
} catch (ioexception e) {
try {
mminstream.close();
} catch (ioexception e1) {
e1.printstacktrace();
}
break;
}
}
}
}
}
1、检查是否开启蓝牙。
2、注册一系列蓝牙的广播。
3、由于蓝牙每经过一个阶段都会发送一个广播,根据广播来实现对应的方法。
4、蓝牙配对->蓝牙连接->发送消息(uuid必须相同)
public class mainactivity extends appcompatactivity implements view.onclicklistener {private textview tv_msg;
private button bt_search, bt_send;
private bluetoothsocket btsocket;
private bluetoothadapter btadapter;
private bluetoothdevice device;
private stringbuilder sb;@override
protected void oncreate(bundle savedinstancestate) {
super.oncreate(savedinstancestate);
setcontentview(r.layout.activity_main);bt_search = (button) findviewbyid(r.id.bt_search);
bt_send = (button) findviewbyid(r.id.bt_send);
tv_msg = (textview) findviewbyid(r.id.tv_msg);
bt_search.setonclicklistener(this);
bt_send.setonclicklistener(this);
sb = new stringbuilder();show(“客户端:检查bt”);
checkbt(this);
show(“客户端:注册接收者”);
registerbtreceiver();
}/**
• ui文本输出
•
• @param msg
*/
public void show(string msg) {
sb.append(msg + “\n”);
runonuithread(new runnable() {
@override
public void run() {
tv_msg.settext(sb.tostring());
}
});
}@override
public void onclick(view v) {
switch (v.getid()) {
case r.id.bt_search:
show(“客户端:开始寻找设备”);
btadapter.startdiscovery();
break;
case r.id.bt_send:
sendmessage();
break;
}
}/**
• 检查蓝牙
*/
public void checkbt(context context) {
btadapter = bluetoothadapter.getdefaultadapter();
if (btadapter != null) {
if (!btadapter.isenabled()) {
intent intent = new intent(bluetoothadapter.action_request_enable);
// 设置蓝牙可见性,最多300秒
intent.putextra(bluetoothadapter.extra_discoverable_duration, 300);
context.startactivity(intent);
}
} else {
system.out.println(“本地设备驱动异常!”);
}
}/**
• 开启客户端
*/
private class clientthread extends thread {
public void run() {
try {
//创建一个socket连接:只需要服务器在注册时的uuid号
btsocket = device.createrfcommsockettoservicerecord(uuid.fromstring(“00001101-0000-1000-8000-00805f9b34fb”));
//连接
show(“客户端:开始连接…”);
btsocket.connect();
show(“客户端:连接成功”);
//启动接受数据
show(“客户端:启动接受数据”);
readthread mreadthread = new readthread();
mreadthread.start();
} catch (ioexception e) {
show(“客户端:连接服务端异常!断开连接重新试一试”);
e.printstacktrace();
}
}
}/**
• 读取数据
*/
private class readthread extends thread {
public void run() {
byte[] buffer = new byte[1024];
int bytes;
inputstream is = null;
try {
is = btsocket.getinputstream();
show(“客户端:获得输入流”);
} catch (ioexception e1) {
e1.printstacktrace();
}
while (true) {
try {
if ((bytes = is.read(buffer)) > 0) {
byte[] buf_data = new byte[bytes];
for (int i = 0; i < bytes; i++) {
buf_data[i] = buffer[i];
}
string s = new string(buf_data);
show(“客户端:读取数据了” + s);
}
} catch (ioexception e) {
try {
is.close();
} catch (ioexception e1) {
e1.printstacktrace();
}
break;
}
}
}
}/**
• 发送数据
/
public void sendmessage() {
if (btsocket == null) {
toast.maketext(this, “没有连接”, toast.length_short).show();
return;
}
try {
outputstream os = btsocket.getoutputstream();
os.write("我爱你dahsid132456@#%¥".getbytes());
os.flush();
show(“客户端:发送信息成功”);
} catch (ioexception e) {
e.printstacktrace();
}
}/**
• 注册广播
*/
public void registerbtreceiver() {
// 设置广播信息过滤
intentfilter intentfilter = new intentfilter();
intentfilter.addaction(bluetoothdevice.action_found);
intentfilter.addaction(bluetoothadapter.action_discovery_started);
intentfilter.addaction(bluetoothadapter.action_discovery_finished);
intentfilter.addaction(bluetoothadapter.action_state_changed);
intentfilter.addaction(bluetoothdevice.action_bond_state_changed);
// 注册广播接收器,接收并处理搜索结果
registerreceiver(btreceive, intentfilter);
}/**
• 注销广播
*/
public void unregisterbtreceiver() {
unregisterreceiver(btreceive);
}@override
protected void ondestroy() {
super.ondestroy();
unregisterbtreceiver();
}/**
• 广播接收者
*/
private broadcastreceiver btreceive = new broadcastreceiver() {
@override
public void onreceive(context context, intent intent) {
string action = intent.getaction();
if (bluetoothdevice.action_found.equals(action)) {
device = intent.getparcelableextra(bluetoothdevice.extra_device);
show(“客户端:找到的bt名:” + device.getname());
// 如果查找到的设备符合要连接的设备,处理
if (device.getname().equalsignorecase(“xu”)) {
show(“客户端:配对xu蓝牙:”);
// 搜索蓝牙设备的过程占用资源比较多,一旦找到需要连接的设备后需要及时关闭搜索
btadapter.canceldiscovery();
// 获取蓝牙设备的连接状态
int connectstate = device.getbondstate();
switch (connectstate) {
// 未配对
case bluetoothdevice.bond_none:
show(“客户端:开始配对:”);
try {
method createbondmethod = bluetoothdevice.class.getmethod(“createbond”);
createbondmethod.invoke(device);
} catch (exception e) {
e.printstacktrace();
}
break;
// 已配对
case bluetoothdevice.bond_bonded:
try {
show(“客户端:开始连接:”);
clientthread clientconnectthread = new clientthread();
clientconnectthread.start();
} catch (exception e) {
e.printstacktrace();
}
break;
}
}
} else if (bluetoothdevice.action_bond_state_changed.equals(action)) {
// 获取蓝牙设备的连接状态
int connectstate = device.getbondstate();
// 已配对
if (connectstate == bluetoothdevice.bond_bonded) {
try {
show(“客户端:开始连接:”);
clientthread clientconnectthread = new clientthread();
clientconnectthread.start();
} catch (exception e) {
e.printstacktrace();
}
}
}
show(action);
}
};
}
action_state_changed 当你蓝牙开启或者关闭的时候发送
action_found 当你匹配到附近蓝牙设备时发送
action_discovery_started 当你开始搜索附近蓝牙设备时发送
action_discovery_finished 当你结束搜索附近蓝牙设备时发送
action_bond_state_changed 当你蓝牙设备匹配状态发生变化时发送