28 votes

Déconnectez une prise Bluetooth dans Android

Je suis l'élaboration d'un programme dans lequel, à partir d'un Téléphone Android, j'ai pour vous connecter en tant que client d'un Bluetooth médical capteur. Je suis sur le Bluetooth de l'API et pas de problème lors de la connexion SPP (profil), mais quand j'arrive à la fin de la prise, le capteur est toujours connecté à mon téléphone (bien que j'ai fermer la connexion).

Il n'existe aucun moyen de faire une déconnexion de la fonction Bluetooth? Je pense qu'il y a une intention appelé ACTION_ACL_CONNECTED, qui ne qui. Quelqu'un peut-il m'expliquer comment l'utiliser?

Merci à l'avance.

MODIFIÉ: Voici le code, si quelqu'un a besoin d'infos supplémentaires, c'est un Non 4100 médical capteur.

Set<BluetoothDevice> pairedDevices = Activa.myBluetoothAdapter.getBondedDevices();
        // If there are paired devices
        if (pairedDevices.size() > 0) {
            // Loop through paired devices
            for (BluetoothDevice device : pairedDevices) {
                // Add the name and address to an array adapter to show in a ListView
                String name = device.getName();
                if (name.contains("Nonin")) {
                    try {
                        found = true;
//                      socket = device.createRfcommSocketToServiceRecord(UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"));
//                      handler.sendEmptyMessage(5);
//                      Activa.myBluetoothAdapter.cancelDiscovery();
//                      socket.connect();
                        BluetoothDevice hxm = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(device.getAddress());
                        Method m;
                        try {
                            m = hxm.getClass().getMethod("createRfcommSocket", new Class[]{int.class});
                            socket = (BluetoothSocket)m.invoke(hxm, Integer.valueOf(1));
                            handler.sendEmptyMessage(5);
                            socket.connect();
                        } catch (Exception e) {
                            handler.sendEmptyMessage(7);
                            e.printStackTrace();
                            break;
                        }
                        handler.sendEmptyMessage(6);
                        InputStream in = socket.getInputStream();
                        OutputStream out = socket.getOutputStream();
                        byte[] retrieve = { 0x44, 0x31};
                        out.write(retrieve);
                        byte [] ack = new byte [1];
                        in.read(ack);
                        if (ack[0] == 0x15) {
                            cancelMeasurement();
                            return;
                        }
                        byte [] data = new byte [3];
                        long timeStart = System.currentTimeMillis();
                        this.timePassed = System.currentTimeMillis() - timeStart;
                        while ((this.timePassed < (this.time))&&(this.finished)) {
                            try {
                                in.read(data);
                                processData(data);
                                Thread.sleep(1000);
                                this.timePassed = System.currentTimeMillis() - timeStart;
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                        in.close();
                        out.close();
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
}

43voto

Brad Hein Points 4874

N'oubliez pas de fermer votre Entrée/sortie flux d'abord, puis de fermer le socket.

En fermant les volets, vous le coup d'envoi de la débrancher les processus. Après la fermeture de la socket, la connexion doit être entièrement décomposé.

Si vous fermez la prise avant les cours d'eau, vous pouvez peut-être contourner l'arrêt de certaines étapes, telles que la (bonne) clôture de la couche physique de la connexion.

Voici la méthode que j'utilise quand il est temps de rupture de la connexion.

/**
 * Reset input and output streams and make sure socket is closed. 
 * This method will be used during shutdown() to ensure that the connection is properly closed during a shutdown.  
 * @return
 */
private void resetConnection() {
        if (mBTInputStream != null) {
                try {mBTInputStream.close();} catch (Exception e) {}
                mBTInputStream = null;
        }

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

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

}

EDIT: Ajout de code pour se connecter():

// bluetooth adapter which provides access to bluetooth functionality. 
BluetoothAdapter        mBTAdapter      = null;
// socket represents the open connection.
BluetoothSocket         mBTSocket   = null;
// device represents the peer
BluetoothDevice         mBTDevice       = null; 

// streams
InputStream           mBTInputStream  = null;
OutputStream          mBTOutputStream = null;

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

/**
 * Try to establish a connection with the peer. 
 * This method runs synchronously and blocks for one or more seconds while it does its thing 
 * SO CALL IT FROM A NON-UI THREAD!
 * @return - returns true if the connection has been established and is ready for use. False otherwise. 
 */
private  boolean connect() {

        // Reset all streams and socket.
        resetConnection();

        // make sure peer is defined as a valid device based on their MAC. If not then do it. 
        if (mBTDevice == null) 
                mBTDevice = mBTAdapter.getRemoteDevice(mPeerMAC);

        // Make an RFCOMM binding. 
        try {mBTSocket = mBTDevice.createRfcommSocketToServiceRecord(UUID_RFCOMM_GENERIC);
        } catch (Exception e1) {
                msg ("connect(): Failed to bind to RFCOMM by UUID. msg=" + e1.getMessage());
                return false;
        }

        msg ("connect(): Trying to connect.");

        try {
                mBTSocket.connect();
        } catch (Exception e) {
                msg ("connect(): Exception thrown during connect: " + e.getMessage());
                return false;
        }

        msg ("connect(): CONNECTED!");

        try {
                mBTOutputStream = mBTSocket.getOutputStream();
                mBTInputStream  = mBTSocket.getInputStream();
        } catch (Exception e) {
                msg ("connect(): Error attaching i/o streams to socket. msg=" + e.getMessage());
                return false;
        }

        return true;
}

8voto

Per Laursen Points 51

SALUT,

J'ai vu exactement le même problème (HTC Desire). En dépit de la fermeture de la socket par le livre (comme Brad suggère), la prochaine connect() bloque jamais - jusqu'à fini par fermer() par un autre thread.

J'ai contourné le problème en appelant BluetoothAdapter.disable()/.enable() avant de les connecter. Terrible, hostile hack, je sais...

Je soupçonne que certains de la présente BT questions sont spécifiques du fabricant, comme certains l'application des réalisateurs semblent vivre heureux avec createRfcommSocketToServiceRecord(), qui certainement ne parvient pas sur mon HTC Desire (Android 2.1 update 1).

J'ai vu des indications (désolé, de ne pas avoir de référence) HTC Desire s BT pile diffère du Nexus One, bien qu'ils semblent être très semblables appareils...

BR Par

(plus) Voici une très simple à reproduire le problème (sans mon désactiver/activer le "cure"):

package com.care2wear.BtTest;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothSocket;
import android.os.Bundle;
import android.util.Log;
import android.widget.TextView;

public class BtTestActivity extends Activity {
    private static final String TAG="BtTest";

    BluetoothAdapter mBtAdapter = null;
    BluetoothDevice mBtDev = null;
    BluetoothSocket mBtSocket = null;
    InputStream isBt;
    OutputStream osBt;  
    String mAddress = "00:18:E4:1C:A4:66";

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);


        init();

        connect();  // ok
        disconnect(); // ok
        connect(); // this invariably fails - blocked until BT is switched off by someone else, or the peer device turns off/goes out of range
        disconnect();
    }

    private void init() {
        Log.d(TAG, "initializing");
        mBtAdapter = BluetoothAdapter.getDefaultAdapter();
        mBtDev = mBtAdapter.getRemoteDevice(mAddress);
        Log.d(TAG, "initialized");
    }

    private void connect() {
        try {
            Log.d(TAG, "connecting");
            Method m = mBtDev.getClass().getMethod("createRfcommSocket", new Class[] { int.class });
            mBtSocket = (BluetoothSocket) m.invoke(mBtDev, 1);
            mBtSocket.connect();
            Log.d(TAG, "connected");
        } catch (SecurityException e) {
            Log.e(TAG, "SecEx", e);
        } catch (NoSuchMethodException e) {
            Log.e(TAG, "NsmEx", e);
        } catch (IllegalArgumentException e) {
            Log.e(TAG, "IArgEx", e);
        } catch (IllegalAccessException e) {
            Log.e(TAG, "IAccEx", e);
        } catch (InvocationTargetException e) {
            Log.e(TAG, "ItEx", e);
        } catch (IOException e) {
            Log.e(TAG, "IOEx", e);
        }

    }

    private void disconnect() {
        Log.d(TAG, "closing");

        if (isBt != null) {
            try {
                isBt.close();
            } catch (IOException e) {
                Log.e(TAG, "isBt IOE", e);              
            }
            isBt = null;
        }
        if (osBt != null) {
            try {
                osBt.close();
            } catch (IOException e) {
                Log.e(TAG, "osBt IOE", e);              
            }
            osBt = null;
        }
        if (mBtSocket != null) {
            try {
                mBtSocket.close();
            } catch (IOException e) {
                Log.e(TAG, "socket IOE", e);                
            }
            mBtSocket = null;
        }
        Log.d(TAG, "closed");       
    }
}

Si quelqu'un peut tache si je le fais, à tort, n'hésitez pas à commenter :)

(2) Je pense que je l'ai eu à travailler maintenant:

  1. La méthode officielle de la connexion RFCOMM (via SDP) maintenant semble fonctionner (HTC Desire, 2.1 update 1), MAIS j'ai dû supprimer et re-paire BT de l'appareil. Allez comprendre..
  2. La reconnexion peut encore échouer (service de l'échec de la découverte) si je me reconnecter "trop vite" (quitter l'application, puis de redémarrer immédiatement). Suppose que la connexion n'est pas complètement vers le bas encore..
  3. Si j'ai toujours la fin de la (dernière) activité non seulement avec la finition(), mais également avec de l'Exécution.getRuntime().exit(0);, ça fonctionne beaucoup mieux. Aller à la figure une fois de plus...

Si quelqu'un peut expliquer cela, je vais apprendre avec joie. /Par

(plus de 3) A finalement obtenu le Froyo (2.2) mise à jour de mon Désir, et d'aussi loin que je peux voir, le SPP fonctionne maintenant :) /Par

3voto

djilk Points 11

J'ai constaté que si j'appelle socket.close () trop tôt après une communication récente via OutputStream, la fermeture échoue et je ne peux pas me reconnecter. J'ai ajouté un Thread.sleep (1000) juste avant l'appel à close () et cela semble le résoudre.

2voto

user343464 Points 21

Je développais une application qui se connecte à un appareil BT. Votre code fonctionne bien dans mon HTC Wildfire mais avec un Samsung Galaxy I5700 ne fonctionne pas. Les deux OS sont une mise à jour 2.1 mais .....

L'exception était «InvocationTargetException»

La seule chose que j'ai dû modifier, c'est la déconnexion ().

 private void disconnect() {
         if(Conectado){ 
            try {
                ***mBtSocket.close();***
                 texto.setText(texto.getText()+"\nDesconectado");
                 Conectado = false;
            } catch (IOException e1) {
                // TODO Auto-generated catch block
                texto.setText(texto.getText()+"\n"+e1.getMessage());
            } 
            catch (Exception e2) {
                // TODO Auto-generated catch block
                texto.setText(texto.getText()+"\n"+e2.getMessage());
            }    
         }
 

1voto

Rafael Mancilla Points 11

Hé, donc j'utilise l'application Bluetooth Chat du site de développement Android et ils fournissent une méthode stop () dans la classe BluetoothChatService. J'ai donc simplement créé une instance de celui-ci dans ma classe principale et j'ai appelé la fonction d'arrêt à partir de mon bouton de déconnexion.

Voici comment je l'appelle dans ma classe principale

// Objet membre pour les services de chat

 private BluetoothManager mChatService = null;
case R.id.disconnect:
        mChatService.stop();
break;
 

La méthode stop () dans BluetoothChatService

  private AcceptThread mAcceptThread;
    private ConnectThread mConnectThread;
    public synchronized void stop() 
    {
    if (mConnectThread != null)
    {
    mConnectThread.cancel(); mConnectThread = null;
    }
    if (mConnectedThread != null) 
    {
    mConnectedThread.cancel(); mConnectedThread = null;
    }
    if (mAcceptThread != null) 
    {
    mAcceptThread.cancel(); mAcceptThread = null;
    }
    }
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X