Android RFCOMM - подключение одного планшета блокирует подключение других планшетов к нему - PullRequest
0 голосов
/ 05 февраля 2020

У меня есть следующий код для подключения к устройству Bluetooth SPP:

public class ConnectTask extends AsyncTask<Void, Void, Void> {

private final WeakReference<Context> weakContext;
BluetoothDevice mdevice;
BluetoothSocket mSocket;
ProgressDialog pd;

public ConnectTask(Context context) {
    weakContext = new WeakReference<Context>(context);
}

@Override
protected void onPreExecute() {
    final Context context = weakContext.get();
    if (context != null) {
        super.onPreExecute();
        if (pd != null) {
            pd = null;
        }
        pd = new ProgressDialog(context);
        pd.setTitle("Connecting...");
        pd.setCancelable(false);
        if (!pd.isShowing()) {
            pd.show();
        }
    }
}

@Override
protected Void doInBackground(Void... params) {
    try {
        BluetoothConnectionService.btAdapter.cancelDiscovery();
            Thread.sleep(1000);
            mdevice = BluetoothConnectionService.getDevice();

            UUID uuid = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

            mSocket = mdevice.createInsecureRfcommSocketToServiceRecord(uuid);
            BluetoothConnectionService.setSocket(mSocket);
            BluetoothConnectionService.getSocket().connect();


            BluetoothConnectionService.setOutStream(BluetoothConnectionService.getSocket().getOutputStream());
        BluetoothConnectionService.setInStream(BluetoothConnectionService.getSocket().getInputStream());
            BluetoothConnectionService.sendMessage(mSocket, "S");
            Thread.sleep(1000);
            Log.i("ConnectTask", "Connected");
    } catch (IOException e) {
        e.printStackTrace();
        try {
            Log.i("ConnectTask", "trying fallback...");
            mSocket = (BluetoothSocket) mSocket.getClass().getMethod("createInsecureRfcommSocket", new Class[]{int.class}).invoke(mdevice, 1);
            BluetoothConnectionService.setSocket(mSocket);
            BluetoothConnectionService.getSocket().connect();
              BluetoothConnectionService.setOutStream(BluetoothConnectionService.getSocket().getOutputStream());
            BluetoothConnectionService.setInStream(BluetoothConnectionService.getSocket().getInputStream());

            BluetoothConnectionService.sendMessage(mSocket, "S");

            Thread.sleep(1000);
            Log.i("ConnectTask", "Connected");
        } catch (Exception e2) {
            Log.e("Error", "fCouldn't establish Bluetooth connection!");
            BluetoothConnectionService.closeSocket();
        }
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    return null;
}

@Override
protected void onPostExecute(Void result) {
    final Context context = weakContext.get();
    if (context != null) {
        super.onPostExecute(result);
        try {
            if (pd != null) {
                if (pd.isShowing()) {
                    if (context instanceof Configuration) {
                        onCompleteConfiguration((Configuration) context);
                    } else if (context instanceof CollectingDetail) {
                        onCompleteCollectingDetail((CollectingDetail) context);
                    }
                    pd.dismiss();
                }
            }
        } catch (final IllegalArgumentException are) {
            Log.e("Error", "Illegal Argument Exception!");
        } finally {
            pd = null;
        }
    }
}

Для отключения у меня есть следующий код:

public class BluetoothKillService extends Service {
    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_NOT_STICKY;
    }

    @Override
    public void onDestroy() {

    }

    @Override
    public void onTaskRemoved(Intent rootIntent) {
        if (BluetoothConnectionService.getSocket() != null) {
            BluetoothConnectionService.sendMessage(BluetoothConnectionService.socket, "D");
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            BluetoothConnectionService.closeSocket();
            BluetoothConnectionService.btAdapter.disable();
            BluetoothConnectionService.btAdapter.enable();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Вот BluetoothConnectionService:

public class BluetoothConnectionService {
    static BluetoothAdapter btAdapter;
    static ArrayList<BluetoothDevice> pairedDevices;
    static BluetoothDevice selectedDevice;

    static BluetoothSocket socket;

    static InputStream inputStream;
    static OutputStream outputStream;

    public static boolean isBLuetoothEnable() {
        btAdapter = BluetoothAdapter.getDefaultAdapter();
        if (btAdapter == null) {
            return false;
        } else {
            if (!btAdapter.isEnabled()) {
                // Bluetooth is not enable :)
                return false;
            } else {
                return true;
            }
        }
    }

    public static ArrayList<BluetoothDevice> getPairedDevices() {
        btAdapter = BluetoothAdapter.getDefaultAdapter();
        Set<BluetoothDevice> devices = btAdapter.getBondedDevices();
        if (devices.size() > 0) {
            pairedDevices = new ArrayList<BluetoothDevice>();
            for (BluetoothDevice device : devices) {
                pairedDevices.add(device);
            }
        }
        return pairedDevices;
    }

    static void sendMessage(BluetoothSocket socket, String msg) {
        OutputStream outStream;

        if (socket != null) {
            try {
                outStream = socket.getOutputStream();
                setOutStream(outStream);

                outStream.write(msg.getBytes());
            } catch (IOException e) {
                Log.d("BLUETOOTH_COMMS", e.getMessage());

            }
        }
    }

    public static void setDevice(BluetoothDevice device) {
        selectedDevice = device;
    }

    public static BluetoothDevice getDevice() {
        return selectedDevice;
    }

    public static void setSocket(BluetoothSocket msocket) {
        socket = msocket;
    }

    public static void closeSocket() {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            inputStream = null;
        }

        if (outputStream != null) {
            try {
                outputStream.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            outputStream = null;
        }

        if (socket != null) {
            try {
                socket.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
            socket = null;
        }
    }

    public static BluetoothSocket getSocket() {
        return socket;
    }

    public static void setInStream(InputStream inStream) {
        inputStream = inStream;
    }

    public static void setOutStream(OutputStream outStream) {
        outputStream = outStream;
    }
}

По какой-то причине при подключении к устройству Bluetooth с одним планшетом и закрытии приложения второй планшет никогда не сможет подключиться, если я не отключу его вручную. Похоже, что нигде в информации о переполнении стека и в Интернете нет информации об этой проблеме, и есть ли способ ее преодолеть?

Кстати, мои планшеты являются планшетами Dragon Touch V10.

РЕДАКТИРОВАТЬ : Устройство Bluetooth основано на RN4677.

...