|
續上篇 Android BLE ESP32的onCharacteristicChanged沒有回撥及getDescriptor null
如何在Android BLE 發送數據 ESP32?
如何在Android BLE 發送到 ESP32 超過20個字元的數據?
自己照著Android Bluetooth原始碼寫,因為要轉換Activity切換畫面
但一離開Activity馬上出現離線的LOG
這時就想起手機在打開藍牙連線的時候,不管換了多少APP都不會斷連
網路上GOOGLE Buletooth background Service找到了這篇
在BluetoothLeService.java Activity加入以下代碼
測試之後,順暢穩定執行
- public class BluetoothServices extends Service {
- private BluetoothAdapter mBluetoothAdapter;
- public static final String B_DEVICE = "MY DEVICE";
- public static final String B_UUID = "00001101-0000-1000-8000-00805f9b34fb"; //藍芽串口服務
- // 00000000-0000-1000-8000-00805f9b34fb
- public static final int STATE_NONE = 0;
- public static final int STATE_LISTEN = 1;
- public static final int STATE_CONNECTING = 2;
- public static final int STATE_CONNECTED = 3;
- private ConnectBtThread mConnectThread;
- private static ConnectedBtThread mConnectedThread;
- private static Handler mHandler = null;
- public static int mState = STATE_NONE;
- public static String deviceName;
- public static BluetoothDevice sDevice = null;
- public Vector<Byte> packData = new Vector<>(2048);
- //IBinder mIBinder = new LocalBinder();
- @Nullable
- @Override
- public IBinder onBind(Intent intent) {
- //mHandler = getApplication().getHandler();
- return mBinder;
- }
- public void toast(String mess){
- Toast.makeText(this,mess,Toast.LENGTH_SHORT).show();
- }
- private final IBinder mBinder = new LocalBinder();
- public class LocalBinder extends Binder {
- BluetoothServices getService() {
- // Return this instance of LocalService so clients can call public methods
- return BluetoothServices.this;
- }
- }
- @Override
- public int onStartCommand(Intent intent, int flags, int startId) {
- String deviceg = intent.getStringExtra("bluetooth_device");
- mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
- connectToDevice(deviceg);
- return START_STICKY;
- }
- private synchronized void connectToDevice(String macAddress){
- BluetoothDevice device = mBluetoothAdapter.getRemoteDevice(macAddress);
- if (mState == STATE_CONNECTING){
- if (mConnectThread != null){
- mConnectThread.cancel();
- mConnectThread = null;
- }
- }
- if (mConnectedThread != null){
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- mConnectThread = new ConnectBtThread(device);
- toast("connecting");
- mConnectThread.start();
- setState(STATE_CONNECTING);
- }
- private void setState(int state){
- mState = state;
- if (mHandler != null){
- // mHandler.obtainMessage();
- }
- }
- public synchronized void stop(){
- setState(STATE_NONE);
- if (mConnectThread != null){
- mConnectThread.cancel();
- mConnectThread = null;
- }
- if (mConnectedThread != null){
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- if (mBluetoothAdapter != null){
- mBluetoothAdapter.cancelDiscovery();
- }
- stopSelf();
- }
- public void sendData(String message){
- if (mConnectedThread!= null){
- mConnectedThread.write(message.getBytes());
- toast("sent data");
- }else {
- Toast.makeText(BluetoothServices.this,"Failed to send data",Toast.LENGTH_SHORT).show();
- }
- }
- @Override
- public boolean stopService(Intent name) {
- setState(STATE_NONE);
- if (mConnectThread != null){
- mConnectThread.cancel();
- mConnectThread = null;
- }
- if (mConnectedThread != null){
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- mBluetoothAdapter.cancelDiscovery();
- return super.stopService(name);
- }
- /*private synchronized void connected(BluetoothSocket mmSocket){
- if (mConnectThread != null){
- mConnectThread.cancel();
- mConnectThread = null;
- }
- if (mConnectedThread != null){
- mConnectedThread.cancel();
- mConnectedThread = null;
- }
- mConnectedThread = new ConnectedBtThread(mmSocket);
- mConnectedThread.start();
- setState(STATE_CONNECTED);
- }*/
- private class ConnectBtThread extends Thread{
- private final BluetoothSocket mSocket;
- private final BluetoothDevice mDevice;
- public ConnectBtThread(BluetoothDevice device){
- mDevice = device;
- BluetoothSocket socket = null;
- try {
- socket = device.createInsecureRfcommSocketToServiceRecord(UUID.fromString(B_UUID));
- } catch (IOException e) {
- e.printStackTrace();
- }
- mSocket = socket;
- }
- @Override
- public void run() {
- mBluetoothAdapter.cancelDiscovery();
- try {
- mSocket.connect();
- Log.d("service","connect thread run method (connected)");
- SharedPreferences pre = getSharedPreferences("BT_NAME",0);
- pre.edit().putString("bluetooth_connected",mDevice.getName()).apply();
- } catch (IOException e) {
- try {
- mSocket.close();
- Log.d("service","connect thread run method ( close function)");
- } catch (IOException e1) {
- e1.printStackTrace();
- }
- e.printStackTrace();
- }
- //connected(mSocket);
- mConnectedThread = new ConnectedBtThread(mSocket);
- mConnectedThread.start();
- }
- public void cancel(){
- try {
- mSocket.close();
- Log.d("service","connect thread cancel method");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- private class ConnectedBtThread extends Thread{
- private final BluetoothSocket cSocket;
- private final InputStream inS;
- private final OutputStream outS;
- private byte[] buffer;
- public ConnectedBtThread(BluetoothSocket socket){
- cSocket = socket;
- InputStream tmpIn = null;
- OutputStream tmpOut = null;
- try {
- tmpIn = socket.getInputStream();
- } catch (IOException e) {
- e.printStackTrace();
- }
- try {
- tmpOut = socket.getOutputStream();
- } catch (IOException e) {
- e.printStackTrace();
- }
- inS = tmpIn;
- outS = tmpOut;
- }
- @Override
- public void run() {
- buffer = new byte[1024];
- int mByte;
- try {
- mByte= inS.read(buffer);
- } catch (IOException e) {
- e.printStackTrace();
- }
- Log.d("service","connected thread run method");
- }
- public void write(byte[] buff){
- try {
- outS.write(buff);
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- private void cancel(){
- try {
- cSocket.close();
- Log.d("service","connected thread cancel method");
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- @Override
- public void onDestroy() {
- this.stop();
- super.onDestroy();
- }
複製代碼 關於service與actvity綁定的知識,但是在調試過程中無意中出現了上述的bug,後來經分析,當清理後台activity時就會報這個錯誤
重寫的onDestroy的回調方法中加入了對服務的解綁操作即unbindService就成功解決了
在MainActivity.jaca加入以下代碼
- protected void onDestroy() {
- // TODO 自动生成的方法存根
- super.onDestroy();
- unbindService(mServiceConnection);
- }
複製代碼 其實這個錯誤有點類似於dialog中如果activity已經finish()掉但dialog還沒dissmiss()時也會報類似的溢出錯誤,希望大家引以為戒,多多注意自己的代碼習慣,做好防護的措施。
來源
http://www.netyea.com
參考文章
https://blog.csdn.net/as02446418/article/details/46790843
|
|