Autore Topic: Problema con bluetooth  (Letto 253 volte)

Offline davix10

  • Utente normale
  • ***
  • Post: 155
  • Respect: 0
    • Mostra profilo
  • Dispositivo Android:
    Lg G4
  • Play Store ID:
    davix10
  • Sistema operativo:
    Windows 10
Problema con bluetooth
« il: 13 Settembre 2016, 10:49:06 CEST »
0
Salve a tutti, ho modificato la mia classe bluetooth in modo che funzioni anche sui dispositivi con a bordo Marshmallow solo che riscontro un problema molto strano. L'app prende i dati che arrivano dal bluetooth e li plotta su di un grafico. Nell'app ho aggiunto la possibilità dell'autoconnect in modo tale che, dopo la prima connessione, viene memorizzato il MAC address del dispositivo e quindi si evita di dover fare il discovery ad ogni avvio.
Il mio problema è che con l'autoconnect l'app funziona perfettamente e il plot è fluido e in real time mentre se clicco sul pulsante discovery dell'app e quindi seleziono il dispositivo con il quale connettermi noto che il plot non è più in real time ma c'è un delay oltre che qualche lag nel plot.
Tutto ciò a cosa potrebbe essere dovuto?

Qui posto tutta la classe del bluetooth:

Codice (Java): [Seleziona]
public class Bluetooth extends Activity implements OnItemClickListener {

    public static void disconnect() {
        if (connectedThread != null) {
            connectedThread.cancel();
            connectedThread = null;
        }
    }

    public static void gethandler(Handler handler) {//Bluetooth handler
        mHandler = handler;
    }

    static Handler mHandler = new Handler();

    static ConnectedThread connectedThread;
    public static final UUID MY_UUID = UUID.fromString("00001101-0000-1000-8000-00805F9B34FB");
    public static boolean finito=false;
    protected static final int SUCCESS_CONNECT = 0;
    protected static final int MESSAGE_READ = 1;
    ArrayAdapter<String> listAdapter;
    ListView listView;
    static BluetoothAdapter btAdapter;
    Set<BluetoothDevice> devicesArray;
    ArrayList<String> pairedDevices;
    ArrayList<BluetoothDevice> devices;
    IntentFilter filter;
    BroadcastReceiver receiver;
    boolean primaVolta = true;
    SharedPreferences salva;
    String mac;
    ProgressDialog pb;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
        primaVolta = settings.getBoolean("autoConnect", true);
        mac = settings.getString("macAddress", null);
        Bundle extras = getIntent().getExtras();
        pb = new ProgressDialog(this);
        if (extras != null) {
            primaVolta = extras.getBoolean("boolean");
        }

        setContentView(R.layout.activity_bluetooth);

