软件信息网 移动端开发 安卓通讯开发——蓝牙的开启,搜索与传输

安卓通讯开发——蓝牙的开启,搜索与传输

蓝牙信息传输的关键步骤
1.首先开启蓝牙
2.搜索可用设备
3.创建蓝牙socket,获取输入输出流
4.读取和写入数据
5.断开连接关闭蓝牙

蓝牙设备操作
权限
要在应用中使用蓝牙功能,必须声明蓝牙权限 BLUETOOTH。您需要此权限才能执行任何蓝牙通信,例如请求连接、接受连接和传输数据等。

如果您希望您的应用启动设备发现或操作蓝牙设置,则还必须声明 BLUETOOTH_ADMIN 权限。 大多数应用需要此权限仅仅为了能够发现本地蓝牙设备。 除非该应用是将要应用户请求修改蓝牙设置的“超级管理员”,否则不应使用此权限所授予的其他能力。 注:如果要使用 BLUETOOTH_ADMIN 权限,则还必须拥有 BLUETOOTH 权限。

安卓通讯开发——蓝牙的开启,搜索与传输插图

打开操作
BluetoothAdapter mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
if (mBluetoothAdapter == null) {
// Device does not support Bluetooth
}

if (!mBluetoothAdapter.isEnabled()) {
Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
}

关闭操作

BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter(); 
_bluetooth.disable ():

搜索操作

BluetoothAdapter _bluetooth = BluetoothAdapter.getDefaultAdapter();
_bluetooth.startDiscovery();

UUID

蓝牙设备进行连接,需要一个唯一的UUID,在本案例中填写为6ee26c8e-a2ab-4291-adf3-8a679123616b,需要保证两个设备是相同的。

客户端与服务端

客户端

服务端

public class Server extends AppCompatActivity {
private static final int CONN_SUCCESS = 0x1;
private static final int CONN_FAIL = 0x2;
private static final int RECEIVER_INFO = 0x3;
private static final int SET_EDITTEXT_NULL = 0x4;
private static Button send;
private static TextView server_state;
private static EditText server_send;

BluetoothAdapter bluetooth = null;//本地蓝牙设备
BluetoothServerSocket serverSocket = null;//蓝牙设备Socket服务端
BluetoothSocket socket = null;//蓝牙设备Socket客户端

//输入输出流
PrintStream out;
BufferedReader in;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_server);
setTitle("蓝牙服务端");
server_state = (TextView) findViewById(R.id.server_state);
server_send = (EditText) findViewById(R.id.server_send);
send = (Button) findViewById(R.id.send);
init();
}

//创建蓝牙服务器端的Socket
private void init() {
server_state.setText("服务器已启动,正在等待连接...\n");
new Thread(new Runnable() {
@Override
public void run() {
//1.得到本地设备
bluetooth = BluetoothAdapter.getDefaultAdapter();
//2.创建蓝牙Socket服务器
try {
serverSocket = bluetooth.listenUsingRfcommWithServiceRecord("text", UUID.fromString("6ee26c8e-a2ab-4291-adf3-8a679123616b"));
//3.阻塞等待Socket客户端请求
socket = serverSocket.accept();
if (socket != null) {
out = new PrintStream(socket.getOutputStream());
in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
}
handler.sendEmptyMessage(CONN_SUCCESS);
} catch (IOException e) {
e.printStackTrace();
Message msg = handler.obtainMessage(CONN_FAIL, e.getLocalizedMessage());
handler.sendMessage(msg);
}

}
}).start();

}

//防止内存泄漏 正确的使用方法
private final MyHandler handler = new MyHandler(this);

public class MyHandler extends Handler {
//软引用
WeakReference<Server> weakReference;

public MyHandler(Server activity) {
weakReference = new WeakReference<Server>(activity);
}

@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
Server activity = weakReference.get();
if (activity != null) {
switch (msg.what) {
case RECEIVER_INFO:
setInfo(msg.obj.toString() + "\n");
break;
case SET_EDITTEXT_NULL:
server_send.setText("");
break;
case CONN_SUCCESS:
setInfo("连接成功!\n");
send.setEnabled(true);
new Thread(new ReceiverInfoThread()).start();
break;
case CONN_FAIL:
setInfo("连接失败!\n");
setInfo(msg.obj.toString() + "\n");
break;
default:
break;
}
}
}
}

private boolean isReceiver = true;

class ReceiverInfoThread implements Runnable {
@Override
public void run() {
String info = null;
while (isReceiver) {
try {
info = in.readLine();
Message msg = handler.obtainMessage(RECEIVER_INFO, info);
handler.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

public void send(View v) {
final String content = server_send.getText().toString();
if (TextUtils.isEmpty(content)) {
Toast.makeText(Server.this, "不能发送空消息", Toast.LENGTH_LONG).show();
return;
}
new Thread(new Runnable() {
@Override
public void run() {
out.println(content);
out.flush();
handler.sendEmptyMessage(SET_EDITTEXT_NULL);
}
}).start();
}

private void setInfo(String info) {
StringBuffer sb = new StringBuffer();
sb.append(server_state.getText());
sb.append(info);
server_state.setText(sb);
}

}

activity_server.xml

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".Server">

<TextView
android:id="@+id/server_text"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="服务器端"
android:textSize="33sp"
app:layout_constraintTop_toTopOf="parent" />

<TextView
android:id="@+id/server_state"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:text="当前未执行任何操作"
android:textSize="22sp"
app:layout_constraintBottom_toTopOf="@+id/server_send"
app:layout_constraintTop_toBottomOf="@+id/server_text" />

<EditText
android:id="@+id/server_send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:hint="请输入要发送的内容"
app:layout_constraintBottom_toTopOf="@+id/send" />

<Button
android:id="@+id/send"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:onClick="send"
android:text="发送"
app:layout_constraintBottom_toBottomOf="parent" />

 

</androidx.constraintlayout.widget.ConstraintLayout>

在填写完服务端手机的MAC地址后,就可以开启这两个手机进行测试,测试的结果如下:

客户端:

安卓通讯开发——蓝牙的开启,搜索与传输插图1

服务端:

安卓通讯开发——蓝牙的开启,搜索与传输插图2

作者: 商业模式软件定制开发

李铁牛,一直致力于企业客户软件定制开发,计算机专业毕业后,一直从事于互联网产品开发到现在。系统开发,系统源码:15889726201
上一篇
下一篇
联系我们

联系我们

15889726201

在线咨询: QQ交谈

邮箱: 187395037@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

关注微博
返回顶部