Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间数据传输(4)

本文涉及的产品
数据传输服务 DTS,数据迁移 small 3个月
推荐场景:
MySQL数据库上云
数据传输服务 DTS,数据同步 small 3个月
推荐场景:
数据库上云
数据传输服务 DTS,数据同步 1个月
简介: Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间数据传输(4)附录文章3简介了Android Bluetooth蓝牙设备之间的连接建立,和Java网络编程的socket套接字连接建立一样,Android不同的Bluetooth蓝牙设备间的socket连接建立后,就可以进行数据传输了。


Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间数据传输(4)


附录文章3简介了Android Bluetooth蓝牙设备之间的连接建立,和Java网络编程的socket套接字连接建立一样,Android不同的Bluetooth蓝牙设备间的socket连接建立后,就可以进行数据传输了。
Android Bluetooth蓝牙的socket编程模型和Java网络编程模型类似,数据传输模型也是基于流的模型。在Java网络编程中,从一个socket套接字获得输入(InputStream)、输出流(OutputStream),进而进行服务器端和客户端的点到点的数据传输(读和写)。而Android Bluetooth蓝牙数据传输基本可以认为就是仿照Java的流模型。
附录文章3完成了两个不同蓝牙设备的socket套接字的连接,本文在附录文章3的基础上更进一步,从已经建立socket套接字的基础上获取输入输出流,从而完成一个简单的数据传输,实现一个简单的功能:Android Bluetooth蓝牙设备服务端等待客户连接请求,当外部的一个Android Bluetooth蓝牙设备传入一个连接请求并与服务器端建立连接后,服务器端就发给客户端一个简单的字符串数据比如经典的hello,world!
为了完成上述简单的字符串传输,其实就是在附录文章3的基础上、从已有的socket像Java网络编程中的socket一样获取InputStream进行数据的读、获取OutputStream进行数据的写。
还是先简单描述一下编程模型的逻辑思路划分:
(A)还是在一个蓝牙设备上部署服务器端代码,然后在一个while循环里面等待客户端连接请求。当有客户端请求进来并且建立socket连接后,服务器端就从这个socket获取OutputStream,至此,问题就简化成一般的Java流的写,然后在这个OutputStream写入hello,world!即可。
(B)在另外一个蓝牙设备上部署客户端代码。客户端代码扫描获得服务器端Android Bluetooth设备后,就发起对服务器端蓝牙设备的连接(这部分过程在我写的附录文章1中已有简介)。获得服务器端蓝牙设备后,就像我写的附录文章3那样,和服务器端建立socket连接,然后从这个socket获得InputStream,到这个阶段,问题就简化成一般的Java流的读,从这个InputStream把hello,world!读出来即可。

上述功能过程的完整代码(Android Bluetooth蓝牙服务器端):

package zhangphil.bluetooth;

import java.io.OutputStream;
import java.util.UUID;

