Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keep bluetooth service running for all fragments

I'm stuck and can't find a way to restart or reconnect the Bluetooth service in my app. The app has 3 fragments, tabs managed by FragmentPagerAdapter. In the first fragment you can discover, associate and communicate with the BT device. In the second and third card it is necessary to interact with the device, it is not possible to get the connection or keep the service connected.

Here it goes the first fragment:

public class Conexiones extends Fragment implements ServiceConnection, SerialListener {
    public BluetoothAdapter BTAdapter;
    private ListView listView; // detectados
    private ArrayList<String> mDeviceList;
    public Button conectar, actualizar;
    private ArrayAdapter m_DiscoveredPeersAdapter;
    BluetoothDevice bdDevice;
    BluetoothClass dbClass;
    ArrayList<BluetoothDevice> listaBTDevices = null;
    View view;

    public SerialSocket socket;
    public SerialService service;

    public Conexiones(){

    }

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        view = inflater.inflate(R.layout.fragment_conexiones, container, false );
        BTAdapter = BluetoothAdapter.getDefaultAdapter();
        listView = (ListView) this.view.findViewById(R.id.listView);
        mDeviceList = new ArrayList<>();
        m_DiscoveredPeersAdapter = new ArrayAdapter(getActivity(), android.R.layout.simple_list_item_1, mDeviceList);
        listView.setAdapter(m_DiscoveredPeersAdapter);
        listItemClicked = new ListItemClicked();
        clicked = new ButtonClicked();

        checkBTPermissions();
        listaBTDevices = new ArrayList<BluetoothDevice>();
        m_DiscoveredPeersAdapter.notifyDataSetChanged();
        if (BTAdapter == null || !BTAdapter.isEnabled()) {
            Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(turnOn, 1);
        }
        int MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION = 1;
        ActivityCompat.requestPermissions(activity,
                new String[]{Manifest.permission.ACCESS_COARSE_LOCATION},
                MY_PERMISSIONS_REQUEST_ACCESS_COARSE_LOCATION);

        if (BTAdapter.isEnabled()){
            BTAdapter.startDiscovery();
            Log.e("mio", "dp de star discovery");
        }
        else{
            Intent turnOn = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            startActivityForResult(turnOn, 1);
            Log.e("mio", "no weisa");
        }

        IntentFilter filter = new IntentFilter();
        filter.addAction(BluetoothDevice.ACTION_FOUND);
        filter.addAction(BluetoothAdapter.ACTION_STATE_CHANGED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
        filter.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
        activity.registerReceiver(mReceiver, filter);

        return view;
    }

    @Override
    public void onStart() {
        Log.e("mio", "dentro de on start ");
        dataInicialRecibida=false;
        super.onStart();
        //getPairedDevices();
        this.conectar.setOnClickListener(clicked);
        this.actualizar.setOnClickListener(clicked);
        listView.setOnItemClickListener(listItemClicked);
        MainActivity activity = (MainActivity) getActivity();
        texto.setText("sistema listo");

    }

