为所有片段保持蓝牙服务运行

Luc*_*sRT 6 java android android-fragments android-bluetooth

我卡住了,找不到在我的应用程序中重新启动或重新连接蓝牙服务的方法。该应用程序有 3 个片段,由 FragmentPagerAdapter 管理的选项卡。在第一个片段中,您可以发现、关联和与 BT 设备通信。在第二张和第三张卡中,必须与设备交互,无法获得连接或保持服务连接。

这是第一个片段:

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();
        }
    }


    }

Run Code Online (Sandbox Code Playgroud)

串行服务:


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();
                }
            }
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

串行套接字类:


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 devi