import android.app.ListActivity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends ListActivity {

	private BluetoothAdapter mBluetoothAdapter;

	private final String tag = "zhangphil";
	private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";

	private class ServerThread extends Thread {

		private BluetoothServerSocket serverSocket;

		@Override
		public void run() {

			try {
				serverSocket = mBluetoothAdapter.listenUsingRfcommWithServiceRecord(tag, UUID.fromString(MY_UUID));
			} catch (Exception e) {
				e.printStackTrace();
			}

			Log.d(tag, "等待客户连接...");
			while (true) {
				try {
					BluetoothSocket socket = serverSocket.accept();

					BluetoothDevice device = socket.getRemoteDevice();
					Log.d(tag, "接受客户连接 , 远端设备名字:" + device.getName() + " , 远端设备地址:" + device.getAddress());

					if (socket.isConnected()) {
						Log.d(tag, "已建立与客户连接.");

						// 写数据
						sendDataToClient(socket);
					}

				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		}

		// 蓝牙服务端发送简单的一个字符串:hello,world!给连接的客户
		private void sendDataToClient(BluetoothSocket socket) {
			String s = "hello,world ! by zhangphil";
			byte[] buffer = s.getBytes();

			try {
				OutputStream os = socket.getOutputStream();

				os.write(buffer);
				os.flush();

				// os.close();
				// socket.close();

				Log.d(tag, "服务器端数据发送完毕!");
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
		if (mBluetoothAdapter != null)
			new Thread(new ServerThread()).start();
	}
}


相应的,完整的Android Bluetooth蓝牙客户端代码:

package zhangphil.client;

import java.io.InputStream;
import java.util.UUID;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends Activity {

	private BluetoothAdapter mBluetoothAdapter;

	private final String tag = "zhangphil";
	private final String MY_UUID = "00001101-0000-1000-8000-00805F9B34FB";

	// 广播接收发现蓝牙设备
	private BroadcastReceiver mReceiver = new BroadcastReceiver() {

		@Override
		public void onReceive(Context context, Intent intent) {
			String action = intent.getAction();
			if (BluetoothDevice.ACTION_FOUND.equals(action)) {

				BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);

				String name = device.getName();
				if (name != null)
					Log.d(tag, "发现设备:" + name);

				if (name != null && name.equals("zhangphil_pad")) {
					Log.d(tag, "发现目标设备,开始线程连接!");

					// 蓝牙搜索是非常消耗系统资源开销的过程,一旦发现了目标感兴趣的设备,可以考虑关闭扫描。
					mBluetoothAdapter.cancelDiscovery();

					new Thread(new ClientThread(device)).start();
				}
			}
		}
	};

	private class ClientThread extends Thread {

		private BluetoothDevice device;

		public ClientThread(BluetoothDevice device) {
			this.device = device;
		}

		@Override
		public void run() {

			BluetoothSocket socket = null;

			try {
				socket = device.createRfcommSocketToServiceRecord(UUID.fromString(MY_UUID));

				Log.d(tag, "连接服务端...");
				socket.connect();
				Log.d(tag, "连接建立.");

				// 读数据
				readDataFromServer(socket);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}

		private void readDataFromServer(BluetoothSocket socket) {
			byte[] buffer = new byte[64];
			try {
				InputStream is = socket.getInputStream();

				int cnt = is.read(buffer);
				is.close();

				String s = new String(buffer, 0, cnt);
				Log.d(tag, "收到服务端发来数据:" + s);
			} catch (Exception e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

		// 注册广播接收器。接收蓝牙发现讯息
		IntentFilter filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
		registerReceiver(mReceiver, filter);

		if (mBluetoothAdapter.startDiscovery()) {
			Log.d(tag, "启动蓝牙扫描设备...");
		}
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
		unregisterReceiver(mReceiver);
	}
}


注意在连接阶段设备名的区分设置,我写的这个例子,在蓝牙互相并连接阶段,是根据蓝牙设备的名字进行过滤和配对的。在我写的这个例子中,服务端的Android Bluetooth蓝牙设备名字设置成:zhangphil_pad。服务器端代码和客户端代码分别部署在不同的Android Bluetooth蓝牙设备终端。
代码运行结果如图(客户端读到的数据,logcat的输出):


附录文章:

1,《Android Bluetooth蓝牙开发:发现Bluetooth蓝牙设备(1)》链接地址:http://blog.csdn.net/zhangphil/article/details/50524809
2,《Android Bluetooth蓝牙开发:Bluetooth蓝牙设备配对Paired Bluetooth Devices(2)》链接地址:http://blog.csdn.net/zhangphil/article/details/50537796
3,《Android Bluetooth蓝牙开发:Bluetooth蓝牙设备之间的连接建立(3)》链接地址:http://blog.csdn.net/zhangphil/article/details/50554415
4,Android Bluetooth蓝牙开发Google官方文档链接地址:http://developer.android.com/intl/zh-cn/guide/topics/connectivity/bluetooth.html

相关实践学习
部署高可用架构
本场景主要介绍如何使用云服务器ECS、负载均衡SLB、云数据库RDS和数据传输服务产品来部署多可用区高可用架构。
Sqoop 企业级大数据迁移方案实战
Sqoop是一个用于在Hadoop和关系数据库服务器之间传输数据的工具。它用于从关系数据库(如MySQL,Oracle)导入数据到Hadoop HDFS,并从Hadoop文件系统导出到关系数据库。 本课程主要讲解了Sqoop的设计思想及原理、部署安装及配置、详细具体的使用方法技巧与实操案例、企业级任务管理等。结合日常工作实践,培养解决实际问题的能力。本课程由黑马程序员提供。
相关文章
|
7天前
|
JavaScript Linux 网络安全
Termux安卓终端美化与开发实战:从下载到插件优化,小白也能玩转Linux
Termux是一款安卓平台上的开源终端模拟器,支持apt包管理、SSH连接及Python/Node.js/C++开发环境搭建,被誉为“手机上的Linux系统”。其特点包括零ROOT权限、跨平台开发和强大扩展性。本文详细介绍其安装准备、基础与高级环境配置、必备插件推荐、常见问题解决方法以及延伸学习资源,帮助用户充分利用Termux进行开发与学习。适用于Android 7+设备,原创内容转载请注明来源。
64 19
|
1月前
|
JavaScript 搜索推荐 Android开发
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
70 8
【01】仿站技术之python技术,看完学会再也不用去购买收费工具了-用python扒一个app下载落地页-包括安卓android下载(简单)-ios苹果plist下载(稍微麻烦一丢丢)-客户的麻将软件需要下载落地页并且要做搜索引擎推广-本文用python语言快速开发爬取落地页下载-优雅草卓伊凡
|
1月前
|
前端开发 Java Shell
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
184 20
【08】flutter完成屏幕适配-重建Android,增加GetX路由,屏幕适配,基础导航栏-多版本SDK以及gradle造成的关于fvm的使用(flutter version manage)-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
Dart 前端开发 Android开发
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
59 4
【09】flutter首页进行了完善-采用android studio 进行真机调试开发-增加了直播间列表和短视频人物列表-增加了用户中心-卓伊凡换人优雅草Alex-开发完整的社交APP-前端客户端开发+数据联调|以优雅草商业项目为例做开发-flutter开发-全流程-商业应用级实战开发-优雅草Alex
|
1月前
|
安全 Android开发 iOS开发
escrcpy:【技术党必看】Android开发,Escrcpy 让你无线投屏新体验!图形界面掌控 Android,30-120fps 超流畅!🔥
escrcpy 是一款基于 Scrcpy 的开源项目,使用 Electron 构建,提供图形化界面来显示和控制 Android 设备。它支持 USB 和 Wi-Fi 连接,帧率可达 30-120fps,延迟低至 35-70ms,启动迅速且画质清晰。escrcpy 拥有丰富的功能,包括自动化任务、多设备管理、反向网络共享、批量操作等,无需注册账号或广告干扰。适用于游戏直播、办公协作和教育演示等多种场景,是一款轻量级、高性能的 Android 控制工具。
|
10月前
|
SQL 分布式计算 监控
在数据传输服务(DTS)中,要查看每个小时源端产生了多少条数据
【2月更文挑战第32天】在数据传输服务(DTS)中,要查看每个小时源端产生了多少条数据
106 6
|
10月前
|
存储 SQL NoSQL
数据传输DTS同步问题之同步失败如何解决
数据传输服务(DTS)是一项专注于数据迁移和同步的云服务,在使用过程中可能遇到多种问题,本合集精选常见的DTS数据传输问题及其答疑解惑,以助用户顺利实现数据流转。
|
10月前
|
Cloud Native NoSQL 关系型数据库
数据传输DTS校验问题之校验报错如何解决
数据传输服务(DTS)是一项专注于数据迁移和同步的云服务,在使用过程中可能遇到多种问题,本合集精选常见的DTS数据传输问题及其答疑解惑,以助用户顺利实现数据流转。
|
7月前
|
存储 安全 关系型数据库
跨越地域的数据传输大冒险!如何轻松更换DTS实例地域,全面攻略揭秘!
【8月更文挑战第15天】在数字时代的浪潮中,数据传输服务(DTS)是企业跨地域扩张的重要桥梁。然而,更换DTS实例地域就像是一场冒险旅程,充满了未知和挑战。本文将带你踏上这场跨越地域的数据传输大冒险,揭示如何轻松更换DTS实例地域的秘密。无论你是追求速度的迁移高手,还是成本敏感的手动操作者,这里都有你需要的答案。让我们一起探索这个神秘的世界,解锁数据传输的无限可能!
97 0
|
7月前
|
关系型数据库 MySQL OLAP
数据传输DTS是什么?
【8月更文挑战第30天】数据传输DTS是什么?
730 3

热门文章

最新文章