    private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            Log.i("BT", "recibe");
            if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {
                //discovery starts, we can show progress dialog or perform other tasks
                Log.i("BT", "empezamos BT");
            }
            if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {
                //discovery starts, we can show progress dialog or perform other tasks
                Log.i("BT", "terminiamos BT");
                try {
                    Method getUuidsMethod = BluetoothAdapter.class.getDeclaredMethod("getUuids", null);
                    ParcelUuid[] uuids = (ParcelUuid[]) getUuidsMethod.invoke(BTAdapter, null);

                    if(uuids != null) {
                        for (ParcelUuid uuid : uuids) {
                            Log.d(TAG, "UUID: " + uuid.getUuid().toString());
                            miu=uuid.getUuid().toString();
                        }
                    }else{
                        Log.d(TAG, "Uuids not found, be sure to enable Bluetooth!");
                    }

                }catch (NoSuchMethodException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                }

            }
            if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                //discovery starts, we can show progress dialog or perform other tasks
                Log.i("BT", "state changed BT");
            }
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent
                        .getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
            //    mDeviceList.add(device.getName() + "\n" + device.getAddress());
           //     DeviceItem newDevice = new DeviceItem(device.getName(), device.getAddress(), "false");
                Log.i("BTN", device.getName() + "\n" + device.getAddress());
          //      mDeviceList.notifyDataSetChanged();
                if(listaBTDevices.size()<1) // this checks if the size of bluetooth device is 0,then add the
                {
                    Log.i("mio", "lista devices menor a 1");// device to the arraylist.
                    m_DiscoveredPeersAdapter.add(device.getName()+"\n"+device.getAddress());
                    listaBTDevices.add(device);
                    m_DiscoveredPeersAdapter.notifyDataSetChanged();
                }
                else
                {
                    Log.i("mio", "lista devices maor o igual a 1");
                    boolean flag = true;    // flag to indicate that particular device is already in the arlist or not
                    for(int i = 0; i<listaBTDevices.size();i++)
                    {
                        if(device.getAddress().equals(listaBTDevices.get(i).getAddress()))
                        {
                            flag = false;
                        }
                    }
                    if(flag == true)
                    {
                        m_DiscoveredPeersAdapter.add(device.getName()+"\n"+device.getAddress());
                        listaBTDevices.add(device);
                        m_DiscoveredPeersAdapter.notifyDataSetChanged();
                    }
                }
            }
            listView.setAdapter(new ArrayAdapter<String>(context,
                        android.R.layout.simple_list_item_1, mDeviceList));
            }

    };

    @RequiresApi(api = Build.VERSION_CODES.M)
    private void checkBTPermissions() {
        if(Build.VERSION.SDK_INT > Build.VERSION_CODES.LOLLIPOP){
            int permissionCheck =getActivity().checkSelfPermission("Manifest.permission.ACCESS_FINE_LOCATION");
            permissionCheck += getActivity().checkSelfPermission("Manifest.permission.ACCESS_COARSE_LOCATION");
            if (permissionCheck != 0) {

                this.requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1001); //Any number
            }
        }else{
            Log.d(TAG, "checkBTPermissions: No need to check permissions. SDK version < LOLLIPOP.");
        }
    }

    @Override
    public void onDestroy() {
        MainActivity activity = (MainActivity) getActivity();
        activity.unregisterReceiver(mReceiver);
        super.onDestroy();
        Log.e("mio", "on destroy ");
    }


    @Override
    public void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode == RESULT_OK){
            Log.d(TAG, "caso okookok.");
            BTAdapter.startDiscovery();
        }else{
            Log.d(TAG, "cas no ok.");
        }
    }

    @Override
    public void onStop() {
        super.onStop();
        Log.e("mio", "on stop");
        MainActivity activity = (MainActivity) getActivity();
        activity.unregisterReceiver(mReceiver);
    }

    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
        service = ((SerialService.SerialBinder) binder).getService();
        Log.e("mio", "on service conectado conexiones ");
        if(initialStart && isResumed()) {
            initialStart = false;
            getActivity().runOnUiThread(this::connect);

        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        service = null;
        texto.setText("desconectado BT");
        Log.e("mio", "desconectado BT conexiones");
    }

    @Override
    public void onSerialConnect() {
        texto.setText("conexion BT");
        Log.e("mio", "conectado BT conexiones");
    }

    @Override
    public void onSerialConnectError(Exception e) {
        texto.setText("error conexion BT");
        Log.e("mio", "onSerialConnectError");
    }

    @Override
    public void onSerialRead(byte[] data) {

        receive(data);
        texto.setText("leyendo BT");
        Log.e("mio", "leyendo BT  ");
    }

    private void receive(byte[] data) {
        receiveText+=new String(data);

        receiveText="";

    }


    @Override
    public void onSerialIoError(Exception e) {
        texto.setText("error conexion BT");
    }

    class ButtonClicked implements View.OnClickListener
    {
        @Override
        public void onClick(View view) {
            switch (view.getId()) {
                case R.id.button:
                    listaBTDevices.clear();
                    m_DiscoveredPeersAdapter.clear();
                    startSearching();
                    texto.setText("buscando dispositivos BT");
                    break;

                case R.id.button3:
                     break;
            }
        }
    }

    class ListItemClicked implements AdapterView.OnItemClickListener
    {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {

            bdDevice = listaBTDevices.get(position);
            //bdClass = arrayListBluetoothDevices.get(position);
            Log.i("Log", "The dvice : "+bdDevice.toString());

            connect();

        }
    }

    private boolean isNetworkAvailable() {
        ConnectivityManager connectivityManager = (ConnectivityManager) service.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
        return activeNetworkInfo != null && activeNetworkInfo.isConnected();
    }

    private void getPairedDevices() {
       // Set<BluetoothDevice> pairedDevice = BTAdapter.getBondedDevices();
     //   if(pairedDevice.size()>0)
        {
      //      for(BluetoothDevice device : pairedDevice)
            {
           //     arrayListpaired.add(device.getName()+"\n"+device.getAddress());
           //     arrayListPairedBluetoothDevices.add(device);
            }
        }
     //   adapter.notifyDataSetChanged();
    }

    public void send(String str) {
              try {
            SpannableStringBuilder spn = new SpannableStringBuilder(str+'\n');
            byte[] data = (str).getBytes();
            socket.write(data);
        } catch (Exception e) {
            onSerialIoError(e);
        }
    }

    @SuppressWarnings("deprecation")
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
      //  getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
    }


    private void connect() {

        try {

            BTAdapter = BluetoothAdapter.getDefaultAdapter();
            BluetoothDevice device = BTAdapter .getRemoteDevice(bdDevice.getAddress());
            String deviceName = device.getName() != null ? device.getName() : device.getAddress();
            socket = new SerialSocket();
            service.connect(this, "Connected to " + deviceName);
            socket.connect(getContext(), service, device);
            MainActivity activity = (MainActivity) getActivity();
            activity.setidEquipo(bdDevice.getAddress());
            // conexión ok, cambiar color letras boton

        } catch (Exception e) {
            //onSerialConnectError(e);
            Log.i("mio", "error del connect "+e);
            // sino hay conexión mantener boton con letras naranjas

        }

    }

    private void startSearching() {
        Log.i("Log", "in the start searching method");
        MainActivity activity = (MainActivity) getActivity();
        IntentFilter intentFilter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
        activity.registerReceiver(mReceiver, intentFilter);
        BTAdapter.startDiscovery();
    }
    private void onBluetooth() {
        if(!BTAdapter.isEnabled())
        {
            BTAdapter.enable();
            Log.i("Log", "Bluetooth is Enabled");
        }
    }
    private void offBluetooth() {
        if(BTAdapter.isEnabled())
        {
            BTAdapter.disable();
        }
    }


    }

