Android- 蓝牙:蓝牙服务行为异常
Android- Bluetooth: Bluetooth Service behaving unexpectedly
我正在编写一个可以与 arduino 交互的 android 应用程序。我的应用程序有 2 个按钮 1. 连接 2. 断开连接,用于启动和停止蓝牙服务。我在 arduino 上有一个测试草图,当收到“1”时会发送“404”(只是为了测试!)回到我的phone。
这是我的蓝牙服务class
public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private ServiceHandler mSHandler;
public BluetoothService(){}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
}
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("ServiceStartArguments", android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Looper mSLoop = thread.getLooper();
mSHandler = new ServiceHandler(mSLoop);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = mSHandler.obtainMessage();
msg.arg1 = startId;
mSHandler.sendMessage(msg);
bluetoothManager=new BluetoothManager();
bluetoothManager.writeData("1", getApplicationContext()); //sending "1" to arduino
String str= bluetoothManager.readData(getApplicationContext()); //reading "404" from arduino
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy(){
bluetoothManager.turnBluetoothOff();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
现在这是我的蓝牙管理器 class:
public class BluetoothManager {
private BluetoothAdapter bluetoothAdapter;
private BluetoothDevice bluetoothDevice;
private BluetoothSocket bluetoothSocket;
private ConnectedThread connectedThread;
private byte[] buffer;
public BluetoothManager(){
buffer=new byte[256];
bluetoothSocket=null;
bluetoothAdapter=null;
bluetoothDevice=null;
connectedThread=null;
getBluetoothAdapter();
if(!isBluetoothAvailable()){
turnBluetoothOn();
}
scanToConnect();
}
public void turnBluetoothOff(){
try {
bluetoothSocket.close();
bluetoothSocket=null;
bluetoothAdapter.cancelDiscovery();
bluetoothAdapter.disable();
bluetoothAdapter=null;
bluetoothDevice=null;
}catch(Exception e){
e.printStackTrace();
}
}
private boolean isBluetoothAvailable(){
return bluetoothAdapter.isEnabled();
}
private void turnBluetoothOn(){
bluetoothAdapter.enable();
}
public String readData(Context context){
String outputString=null;
if(isBluetoothAvailable()) {
outputString = connectedThread.read(buffer);
}else{
Toast.makeText(context, "Error: Not Connected", Toast.LENGTH_LONG).show();
}
return outputString;
}
public void writeData(String string, Context context){
if(isBluetoothAvailable()) {
connectedThread.write(string.getBytes());
}else{
Toast.makeText(context, "Error: Not Connected", Toast.LENGTH_LONG).show();
}
}
private void getBluetoothAdapter(){
try{
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
}catch (Exception e){
e.printStackTrace();
}
}
private void scanToConnect(){
Set<BluetoothDevice> pairedDevices=bluetoothAdapter.getBondedDevices();
if(pairedDevices.size()>0){
try {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("HC-05")) {
bluetoothDevice = device;
new connectBt(bluetoothDevice);
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
private class connectBt extends Thread {
public connectBt(BluetoothDevice device) {
BluetoothSocket tmp = null;
bluetoothDevice = device;
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = tmp;
run();
}
public void run() {
bluetoothAdapter.cancelDiscovery();
try {
bluetoothSocket.connect();
connectedThread = new ConnectedThread(bluetoothSocket);
} catch (IOException connectException) {
closeSocket();
}
}
private void closeSocket() {
try {
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectedThread extends Thread{
private InputStream mInput=null;
private OutputStream mOutput=null;
private String strInput;
public ConnectedThread(BluetoothSocket socket){
bluetoothSocket=socket;
InputStream tmpIn=null;
OutputStream tmpOut=null;
try{
tmpIn=socket.getInputStream();
tmpOut=socket.getOutputStream();
}catch(IOException e){
e.printStackTrace();
closeSocket();
}
mInput=tmpIn;
mOutput=tmpOut;
}
public void write(byte[] bytes){
try{
mOutput.write(bytes);
}catch(IOException e){
e.printStackTrace();
}
}
public String read(byte[] bytes){
try {
mInput.read(bytes);
strInput = new String(bytes);
}catch(Exception e){
e.printStackTrace();
}
return strInput;
}
public void closeSocket(){
try{
bluetoothSocket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
我的问题是我必须按两次连接按钮才能连接到arduino,第一次按下将启用蓝牙,第二次按下将连接到arduino,然后发送和接收数据。但这不是我想要的,启用蓝牙和连接应该只需要按一下就可以了。
那么为什么会这样呢?
N.B:我是 java 和 android 的新手。
您可以使用 Intent 过滤器收听 ACTION_ACL_CONNECTED、ACTION_ACL_DISCONNECT_REQUESTED 和 ACTION_ACL_DISCONNECTED 广播:
更多请查看这里;
How to programmatically tell if a Bluetooth device is connected? (Android 2.2)
启用蓝牙后需要一段时间才能获取配对设备列表。但在这种情况下,您会在打开蓝牙后立即读取配对设备。可能是你延迟了连接部分。
使用处理程序方法延迟执行。
我正在编写一个可以与 arduino 交互的 android 应用程序。我的应用程序有 2 个按钮 1. 连接 2. 断开连接,用于启动和停止蓝牙服务。我在 arduino 上有一个测试草图,当收到“1”时会发送“404”(只是为了测试!)回到我的phone。
这是我的蓝牙服务class
public class BluetoothService extends Service {
private BluetoothManager bluetoothManager;
private ServiceHandler mSHandler;
public BluetoothService(){}
private final class ServiceHandler extends Handler {
public ServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
}
}
@Override
public void onCreate() {
super.onCreate();
HandlerThread thread = new HandlerThread("ServiceStartArguments", android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
Looper mSLoop = thread.getLooper();
mSHandler = new ServiceHandler(mSLoop);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Message msg = mSHandler.obtainMessage();
msg.arg1 = startId;
mSHandler.sendMessage(msg);
bluetoothManager=new BluetoothManager();
bluetoothManager.writeData("1", getApplicationContext()); //sending "1" to arduino
String str= bluetoothManager.readData(getApplicationContext()); //reading "404" from arduino
Toast.makeText(getApplicationContext(), str, Toast.LENGTH_LONG).show();
return START_STICKY;
}
@Override
public void onDestroy(){
bluetoothManager.turnBluetoothOff();
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
现在这是我的蓝牙管理器 class:
public class BluetoothManager {
private BluetoothAdapter bluetoothAdapter;
private BluetoothDevice bluetoothDevice;
private BluetoothSocket bluetoothSocket;
private ConnectedThread connectedThread;
private byte[] buffer;
public BluetoothManager(){
buffer=new byte[256];
bluetoothSocket=null;
bluetoothAdapter=null;
bluetoothDevice=null;
connectedThread=null;
getBluetoothAdapter();
if(!isBluetoothAvailable()){
turnBluetoothOn();
}
scanToConnect();
}
public void turnBluetoothOff(){
try {
bluetoothSocket.close();
bluetoothSocket=null;
bluetoothAdapter.cancelDiscovery();
bluetoothAdapter.disable();
bluetoothAdapter=null;
bluetoothDevice=null;
}catch(Exception e){
e.printStackTrace();
}
}
private boolean isBluetoothAvailable(){
return bluetoothAdapter.isEnabled();
}
private void turnBluetoothOn(){
bluetoothAdapter.enable();
}
public String readData(Context context){
String outputString=null;
if(isBluetoothAvailable()) {
outputString = connectedThread.read(buffer);
}else{
Toast.makeText(context, "Error: Not Connected", Toast.LENGTH_LONG).show();
}
return outputString;
}
public void writeData(String string, Context context){
if(isBluetoothAvailable()) {
connectedThread.write(string.getBytes());
}else{
Toast.makeText(context, "Error: Not Connected", Toast.LENGTH_LONG).show();
}
}
private void getBluetoothAdapter(){
try{
bluetoothAdapter=BluetoothAdapter.getDefaultAdapter();
}catch (Exception e){
e.printStackTrace();
}
}
private void scanToConnect(){
Set<BluetoothDevice> pairedDevices=bluetoothAdapter.getBondedDevices();
if(pairedDevices.size()>0){
try {
for (BluetoothDevice device : pairedDevices) {
if (device.getName().equals("HC-05")) {
bluetoothDevice = device;
new connectBt(bluetoothDevice);
break;
}
}
}catch(Exception e){
e.printStackTrace();
}
}
}
private class connectBt extends Thread {
public connectBt(BluetoothDevice device) {
BluetoothSocket tmp = null;
bluetoothDevice = device;
UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805f9b34fb");
try {
tmp = device.createRfcommSocketToServiceRecord(uuid);
} catch (IOException e) {
e.printStackTrace();
}
bluetoothSocket = tmp;
run();
}
public void run() {
bluetoothAdapter.cancelDiscovery();
try {
bluetoothSocket.connect();
connectedThread = new ConnectedThread(bluetoothSocket);
} catch (IOException connectException) {
closeSocket();
}
}
private void closeSocket() {
try {
bluetoothSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
private class ConnectedThread extends Thread{
private InputStream mInput=null;
private OutputStream mOutput=null;
private String strInput;
public ConnectedThread(BluetoothSocket socket){
bluetoothSocket=socket;
InputStream tmpIn=null;
OutputStream tmpOut=null;
try{
tmpIn=socket.getInputStream();
tmpOut=socket.getOutputStream();
}catch(IOException e){
e.printStackTrace();
closeSocket();
}
mInput=tmpIn;
mOutput=tmpOut;
}
public void write(byte[] bytes){
try{
mOutput.write(bytes);
}catch(IOException e){
e.printStackTrace();
}
}
public String read(byte[] bytes){
try {
mInput.read(bytes);
strInput = new String(bytes);
}catch(Exception e){
e.printStackTrace();
}
return strInput;
}
public void closeSocket(){
try{
bluetoothSocket.close();
}catch(IOException e){
e.printStackTrace();
}
}
}
}
我的问题是我必须按两次连接按钮才能连接到arduino,第一次按下将启用蓝牙,第二次按下将连接到arduino,然后发送和接收数据。但这不是我想要的,启用蓝牙和连接应该只需要按一下就可以了。 那么为什么会这样呢?
N.B:我是 java 和 android 的新手。
您可以使用 Intent 过滤器收听 ACTION_ACL_CONNECTED、ACTION_ACL_DISCONNECT_REQUESTED 和 ACTION_ACL_DISCONNECTED 广播:
更多请查看这里;
How to programmatically tell if a Bluetooth device is connected? (Android 2.2)
启用蓝牙后需要一段时间才能获取配对设备列表。但在这种情况下,您会在打开蓝牙后立即读取配对设备。可能是你延迟了连接部分。
使用处理程序方法延迟执行。