实现数据传递需要做些什么?需要用到什么?怎么才能让数据传递到另一端? 以下几个类有什么作用,作用域在哪? 1、BluetoothAdapter 2、BluetoothDevice 3、BluetoothSocket 4、BluetoothServerScoket
- 客户端实现了的功能
1. 控制蓝牙的开关 2. 扫描发现附近蓝牙设备 3. 配对蓝牙 4. 取消正在配对 5. 解绑已经配对 6. 发送数据到服务端(demo传递100随机数) - 服务端主要实现功能
- 接收客户端传递过来的信息(接收传递来的100内随机数)
- BluetoothAdapter介绍以及作用
BluetoothAdapter代表了移动设备的本地的蓝牙适配器, 通过该蓝牙适配器可以对蓝牙进行基本操作, 例如 : 启动设备发现(startDiscovery), 获取已配对设备(getBoundedDevices), 通过mac蓝牙地址获取蓝牙设备(getRemoteDevice), 从其它设备创建一个监听连接(listenUsingRfcommWithServiceRecord); (1)开关状态值 蓝牙关闭 : int STATE_OFF , 值为10, 蓝牙模块处于关闭状态; 蓝牙打开中 : int STATE_TURNING_ON , 值为11, 蓝牙模块正在打开; 蓝牙开启 : int STATE_ON , 值为12, 蓝牙模块处于开启状态; 蓝牙开启中 : int STATE_TURNING_OFF , 值为13, 蓝牙模块正在关闭; 蓝牙开关状态顺序 : STATE_OFF --> STATE_TURNING_ON --> STATE_ON --> STATE_TURNING_OFF --> STATE_OFF; (2)扫描状态值 无功能状态 : int SCAN_MODE_NONE , 值为20, 查询扫描和页面扫描都失效, 该状态下蓝牙模块既不能扫描其它设备, 也不可见; 扫描状态 : int SCAN_MODE_CONNECTABLE , 值为21, 查询扫描失效, 页面扫描有效, 该状态下蓝牙模块可以扫描其它设备, 从可见性来说只对已配对的蓝牙设备可见, 只有配对的设备才能主动连接本设备; 可见状态 : int SCAN_MODE_CONNECTABLE_DISCOVERABLE, 值为23, 查询扫描和页面扫描都有效;
BluetoothAdapter BluetoothAdapter = BluetoothAdapter.getDefaultAdapter()
- BluetoothDevice
BluetoothDevice对象代表了一个远程的蓝牙设备, 通过这个类可以查询远程设备的物理地址, 名称, 连接状态等信息; 对这个类的操作, 会执行在远程蓝牙设备的硬件上. 对象获取途径 :
a. 调用BluetoothAdapter的getRemoteDevice(address)方法获取物理地址对应的该类对象;
b. 调用BluetoothAdapter的getBoundedDevices()方法, 可以获取已经配对的蓝牙设备集合;
- BluetoothSocket
已连接或正在连接的蓝牙插座。 蓝牙套接字的接口类似于TCP套接字:Socket和ServerSocket。在服务器端,使用BluetoothServerSocket来创建侦听服务器套接字。当一个连接被BluetoothServerSocket接受时,它将返回一个新的BluetoothSocket来管理这个连接。在客户端,使用一个单一的BluetoothSocket来发起一个传出连接和管理连接。 最常见的蓝牙套接字类型是RFCOMM,这是Android api所支持的类型。RFCOMM是一个基于蓝牙的面向连接的流传输。它也被称为串口配置文件(SPP)。 要创建一个用于连接到已知设备的BluetoothDevice.createRfcommSocketToServiceRecord()。然后调用connect()来尝试连接到远程设备。此调用将阻塞,直到连接建立或连接失败。 要创建一个作为服务器(或“主机”)的BluetoothServerSocket,请参阅BluetoothServerSocket文档。 一旦套接字连接上,无论是作为客户端初始化还是作为服务器接受,都可以通过调用getInputStream()和getOutputStream()来打开IO流,以便分别检索自动连接到套接字的InputStream和OutputStream对象。 BluetoothSocket线程安全。特别地,close()将总是立即中止正在进行的操作并关闭套接字。 - BluetoothServerScoket
收听蓝牙插座。 蓝牙套接字的接口类似于TCP套接字:Socket和ServerSocket。在服务器端,使用BluetoothServerSocket来创建侦听服务器套接字。当一个连接被BluetoothServerSocket接受时,它将返回一个新的BluetoothSocket来管理这个连接。在客户端,使用一个单一的BluetoothSocket来发起一个传出连接和管理连接。 对于蓝牙BR/EDR,最常见的套接字类型是RFCOMM,这是Android api所支持的类型。RFCOMM是一个基于蓝牙BR/EDR的面向连接的流传输。它也被称为串口配置文件(SPP)。使用BluetoothAdapter.listenUsingRfcommWithServiceRecord()来创建一个准备好接收蓝牙BR/EDR连接的侦听BluetoothServerSocket。 对于蓝牙LE,套接字使用LE面向连接通道(CoC)。LE CoC是基于蓝牙LE的面向连接的流传输,并具有基于信用的流控制。相应地,使用BluetoothAdapter.listenUsingL2capChannel()来创建一个正在监听的BluetoothServerSocket,它已经准备好接收蓝牙LE CoC连接。对于LE CoC,您可以使用getPsm()来获取对等端需要使用的协议/服务多路复用器(PSM)值来连接到您的套接字。 在创建侦听的BluetoothServerSocket之后,调用accept()来监听传入的连接请求。这个调用将阻塞,直到连接建立,此时,它将返回一个BluetoothSocket来管理连接。一旦获得了BluetoothServerSocket,当它不再需要接受连接时,在BluetoothServerSocket上调用close()是个好主意。关闭BluetoothServerSocket不会关闭返回的BluetoothSocket。 BluetoothServerSocket是线程安全。特别地,close()将总是立即中止正在进行的操作并关闭服务器套接字。 - 蓝牙的开和关
public boolean openBluetooth(){
if (!isBlueEnable()){
boolean b = false;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ECLAIR) {
b = adapter.enable();
}
LogUtil.v("openBluetooth="+b);
return b ;
}
return false ;
}
public boolean closeBluetooth(){
if (isBlueEnable()){
boolean b = false;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.ECLAIR) {
if (isDiscovering()){
cancelDiscovery() ;
}
b = adapter.disable();
}
LogUtil.v("closeBluetooth="+b);
return b ;
}
return false;
}
public boolean startDiscovery(){
if (!isBlueEnable()){
LogUtil.v("startDiscovery this is not open");
return false ;
}
if (isDiscovering()){
LogUtil.v("startDiscovery this is isDiscovering");
adapter.cancelDiscovery();
}
return adapter.startDiscovery();
}
public void register(Context context){
scanBluetoothReceiver = new ScanBluetoothReceiver();
scanBluetoothReceiver.setScanBluetoothListener(scanBluetoothListener);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
intentFilter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
intentFilter.addAction(BluetoothDevice.ACTION_FOUND);
intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
intentFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
intentFilter.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED);
intentFilter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
context.registerReceiver(scanBluetoothReceiver,intentFilter);
}
public boolean createBond(BluetoothDevice device){
if (device.getBondState()==BluetoothDevice.BOND_NONE){
Class<? extends BluetoothDevice> cls = device.getClass();
try {
Method method = cls.getMethod("createBond");
Boolean returnValue = (Boolean) method.invoke(device);
return returnValue.booleanValue();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
return false ;
}
@SuppressWarnings("unchecked")
public boolean cancelBondProcess(Class btClass, BluetoothDevice device) {
Method createBondMethod = null;
try {
createBondMethod = btClass.getMethod("cancelBondProcess");
Boolean returnValue = (Boolean) createBondMethod.invoke(device);
return returnValue.booleanValue();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false ;
}
public boolean removeBond(BluetoothDevice device){
Class<? extends BluetoothDevice> cls = device.getClass();
try {
Method method = cls.getMethod("removeBond");
Boolean returnValue = (boolean) method.invoke(device);
return returnValue.booleanValue();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return false ;
}
- 客户端发送数据到服务端(BluetoothSocket)
public void startConnect(CallBack callBack){
new Thread(new Runnable() {
@Override
public void run() {
if (serverDevice == null){
if (callBack!=null)
callBack.onError(-1,"蓝牙还未配对");
return;
}
if (socket!=null){
try {
socket.connect();
} catch (IOException connectException) {
try {
Method m = serverDevice.getClass().getMethod("createRfcommSocket", new Class[] {int.class});
socket = (BluetoothSocket) m.invoke(serverDevice, 1);
socket.connect();
} catch (Exception e) {
if (callBack!=null) callBack.onError(-1,"连接失败!");
try{
socket.close();
}catch (IOException ie){
ie.printStackTrace();
}
}
return;
}
}else {
if (callBack!=null)
callBack.onError(-1,"获取socket失败!");
return;
}
OutputStream os = null;
InputStream in = null;
try {
os = socket.getOutputStream();
in = socket.getInputStream();
sendMsgToServer(os,callBack);
new readSocketTask().execute(in) ;
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
- 服务端主要实现(BluetoothServerSocket)
private void start(){
new Thread(new Runnable() {
@SuppressLint("MissingPermission")
@Override
public void run() {
try {
socket = serverSocket.accept();
InputStream in = socket.getInputStream();
OutputStream out = socket.getOutputStream();
while (in.available() == 0);
String msg=manageConnectedSocket(in);
responseClient(msg,out);
} catch (IOException e) {
e.printStackTrace();
sendMsg(e.getMessage());
}
finally {
try {
socket.close();
socket = null ;
} catch (IOException e) {
e.printStackTrace();
}finally {
start();
}
}
}
}).start();
}
|