The serial service:


public class SerialService extends Service implements SerialListener {

    class SerialBinder extends Binder {
        SerialService getService() { return SerialService.this; }
    }

    private enum QueueType {Connect, ConnectError, Read, IoError}

    private class QueueItem {
        QueueType type;
        byte[] data;
        Exception e;

        QueueItem(QueueType type, byte[] data, Exception e) { this.type=type; this.data=data; this.e=e; }
    }

    private final Handler mainLooper;
    private final IBinder binder;
    private final Queue<QueueItem> queue1, queue2;

    private SerialListener listener;
    private boolean connected;
    private String notificationMsg;


    public SerialService() {
        mainLooper = new Handler(Looper.getMainLooper());
        binder = new SerialBinder();
        queue1 = new LinkedList<>();
        queue2 = new LinkedList<>();
    }


    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return binder;
    }


    public void connect(SerialListener listener, String notificationMsg) {
        this.listener = listener;
        connected = true;
        this.notificationMsg = notificationMsg;
    }

    public void disconnect() {
        listener = null;
        connected = false;
        notificationMsg = null;
    }

    public void attach(SerialListener listener) {
        if(Looper.getMainLooper().getThread() != Thread.currentThread())
            throw new IllegalArgumentException("not in main thread");
        cancelNotification();
        // use synchronized() to prevent new items in queue2
        // new items will not be added to queue1 because mainLooper.post and attach() run in main thread
        if(connected) {
            synchronized (this) {
                this.listener = listener;
            }
        }
        for(QueueItem item : queue1) {
            switch(item.type) {
                case Connect:       listener.onSerialConnect      (); break;
                case ConnectError:  listener.onSerialConnectError (item.e); break;
                case Read:          listener.onSerialRead         (item.data); break;
                case IoError:       listener.onSerialIoError      (item.e); break;
            }
        }
        for(QueueItem item : queue2) {
            switch(item.type) {
                case Connect:       listener.onSerialConnect      (); break;
                case ConnectError:  listener.onSerialConnectError (item.e); break;
                case Read:          listener.onSerialRead         (item.data); break;
                case IoError:       listener.onSerialIoError      (item.e); break;
            }
        }
        queue1.clear();
        queue2.clear();
    }

    public void detach() {
        if(connected)
            createNotification();
        // items already in event queue (posted before detach() to mainLooper) will end up in queue1
        // items occurring later, will be moved directly to queue2
        // detach() and mainLooper.post run in the main thread, so all items are caught
        listener = null;
    }


    public void onSerialConnect() {
        Log.i("mio", "dentro on serial connect ");
        if(connected) {
            Log.i("mio", "dentro de connected ");
            synchronized (this) {
                if (listener != null) {
                    mainLooper.post(() -> {
                        if (listener != null) {
                            listener.onSerialConnect();
                        } else {
                            queue1.add(new QueueItem(QueueType.Connect, null, null));
                        }
                    });
                } else {
                    queue2.add(new QueueItem(QueueType.Connect, null, null));
                }
            }
        }
    }

    public void onSerialConnectError(Exception e) {
        if(connected) {
            synchronized (this) {
                if (listener != null) {
                    mainLooper.post(() -> {
                        if (listener != null) {
                            listener.onSerialConnectError(e);
                        } else {
                            queue1.add(new QueueItem(QueueType.ConnectError, null, e));
                            cancelNotification();
                            disconnect();
                        }
                    });
                } else {
                    queue2.add(new QueueItem(QueueType.ConnectError, null, e));
                    cancelNotification();
                    disconnect();
                }
            }
        }
    }

    public void onSerialRead(byte[] data) {
        if(connected) {
            synchronized (this) {
                if (listener != null) {
                    mainLooper.post(() -> {
                        if (listener != null) {
                            listener.onSerialRead(data);
                        } else {
                            queue1.add(new QueueItem(QueueType.Read, data, null));
                        }
                    });
                } else {
                    queue2.add(new QueueItem(QueueType.Read, data, null));
                }
            }
        }
    }

    public void onSerialIoError(Exception e) {
        if(connected) {
            synchronized (this) {
                if (listener != null) {
                    mainLooper.post(() -> {
                        if (listener != null) {
                            listener.onSerialIoError(e);
                        } else {
                            queue1.add(new QueueItem(QueueType.IoError, null, e));
                            cancelNotification();
                            disconnect();
                        }
                    });
                } else {
                    queue2.add(new QueueItem(QueueType.IoError, null, e));
                    cancelNotification();
                    disconnect();
                }
            }
        }
    }

}