        init();
        if (btAdapter == null) {
            Toast.makeText(getApplicationContext(), "No bluetooth detected", Toast.LENGTH_SHORT).show();
            finish();
        } else {
            if (!btAdapter.isEnabled()) {
                turnOnBT();
            }
            if (primaVolta == true) {
                getPairedDevices();
                startDiscovery();
            }
        }

    }

    private void startDiscovery() {
        // TODO Auto-generated method stub
        btAdapter.cancelDiscovery();
        if (btAdapter.isEnabled()) {
            int aa = 0;
        } else {
            int aa = 0;
        }
        btAdapter.startDiscovery();
        if (android.os.Build.VERSION.SDK_INT >= 23) {
            List<ScanFilter> scanFilters = new ArrayList<ScanFilter>();
            ScanSettings scanSettings;
            boolean isScanning = false;

            ScanSettings.Builder scanSettingsBuilder = new ScanSettings.Builder();
            scanSettingsBuilder.setScanMode(ScanSettings.SCAN_MODE_LOW_LATENCY);
            scanSettings = scanSettingsBuilder.build();
            BluetoothLeScanner scanner = BluetoothAdapter.getDefaultAdapter().getBluetoothLeScanner();

            ScanCallback scanCallback = new ScanCallback() {
                @Override
                public void onScanResult(int callbackType, ScanResult result) {
                    super.onScanResult(callbackType, result);

                    if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
                        int rssi = result.getRssi();
                    }


                    // do something with RSSI value
                }

                @Override
                public void onScanFailed(int errorCode) {
                    super.onScanFailed(errorCode);

                    // a scan error occurred
                }
            };

            if (isScanning) {
                scanner.stopScan(scanCallback);
            } else {
                scanner.startScan(scanFilters, scanSettings, scanCallback);
            }

            isScanning = !isScanning;


        }
    }

    private void turnOnBT() {
        Intent intent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
        startActivityForResult(intent, 1);
    }

    private void getPairedDevices() {
        devicesArray = btAdapter.getBondedDevices();
        if (devicesArray.size() > 0) {
            for (BluetoothDevice device : devicesArray) {
                pairedDevices.add(device.getName());
            }
        }
    }

    private void init() {
        if (primaVolta == true) {
            listView = (ListView) findViewById(R.id.listView);
            listView.setOnItemClickListener(this);
            listAdapter = new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, 0);
            listView.setAdapter(listAdapter);
            btAdapter = BluetoothAdapter.getDefaultAdapter();
            pairedDevices = new ArrayList<String>();
            filter = new IntentFilter(BluetoothDevice.ACTION_FOUND);
            devices = new ArrayList<BluetoothDevice>();
            receiver = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    String action = intent.getAction();
                    if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                        BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                        devices.add(device);
                        String s = "";
                        for (int a = 0; a < pairedDevices.size(); a++) {
                            if (device.getName() != null && device.getName().equals(pairedDevices.get(a))) {
                                //append
                                s = "(Paired)";
                                break;
                            }
                        }
                        listAdapter.add(device.getName() + " " + s + " " + "\n" + device.getAddress());

                    } else if (BluetoothAdapter.ACTION_DISCOVERY_STARTED.equals(action)) {

                    } else if (BluetoothAdapter.ACTION_DISCOVERY_FINISHED.equals(action)) {

                    } else if (BluetoothAdapter.ACTION_STATE_CHANGED.equals(action)) {
                        if (btAdapter.getState() == btAdapter.STATE_OFF) {
                            turnOnBT();
                        }
                    }
                }

            };
            registerReceiver(receiver, filter);
            IntentFilter filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_STARTED);
            registerReceiver(receiver, filter);
            filter = new IntentFilter(BluetoothAdapter.ACTION_DISCOVERY_FINISHED);
            registerReceiver(receiver, filter);
            filter = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED);
        } else {
            try {
                btAdapter = BluetoothAdapter.getDefaultAdapter();
                String address = mac;
                BluetoothDevice device = btAdapter.getRemoteDevice(address);
                final ConnectThread connect = new ConnectThread(device);
                connect.start();
                pb.setMessage("Connecting...");
                pb.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
                pb.setCancelable(false);
                pb.setIndeterminate(true);
                pb.setProgressNumberFormat(null);
                pb.setProgressPercentFormat(null);
                pb.show();
                final Handler handler = new Handler();
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        pb.dismiss();
                        finish();
                    }
                }, 10000);
            } catch (Exception e) {
                finish();
            }

        }
    }

    @Override
    protected void onPause() {
        // TODO Auto-generated method stub
        super.onPause();
        try {
            unregisterReceiver(receiver);
        } catch (IllegalArgumentException e) {
            // ignored
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (resultCode == RESULT_CANCELED) {
            Toast.makeText(getApplicationContext(), "Bluetooth must be enabled to continue", Toast.LENGTH_SHORT).show();
            finish();
        }
    }

    @Override
    public void onItemClick(AdapterView<?> arg0, View arg1, int arg2, long arg3) {
        // TODO Auto-generated method stub
        if (btAdapter.isDiscovering()) {
            btAdapter.cancelDiscovery();
        }
        if (listAdapter.getItem(arg2).contains("(Paired)")) {

            BluetoothDevice selectedDevice = devices.get(arg2);
            mac = selectedDevice.getAddress();
            ConnectThread connect = new ConnectThread(selectedDevice);
            connect.start();
            SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(this);
            SharedPreferences.Editor editor = settings.edit();
            editor.putBoolean("autoConnect", false);
            editor.putString("macAddress", mac);
            editor.commit();
        } else {
            Toast.makeText(getApplicationContext(), "device is not paired", Toast.LENGTH_SHORT).show();
        }
    }

   

    private class ConnectThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final BluetoothDevice mmDevice;


        public ConnectThread(BluetoothDevice device) {
            // Use a temporary object that is later assigned to mmSocket,
            // because mmSocket is final
            BluetoothSocket tmp = null;
            mmDevice = device;
            Log.d("entro","thread");

            // Get a BluetoothSocket to connect with the given BluetoothDevice
            try {
                // MY_UUID is the app's UUID string, also used by the server code
                tmp = device.createRfcommSocketToServiceRecord(MY_UUID);
            } catch (IOException e) {
            }
            mmSocket = tmp;
        }

        public void run() {
            // Cancel discovery because it will slow down the connection
            btAdapter.cancelDiscovery();

            try {
                // Connect the device through the socket. This will block
                // until it succeeds or throws an exception
                mmSocket.connect();
                //connectedThread = new ConnectedThread(mmSocket);
            } catch (IOException connectException) {
                // Unable to connect; close the socket and get out
                try {
                    mmSocket.close();
                } catch (IOException closeException) {
                }

                return;
            }

            // Do work to manage the connection (in a separate thread)
            mHandler.obtainMessage(SUCCESS_CONNECT, mmSocket).sendToTarget();
            pb.dismiss();
            Log.d("esco","thread");
            finish();
         
        }

        /**
         * Will cancel an in-progress connection, and close the socket
         */

        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }
    }

    static class ConnectedThread extends Thread {
        private final BluetoothSocket mmSocket;
        private final InputStream mmInStream;
        private final OutputStream mmOutStream;

        public ConnectedThread(BluetoothSocket socket) {
            mmSocket = socket;
            InputStream tmpIn = null;
            OutputStream tmpOut = null;

            // Get the input and output streams, using temp objects because
            // member streams are final
            try {
                tmpIn = socket.getInputStream();
                tmpOut = socket.getOutputStream();
            } catch (IOException e) {
            }

            mmInStream = tmpIn;
            mmOutStream = tmpOut;
        }

        StringBuffer sbb = new StringBuffer();

        public void run() {
            byte[] buffer = new byte[1024];
            int bytes; // bytes returned from read()

            // Keep listening to the InputStream until an exception occurs
            while (true) {
                try {
                    /*
                    try {
                                               
                                        } catch (InterruptedException e) {
                                                // TODO Auto-generated catch block
                                                e.printStackTrace();
                                        }*/

                    buffer = new byte[100];
                    bytes = mmInStream.read(buffer, 0, 2);
                    while (bytes < 2) {
                        bytes += mmInStream.read(buffer, bytes, 2 - bytes);
                        Thread.sleep(1);
                    }
                    String aa= String.valueOf(System.currentTimeMillis());
//                    Log.d("tempo",aa);
                    mHandler.obtainMessage(MESSAGE_READ, 100000, 1, buffer).sendToTarget();
                    Thread.sleep(1);

                    // Send the obtained bytes to the UI activity

                } catch (IOException e) {
                    break;
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        public boolean controlloDimensione(int bytesNelBuffer) {
            int channels = 1;
            boolean controllo = false;

            if ((bytesNelBuffer / channels / 2 * channels * 2) >= 2) {

                controllo = true;

            }
            return controllo;


        }

        /* Call this from the main activity to send data to the remote device */
        public void write(String income) {

            try {
                mmOutStream.write(income.getBytes());
                for (int i = 0; i < income.getBytes().length; i++)
                    Log.v("outStream" + Integer.toString(i), Character.toString((char) (Integer.parseInt(Byte.toString(income.getBytes()[i])))));
                try {
                    Thread.sleep(20);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            } catch (IOException e) {
            }
        }

        public void write(byte[] buffer) {

            try {

                mmOutStream.write(buffer);

            } catch (IOException e) {
            }

        }


        /* Call this from the main activity to shutdown the connection */
        public void cancel() {
            try {
                mmSocket.close();
            } catch (IOException e) {
            }
        }

    }


}
Potrebbe essere un problema di thread non chiuso o del discovery che continua a girare in backgroud? Anche se a me in realtà non sembra nessuna di queste due opzioni.

Grazie!

Offline wlf

  • Utente normale
  • ***
  • Post: 315
  • Respect: +8
    • Mostra profilo
  • Dispositivo Android:
    Xperia
Re:Problema con bluetooth
« Risposta #1 il: 20 Settembre 2016, 10:24:52 CEST »
0
Succede anche la prima volta che esegui la discover prima della connect oppure succede solo dopo un autoconnect?
Nella onItemClick hai messe la cancellazione della discover, quindi escluderei che la discover sia ancora attiva; considera poi che la discover dura una decina di secondi o poco più poi termina comunque automaticamente, quindi potresti attendere che termini la discover prima di effettuare la connect se hai il dubbio.

Vieni avvertito dal BroadcastReceiver che la discover è finita (BluetoothAdapter.ACTION_DISCOVERY_FINISHED).

Io punterei il dito più sul fatto che la discover casomai abbassa la velocità di trasmissione del bluetooth che non effettuare una connect diretta ... casomai hai altri segnali bluetooth o wifi che fanno si che la velocità si abbassi ...