藍芽客戶端和伺服器的實現
需要許可權:
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
客戶端:
package com.pax.btclient;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.bluetooth.*;
import android.os.ConditionVariable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.UUID;
import java.util.Random;
public class MainActivity extends Activity {
private BluetoothAdapter adapter = null;
private BluetoothDevice remoteDevice = null;
private BluetoothSocket socket = null;
private ConditionVariable done = null;
private Activity activity = null;
private final static String TAG = "BTClient";
final UUID MyUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
BluetoothStateChangeReceiver stateChangeReceiver;
BluetoothDiscoveryReciver discoveryReciver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
adapter = BluetoothAdapter.getDefaultAdapter();
done = new ConditionVariable();
IntentFilter filter = new IntentFilter();
filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
stateChangeReceiver = new BluetoothStateChangeReceiver();
registerReceiver(stateChangeReceiver, filter);
IntentFilter discoveryFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
discoveryFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED);
discoveryFilter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
discoveryReciver = new BluetoothDiscoveryReciver();
registerReceiver(discoveryReciver, discoveryFilter);
Thread thread = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
BluetoothTest();
}
};
thread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(stateChangeReceiver);
unregisterReceiver(discoveryReciver);
}
void BluetoothTest(){
Log.i(TAG,"start BT test\n");
int i = 0;
int j = 0;
if(adapter != null){
//開啟藍芽
Log.i(TAG,"open BT...\n");
if(!adapter.isEnabled()){
adapter.enable();
done.block();
done.close();
}
//搜尋藍芽
Log.i(TAG,"discovery BT...\n");
adapter.startDiscovery();
done.block();
done.close();
if(remoteDevice != null){
byte[] sendData = new byte[1024];
byte[] receiveData = new byte[1024];
Random rand = new Random();
for(j = 0;j < sendData.length; j++)
{
sendData[j] = (byte)Math.abs(rand.nextInt());
}
BluetoothSocket socket = null;
InputStream inputStream = null;
OutputStream outputStream = null;
int recvLen = 0;
try {
Log.i(TAG,"create socket...\n");
socket = remoteDevice.createRfcommSocketToServiceRecord(MyUUID);
if(socket != null)
{
socket.connect();
outputStream = socket.getOutputStream();
inputStream = socket.getInputStream();
if(inputStream != null && outputStream != null){
//傳送資料
Log.i(TAG,"send data...\n");
outputStream.write(sendData);
outputStream.flush();
//接收資料
Log.i(TAG,"recive data...\n");
while(true){
if((inputStream.available() > 0) && (recvLen < 1024)){
int len = inputStream.read(receiveData, recvLen, 1024-recvLen);
recvLen += len;
if(recvLen >= 1024){
break;
}
}
}
if(recvLen == 1024){
for(i = 0; i < 1024; i++){
if(receiveData[i]!= sendData[i]){
Log.e(TAG,"cmp error\n");
break;
}
}
}
inputStream.close();
inputStream = null;
outputStream.close();
outputStream = null;
}
socket.close();
socket = null;
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//解除繫結
Log.i(TAG,"remove bond...\n");
Method removeBondMethod;
try {
removeBondMethod = BluetoothDevice.class.getMethod("removeBond");
Boolean result = (Boolean) removeBondMethod.invoke(remoteDevice);
remoteDevice = null;
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//關閉藍芽
Log.i(TAG,"close BT...\n");
adapter.disable();
}
}
class BluetoothStateChangeReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
if(arg1.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
int state = arg1.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
if(state == BluetoothAdapter.STATE_ON || state == BluetoothAdapter.STATE_OFF)
{
done.open();
}
}
}
}
class BluetoothDiscoveryReciver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Log.i(TAG,arg1.getAction());
if(arg1.getAction().equals(BluetoothDevice.ACTION_FOUND)){
BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(("00:17:6F:68:B0:91").equals(device.getAddress()))
{
if(adapter.isDiscovering()){
adapter.cancelDiscovery();
}
int state = device.getBondState();
if(state == BluetoothDevice.BOND_NONE){
Log.i(TAG,"not bonded,create bond\n");
try {
//傳送配對請求
Method createBound = BluetoothDevice.class.getMethod("createBond");
createBound.invoke(device);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}else if(state == BluetoothDevice.BOND_BONDED){
remoteDevice = device;
done.open();
}
}
}else if(arg1.getAction().equals(BluetoothDevice.ACTION_BOND_STATE_CHANGED)){
BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
remoteDevice = device;
done.open();
Log.i(TAG,"bonded\n");
}else if(arg1.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST)){
//自動確認配對
BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
if(("00:17:6F:68:B0:91").equals(device.getAddress())){
Log.i(TAG,"PairingConfirmation\n");
try{
Method setPairingConfirmationMethod = BluetoothDevice.class.getMethod("setPairingConfirmation",new Class[]{boolean.class});
setPairingConfirmationMethod.invoke(device,true);
}catch(Exception e)
{
e.printStackTrace();
}
}
}
}
}
}
伺服器:
package com.pax.btserver;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.bluetooth.*;
import android.os.ConditionVariable;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.util.Log;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.*;
import java.util.UUID;
import com.pax.btserver.R;
public class MainActivity extends Activity {
private final static String TAG = "BTServer";
private BluetoothAdapter adpter = null;
private ConditionVariable done = null;
private BluetoothReceiver bluetoothReceiver;
static final UUID MyUUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
done = new ConditionVariable();
adpter = BluetoothAdapter.getDefaultAdapter();
bluetoothReceiver = new BluetoothReceiver();
IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
filter.addAction(BluetoothDevice.ACTION_PAIRING_REQUEST);
registerReceiver(bluetoothReceiver, filter);
Thread thread = new Thread(){
@Override
public void run() {
// TODO Auto-generated method stub
super.run();
bluetoothServer();
}
};
thread.start();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
unregisterReceiver(bluetoothReceiver);
}
void bluetoothServer(){
Log.i(TAG,"start BT server\n");
BluetoothServerSocket serverSocket = null;
BluetoothSocket socket = null;
InputStream in = null;
OutputStream out = null;
int len = 0;
int recvLen = 0;
byte[] recvdata = new byte[1024];
if(adpter != null){
//開啟藍芽
Log.i(TAG,"open BT\n");
if(!adpter.isEnabled()){
adpter.enable();
done.block();
done.close();
}
try {
Log.i(TAG,"create serverSocket\n");
serverSocket = adpter.listenUsingRfcommWithServiceRecord("local1", MyUUID);
while(serverSocket != null){
if(adpter.isDiscovering()){
adpter.cancelDiscovery();
}
//阻塞直到客戶端連線上伺服器
socket = serverSocket.accept();
in = socket.getInputStream();
out= socket.getOutputStream();
if(in != null && out != null){
try{
while(true){
if(in.available() > 0){
len = in.read(recvdata);
Log.i(TAG,new String(recvdata));
if(len > 0){
out.write(recvdata);
out.flush();
len = 0;
}
}else{
break;
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
in.close();
in = null;
out.close();
out = null;
socket.close();
socket = null;
}
}
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if(serverSocket != null){
try {
serverSocket.close();
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
serverSocket = null;
}
}
}
}
class BluetoothReceiver extends BroadcastReceiver{
@Override
public void onReceive(Context arg0, Intent arg1) {
// TODO Auto-generated method stub
Log.i(TAG,arg1.getAction());
if(arg1.getAction().equals(BluetoothAdapter.ACTION_STATE_CHANGED)){
int state = arg1.getIntExtra(BluetoothAdapter.EXTRA_STATE, 0);
if(state == BluetoothAdapter.STATE_ON){
done.open();
}
}else if(arg1.getAction().equals(BluetoothDevice.ACTION_PAIRING_REQUEST)){
Log.i(TAG,"request pairing\n");
//有配對請求,自動確定配對
BluetoothDevice device = arg1.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
int mType = arg1.getIntExtra(BluetoothDevice.EXTRA_PAIRING_VARIANT, BluetoothDevice.ERROR);
if(mType == BluetoothDevice.PAIRING_VARIANT_PASSKEY_CONFIRMATION){
try {
Method setParingConfirm = BluetoothDevice.class.getMethod("setPairingConfirmation", new Class[]{boolean.class});
setParingConfirm.invoke(device,true);
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}
通過這listenUsingInsecureRfcommWithServiceRecord和createInsecureRfcommSocketToServiceRecord兩個API,可以不配對藍芽裝置就進行通訊
相關文章
- Redis 6.0 客戶端快取的伺服器端實現Redis客戶端快取伺服器
- iOS藍芽開發 Bluetooth藍芽CoreBluetooth 藍芽中心裝置的實現 藍芽外設的實現 有DemoiOS藍芽
- 客戶端骨架屏實現客戶端
- 002 Rust 網路程式設計,實現 UDP 伺服器和客戶端Rust程式設計UDP伺服器客戶端
- 實現伺服器和客戶端資料互動,Java Socket有妙招伺服器客戶端Java
- Redis的Pub/Sub客戶端實現Redis客戶端
- 網頁SSH客戶端的實現網頁客戶端
- 使用Netty實現HTTP2伺服器/客戶端的原始碼和教程 - BaeldungNettyHTTP伺服器客戶端原始碼
- MQTT伺服器搭建服務端和客戶端MQQT伺服器服務端客戶端
- HTML轉PDF的純客戶端和純服務端實現方案HTML客戶端服務端
- 在 WPF 客戶端實現 AOP 和介面快取客戶端快取
- jQuery實現客戶端CheckAll功能jQuery客戶端
- Go 實現簡易的 Redis 客戶端GoRedis客戶端
- Linux下簡單的ACE socket客戶端和伺服器端Linux客戶端伺服器
- Redis原始碼剖析——客戶端和伺服器Redis原始碼客戶端伺服器
- UE 客戶端和伺服器上的時間同步客戶端伺服器
- 實現客戶端與服務端的HTTP通訊客戶端服務端HTTP
- 伺服器獲取真實客戶端 IP伺服器客戶端
- golang實現tcp客戶端服務端程式GolangTCP客戶端服務端
- Golang 實現 Redis(6): 實現 pipeline 模式的 redis 客戶端GolangRedis模式客戶端
- Golang 實現客戶端與伺服器端UDP協議連線通訊Golang客戶端伺服器UDP協議
- 使用 Golang 實現 appium/WebDriverAgent 的客戶端庫GolangAPPWeb客戶端
- RetrofitJs – TypeScript實現的宣告式HTTP客戶端JSTypeScriptHTTP客戶端
- Istio 中實現客戶端源 IP 的保持客戶端
- Jmeter的客戶端實現與Keep-AliveJMeter客戶端Keep-Alive
- TCP實現公網伺服器和內網客戶端一對多訪問(C語言實現)TCP伺服器內網客戶端C語言
- Web 應用客戶端渲染和伺服器端渲染的比較Web客戶端伺服器
- React 伺服器端渲染和客戶端渲染效果對比React伺服器客戶端
- Java UDP伺服器和客戶端原始碼 -javarevisitedJavaUDP伺服器客戶端原始碼
- 利用tirpc庫實現簡單的客戶端和服務端RPC客戶端服務端
- Java的oauth2.0 服務端與客戶端的實現JavaOAuth服務端客戶端
- Easyvision中的伺服器與客戶端伺服器客戶端
- IM撤回訊息-iOS客戶端實現iOS客戶端
- 03. 實現客戶端應用程式客戶端
- FTP客戶端c程式碼功能實現FTP客戶端C程式
- JAVA通訊(二)——實現客戶機和伺服器通訊Java伺服器
- 關於 WebSocket 和 HTTP 區別的思考以及一個最簡單的 WebSocket 的客戶端和伺服器實現WebHTTP客戶端伺服器
- 001 Rust 網路程式設計,實現 TCP 服務端和客戶端程式Rust程式設計TCP服務端客戶端
- python 實現 TCP、UDP 客戶端最簡流程PythonTCPUDP客戶端