The serial socket class:


class SerialSocket implements Runnable {

    private static final UUID BLUETOOTH_SPP = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");

    private final BroadcastReceiver disconnectBroadcastReceiver;

    private Context context;
    private SerialListener listener;
    private BluetoothDevice device;
    private BluetoothSocket socket;
    private boolean connected;

    SerialSocket() {
        disconnectBroadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if(listener != null)
                    listener.onSerialIoError(new IOException("background disconnect"));
                disconnect(); // disconnect now, else would be queued until UI re-attached
            }
        };
    }

    /**
     * connect-success and most connect-errors are returned asynchronously to listener
     */
    void connect(Context context, SerialListener listener, BluetoothDevice device) throws IOException {
        if(connected || socket != null)
            throw new IOException("already connected");
        this.context = context;
        this.listener = listener;
        this.device = device;
        context.registerReceiver(disconnectBroadcastReceiver, new IntentFilter(Constants.INTENT_ACTION_DISCONNECT));
        Executors.newSingleThreadExecutor().submit(this);
    }

    void disconnect() {
        listener = null; // ignore remaining data and errors
        // connected = false; // run loop will reset connected
        if(socket != null) {
            try {
                socket.close();
            } catch (Exception ignored) {
            }
            socket = null;
        }
        try {
            context.unregisterReceiver(disconnectBroadcastReceiver);
        } catch (Exception ignored) {
        }
    }

    void write(byte[] data) throws IOException {
        if (!connected)
            throw new IOException("not connected");
        socket.getOutputStream().write(data);
    }

    @Override
    public void run() { // connect & read
        try {
            socket = device.createRfcommSocketToServiceRecord(BLUETOOTH_SPP);
            socket.connect();
            if(listener != null)
                listener.onSerialConnect();
        } catch (Exception e) {
            if(listener != null)
                listener.onSerialConnectError(e);
            try {
                socket.close();
            } catch (Exception ignored) {
            }
            socket = null;
            return;
        }
        connected = true;
        try {
            byte[] buffer = new byte[1024];
            int len;
            //noinspection InfiniteLoopStatement
            while (true) {
                len = socket.getInputStream().read(buffer);
                byte[] data = Arrays.copyOf(buffer, len);
                if(listener != null)
                    listener.onSerialRead(data);
            }
        } catch (Exception e) {
            connected = false;
            if (listener != null)
                listener.onSerialIoError(e);
            try {
                socket.close();
            } catch (Exception ignored) {
            }
            socket = null;
        }
    }

}

And the second fragment whereas I need to keep connection or connect to the same device already connected in fragment ("conexiones"):

public class Identificacion  extends Fragment implements ServiceConnection, SerialListener {

    private String deviceAddress;
    private String newline = "\r\n";
    private String receiveText;
    private enum Connected { False, Pending, True }
    private String sendText;
    private SerialSocket socket;
    private SerialService service;
    private boolean initialStart = true;
    private Connected connected = Connected.False;

