disconnection activity - Trennen Sie eine Bluetooth-Buchse in Android




title bar (6)

Ich entwickle ein Programm, bei dem ich mich von einem Android Phone aus als Client mit einem medizinischen Bluetooth-Sensor verbinden muss. Ich benutze die offizielle Bluetooth-API und kein Problem während der Verbindung (SPP-Profil), aber wenn ich den Socket schließe, ist der Sensor immer noch mit meinem Telefon verbunden (obwohl ich die Verbindung geschlossen habe).

Gibt es eine Möglichkeit, eine Bluetooth-Verbindung zu trennen? Ich denke, es gibt eine Absicht namens ACTION_ACL_CONNECTED, die das tut. Kann mir jemand erklären, wie man das benutzt?

Danke im Voraus.

EDITED: Hier ist der Code, wenn jemand weitere Informationen benötigt, ist es ein Nonin 4100 medizinischer Sensor.

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

Answers

HALLO,

Ich habe das genau gleiche Problem (HTC Desire) gesehen. Trotz des Schließens des Sockets durch das Buch (wie Brad vorschlägt) blockiert das nächste connect () für immer - bis es von einem anderen Thread beendet wird.

Ich habe das Problem umgangen, indem ich vor dem Verbinden immer BluetoothAdapter.disable () /. Enable () aufgerufen habe. Schrecklicher, unfreundlicher Hack, ich weiß ...

Ich vermute, dass einige der aktuellen BT-Probleme herstellerspezifisch sind, da einige App-Implementer glücklich mit createRfcommSocketToServiceRecord () leben, was auf meinem HTC Desire definitiv fehlschlägt (Android 2.1 Update 1).

Ich habe Hinweise gesehen (sorry, habe keine Referenzen), dass HTC Desire BT-Stack unterscheidet sich von der Nexus One, obwohl sie sehr ähnliche Geräte zu sein scheinen ...

BR Per

(Zusatz) Hier ist eine sehr einfache Aktivität, um das Problem zu reproduzieren (ohne meine Deaktivierung / Aktivierung 'Heilung'):

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

Wenn jemand herausfindet, ob ich es falsch mache, kannst du mich gerne kommentieren :)

(Zusatz 2) Ich denke, ich habe es jetzt zum Laufen gebracht:

  1. Die offizielle Methode, RFCOMM (über SDP) zu verbinden, scheint nun tatsächlich zu funktionieren (HTC Desire, 2.1 Update 1), ABER ich musste das BT-Gerät entfernen und neu pairen. Stelle dir das vor..
  2. Die Wiederverbindung schlägt möglicherweise fehl (Fehler bei der Dienstsuche), wenn ich die Verbindung zu schnell wieder herstelle (App beenden und dann sofort neu starten). Schätze, die Verbindung ist noch nicht komplett runter ..
  3. Wenn ich die (letzte) Aktivität nicht nur mit finish (), sondern auch mit Runtime.getRuntime (). Exit (0); abschliesse, funktioniert es viel besser. Geh noch einmal ...

Wenn jemand das erklären kann, werde ich glücklich lernen. /Pro

(Zusatz 3) Endlich habe ich das Froyo (2.2) Update für mein Desire bekommen, und soweit ich sehen kann, funktioniert SPP jetzt :) / Per


Hey, also habe ich die Bluetooth Chat Anwendung von der Android Development Seite benutzt und sie bieten eine stop() Methode in der BluetoothChatService Klasse. Also habe ich einfach eine Instanz davon in meiner Hauptklasse erstellt und die Stop-Funktion über meine Trennschaltfläche aufgerufen.

So nenne ich es in meiner Hauptklasse

// Mitgliedsobjekt für die Chat-Dienste

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

Die stop () Methode in 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;
    }
}

Ich habe festgestellt, dass, wenn ich socket.close () zu früh nach einer kürzlichen Kommunikation über den OutputStream aufruft, der Abschluss fehlschlägt und ich die Verbindung nicht wiederherstellen kann. Ich habe einen Thread.sleep (1000) kurz vor dem Aufruf von close () hinzugefügt und dies scheint es zu lösen.


Ich habe eine App entwickelt, die mit einem BT-Gerät verbunden ist. Ihr Code funktioniert gut in meinem HTC Wildfire, aber mit einem Samsung Galaxy I5700 funktioniert nicht. Beide sind 2.1 Update, aber .....

Die Ausnahme war 'InvocationTargetException'

Die einzige Sache, die ich ändern musste, ist das disconnect ().

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

Bitte denken Sie daran, zuerst Ihre Eingabe- / Ausgabestreams zu schließen und dann den Socket zu schließen.

Indem Sie die Streams schließen, starten Sie den Trennungsprozess. Nachdem Sie den Socket geschlossen haben, sollte die Verbindung vollständig abgebaut werden.

Wenn Sie den Socket vor den Streams schließen, umgehen Sie möglicherweise bestimmte Schritte zum Herunterfahren, z. B. das (ordnungsgemäße) Schließen der Verbindung zur physikalischen Schicht.

Hier ist die Methode, die ich benutze, wenn es darum geht, die Verbindung zu unterbrechen.

/**
 * 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: Hinzufügen von Code für connect ():

// 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;
}

Um die Startzeit Ihres Emulators zu verkürzen, müssen Sie vor dem Starten des Emulators die Option "Bootanimation deaktivieren" aktivieren. Weitere Informationen finden Sie in der Android-Dokumentation .

Falls Sie dies nicht wissen, müssen Sie den Emulator nicht jedes Mal schließen, wenn Sie Ihre App ausführen / debuggen. Wenn Sie auf Ausführen / Debuggen klicken, wenn es bereits geöffnet ist, wird Ihre APK-Datei in den Emulator hochgeladen und ziemlich sofort gestartet. Emulator dauert nur beim ersten Start ärgerlich lange.

Hier finden Sie einige Tipps, um den Android-Emulator zu beschleunigen : So beschleunigen Sie den Android-Emulator um bis zu 400% .





android bluetooth disconnection