       // constructor requerido vacio
    public Identificacion(){

    }
    @Override
    public void onCreate(Bundle savedInstanceState) {
        Log.e("mio", "dentro on creata identificacion");
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
 //       deviceAddress = getArguments().getString("device");
    }


    @SuppressWarnings("deprecation") // onAttach(context) was added with API 23. onAttach(activity) works for all API versions
    @Override
    public void onAttach(Activity activity) {
        super.onAttach(activity);
        getActivity().bindService(new Intent(getActivity(), SerialService.class), this, Context.BIND_AUTO_CREATE);
    }

    @Override
    public void onDetach() {
        try { getActivity().unbindService(this); } catch(Exception ignored) {}
        super.onDetach();
    }

    @Override
    public void onResume() {
        super.onResume();
  /*      if(initialStart && service !=null) {
            initialStart = false;
            getActivity().runOnUiThread(this::connect);
        } */
    }


    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState){
        view = inflater.inflate(R.layout.fragment_identificacion, container, false );

        return view;
    }

    private void addListenerOnButton() {

        bt12.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View arg0) {
                EditText txtView = (EditText) aux1;
                EditText txtView2 = (EditText) aux2;
                TextView txtView3 = (TextView) aux3;
                if (pin2 != null && pin2.length() == largo && pin4 != null && pin4.length() == largo){
                    //consultar BD si exta bien la pass, caso si:
                    Log.e("mio", "dentro de pin y pass con formato " + pin2);
                    pin=pin2;
                    String aenvio=(String)pin2+";"+pin4;
                    // enviar pin por BT
                    connect();
                    send(aenvio);

                }

            }

        });

    }// fin add listener button

    private void connect() {
        try {
            MainActivity activity = (MainActivity) getActivity();
            String par3= activity.getidEquipo();
            deviceAddress=par3;
            Log.e("mio", "connect identif valor deviceAddress "+deviceAddress);
            //deviceAddress = getArguments().getString("device");
            BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
            BluetoothDevice device = bluetoothAdapter.getRemoteDevice(deviceAddress);
            String deviceName = device.getName() != null ? device.getName() : device.getAddress();
        //    status("connecting...");
            Log.e("mio", "connect identif deviceName  "+deviceName);
            connected = Connected.Pending;
            onAttach(activity);
           // socket =
            //socket = new SerialSocket();
            getActivity().bindService(new Intent(getActivity(), SerialService.class ), this, Context.BIND_ADJUST_WITH_ACTIVITY );
            service.connect(this, "Connected to " + deviceName);
            socket.connect(getContext(), service, device);
            connected = Connected.True;
            Log.e("mio", "connect identif salida  "+deviceName);
        } catch (Exception e) {
            onSerialConnectError(e);
        }
    }

    private void send(String str) {
        if(connected != Connected.True) {
            Toast.makeText(getActivity(), "not connected", Toast.LENGTH_SHORT).show();
            Log.e("mio", "dentro send no conectado "+str);
          //  return;
        }
        try {
            connect();
        //    SpannableStringBuilder spn = new SpannableStringBuilder(str+'\n');
            Log.e("mio", "send conectado "+str);
        //    spn.setSpan(new ForegroundColorSpan(getResources().getColor(R.color.colorSendText)), 0, spn.length(), Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
            Toast.makeText(getActivity(), "enviando login a esp", Toast.LENGTH_SHORT).show();
            sendText=str; // poner aca el string de user;pass a enviar al esp32 app
            byte[] data = (str + newline).getBytes();
            socket.write(data);
        } catch (Exception e) {
            onSerialIoError(e);
        }
    }

    private void receive(byte[] data) {

        receiveText+=(new String(data));
    }


    @Override
    public void onServiceConnected(ComponentName name, IBinder binder) {
        service = ((SerialService.SerialBinder) binder).getService();
        if(initialStart && isResumed()) {
            initialStart = false;
            getActivity().runOnUiThread(this::connect);
        }
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        service = null;
    }


    @Override
    public void onSerialRead(byte[] data) {
        Log.e("mio", "serial leer data ");
        receive(data);
    }

    @Override
    public void onSerialIoError(Exception e) {
        Log.e("mio", "serial io error, desconectar ");
        disconnect();
    }
}
like image 898
LucasRT Avatar asked Dec 05 '19 17:12

LucasRT


1 Answers

Managing code when you are using Bluetooth or system-related task is too hard because it creates a tightly coupled code eventually turn into the buggy code. So you can use this and this libraries to do your task neat and cleanly. Please check the example app for my suggested first and second libraries. If you face any struck in implementation let me know.

like image 190
Gk Mohammad Emon Avatar answered Sep 21 '22 21:09

Gk Mohammad Emon