2013-08-24 3 views
5

Ich schrieb eine einfache Anwendung basierend auf BluetoothChat. Ich kommuniziere zwischen dem Telefon und einem Bluetooth-Modul mit SPP-Profil. Das Telefon initiiert immer die Kommunikation. Die Anwendung funktionierte perfekt auf Android 4.2, mit Nexus 3 und Samsung Galaxy 3. Nach dem Update auf Android 4.3 funktioniert die Anwendung nicht mehr. Ich verbinde mich die ganze Zeit, ich kann einen outpustream senden und die richtigen Daten erhalten, aber nach dem ersten outputstream Befehl, die Anwendung immer nach ca. 6s getrennt. Wie in der folgenden Protokolldatei gezeigt, sieht es so aus, dass es im Eingangsstrom ein Zeitgeberproblem gibt.Anwendung mit Bluetooth SPP-Profil funktioniert nicht nach dem Update von Android 4.2 auf Android 4.3

08-23 14:10:00.726: D/mems(23193): STEVAL-MKI106V1 
08-23 14:10:00.804: D/Main Activity(23193): firmware version*setdb106V1 
08-23 14:10:00.812: D/Main Activity(23193): sent message*setdb106V1 
08-23 14:10:00.812: D/BluetoothMEMSCommunication(23193): dans write3 
08-23 14:10:00.812: D/BluetoothMEMSCommunication(23193): envoi stream 
08-23 14:10:05.812: W/bt-btif(20368): dm_pm_timer expires 
08-23 14:10:05.812: W/bt-btif(20368): dm_pm_timer expires 0 
08-23 14:10:05.812: W/bt-btif(20368): proc dm_pm_timer expires 
08-23 14:10:11.656: E/bt-btm(20368): btm_sec_disconnected - Clearing Pending flag 
08-23 14:10:11.656: W/bt-btif(20368): invalid rfc slot id: 15 
08-23 14:10:11.656: I/connection(23193): connectionlost 

Was ist dm_pm_timer? Ich habe versucht, einen anderen Weg zu verbinden, mit sicheren und unsicheren rfcom. Ich weiß, dass der Bluetooth-Chat nicht optimiert ist, um den Puffer zu empfangen, also habe ich ihn modifiziert, keinen Effekt. Ich habe auch den Flush-Befehl für den Outpustream verwendet, aber auch keinen Effekt.

package com.meneujj.memsbtbis; 

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

import android.bluetooth.BluetoothAdapter; 
import android.bluetooth.BluetoothDevice; 
import android.bluetooth.BluetoothSocket; 
import android.content.Context; 
import android.os.Bundle; 
import android.os.Handler; 
import android.os.Message; 
import android.util.Log; 
import android.widget.Toast; 

public class BluetoothMEMSCommunication { 

// debugging 
private static final String TAG = "BluetoothMEMSCommunication"; 
private static final boolean D = true; 


// eMotion BT h as this standard UUID 
private static final UUID STANDARD_UUID = 
     UUID.fromString("00001101-0000-1000-8000-00805F9B34FB"); 


// Member fields 
private final BluetoothAdapter mAdapter; 
private final Handler mHandler; 
private int mState; 
private int handlerCalling; 
private ConnectThread mConnectThread; 
private ConnectedThread mConnectedThread; 

     // Constants they indicate the current connection state 
public static final int STATE_NONE = 0; 
public static final int STATE_CONNECTED = 3; // now connected to a remote device 

// constructor. Prepares a new Bluetooth Connection 
// context The UI Activity Context 
// handler an Handler to send messages back to the UI Activity 

public BluetoothMEMSCommunication(Context context, Handler handler, int i) { 
    mAdapter = BluetoothAdapter.getDefaultAdapter(); 
    mState = STATE_NONE; 
    mHandler = handler; 
    handlerCalling = i; 

} 


private synchronized void setState(int state) { 
    mState = state; 
    Log.d(TAG, Integer.toString(mState)); 
    mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_STATE_CHANGE, state, -1).sendToTarget(); 
} 

public synchronized void connect(BluetoothDevice device) { 


    // start the thread to connect with the given device 
    if (mConnectThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 

    } 

    // cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 

    } 

    Log.d(TAG,"routine connect lancee"); 
    mConnectThread = new ConnectThread(device); 
    mConnectThread.start(); 

} 


private void ConnectionLost() { 
    // Send a failure message back to the activity 
    Message msg = mHandler.obtainMessage(MainActivityMemsBT.CONNECTION_LOST_MESSAGE); 
    Bundle bundle = new Bundle(); 
    bundle.putString(MainActivityMemsBT.TOAST_CONNECTION_LOST, "Device connection was lost"); 
    msg.setData(bundle); 
    mHandler.sendMessage(msg); 
    Log.i("connection","connectionlost"); 

    setState(STATE_NONE); 
    StopAllThreads(); 

} 



public synchronized void StopAllThreads() { 

    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 

    } 

setState(STATE_NONE); 

} 

public synchronized void connected(BluetoothSocket socket, BluetoothDevice device, final String socketType) { 

    // cancel the thread they completed the connection 
    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

    // Cancel any thread currently running a connection 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 

    } 


    // Start the thread to manage the connection and perform transmission 
    mConnectedThread = new ConnectedThread(socket, socketType); 
    mConnectedThread.start(); 

    // Send the name of the connected device back to the UI activity 
    Message msg = mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_DEVICE_NAME); 
    Bundle bundle = new Bundle(); 
    bundle.putString(MainActivityMemsBT.DEVICE_NAME, device.getName()); 
    msg.setData(bundle); 
    mHandler.sendMessage(msg);  

    setState(STATE_CONNECTED); 

} 


     public void write(byte[] out) { 
// create temporary object 
ConnectedThread r; 

Log.d(TAG,"dans write" + Integer.toString(mState)); 

// synchronize a copy of the ConnectedThread 
synchronized (this) { 

    if (handlerCalling == 2) setState(STATE_CONNECTED); 

    if (mState != STATE_CONNECTED) { 
     Log.d(TAG, "different de STATE_CONNECTED"); 
     Log.i(TAG, Integer.toString(handlerCalling)); 
     return;} 

    r= mConnectedThread; 
} 

r.write(out); 

    } 

Jede Idee ist, gibt es einen Workaround? Oder jeder offensichtlicher Fehler in meinem Code

Dank

// Thread runs while attempting to an an outgoing connection with a device. 
// it runs straight through; the connection either succeeds or fails. 
private class ConnectThread extends Thread { 

    private final BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 
    private String mSocketType; 

    public ConnectThread(BluetoothDevice device) { 
     mmDevice = device; 
     BluetoothSocket tmp = null; 

     try { 
     tmp = device.createRfcommSocketToServiceRecord(STANDARD_UUID); 
      //tmp = device.createInsecureRfcommSocketToServiceRecord(STANDARD_UUID); 

/*   try { 
       Method m = device.getClass().getMethod("createRfcommSocket", new Class[] {int.class}); 
       try { 
        tmp = (BluetoothSocket) m.invoke(device, 1); 
       } catch (IllegalArgumentException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (IllegalAccessException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } catch (InvocationTargetException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 
      } catch (NoSuchMethodException e) { 
       // TODO Auto-generated catch block 
       e.printStackTrace(); 
      } */ 

     } catch (IOException e) { 

     } 
     mmSocket = tmp; 

    } 

    public void run() { 

     setName("ConnectThread" + mSocketType); 
     mAdapter.cancelDiscovery(); 

     try { 
      mmSocket.connect(); 
     } catch (IOException e) { 

      try { 
       mmSocket.close(); 
      } catch (IOException e2) { 
       Log.e(TAG, "unable to close() " + mSocketType + "socket during connection failure", e2); 
      } 

     return; 
     } 

    // reset the CoonectThread because the job is over 
    synchronized (BluetoothMEMSCommunication.this) { 
     mConnectThread = null; 
     } 

    connected(mmSocket, mmDevice, mSocketType); 

    } 

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

     } 
    } 

     // close connectThread class  
} 


    private class ConnectedThread extends Thread { 

private final BluetoothSocket mmSocket; 
private final InputStream mmInStream; 
private final OutputStream mmOutStream; 

public ConnectedThread(BluetoothSocket socket, String socketType) { 

    mmSocket = socket; 
    InputStream tmpIn = null; 
    OutputStream tmpOut = null; 

    try { 
     tmpIn = socket.getInputStream(); 
     tmpOut = socket.getOutputStream(); 

    } catch (IOException e) { 
     ConnectionLost(); 

    } 

    mmInStream = tmpIn; 
    mmOutStream = tmpOut; 

} 

// Thread to listen to input sockets 

public void run() { 

    Log.i(TAG, "Begin mConnectedThread"); 

    byte[] buffer = new byte[1024]; 
// int bytes; 
    int bytesRead = -1; 
    String message = ""; 

    // keep listening to the InputStream while connected 
    while(true) { 


      try { 

       // read from the input stream 
      // bytesRead = mmInStream.read(buffer); 
     //  message = message+ new String(buffer, 0, bytesRead); 

      // byte[] byteString = message.getBytes(); 

       Log.i("info","pret a faire read"); 
       bytesRead = mmInStream.read(buffer, 0, 1024); 

       if (bytesRead != -1 && handlerCalling == 1) { 
       mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_READ, bytesRead, -1, buffer).sendToTarget(); } 

       if (bytesRead !=-1 && handlerCalling == 2) { 
        mHandler.obtainMessage(DemoAccelerometer.MESSAGE_READ, bytesRead, -1, buffer).sendToTarget(); } 

       } 

      catch (IOException e) { 

       ConnectionLost(); 
       break; 
      } 


      } 

     } 


public void write(byte[] buffer) { 

    try{ 
     mmOutStream.write(buffer); 

//  if (handlerCalling == 1) { 
//  mHandler.obtainMessage(MainActivityMemsBT.MESSAGE_WRITE, -1, -1, buffer).sendToTarget(); 
     Log.d(TAG,"envoi stream"); 

    // mmOutStream.flush(); 
//  } 

    } catch (IOException e) { 

    } 

} 

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

    } 
} 

    } 

    } 
+0

können Sie irgendeine Lösung gleiche Sache finden, die ich gegenüberstelle – PankajAndroid

Antwort

2

fand ich eine Arbeit um. Die Verbindung wird getrennt, wenn für einige Sekunden keine Streaming-Aktivität erfolgt. Ich habe es geschafft, einige Ausgaben pro Sekunde mehrmals zu streamen, und es wird nie getrennt.

11

Wir können die Bluetooth-Verbindung nach 6 Sekunden bei der Kommunikation von unserer Nexus 4-App zu einem externen Bluetooth-EKG (medizinisches Gerät) nach dem Upgrade von Android 4.2 auf 4.3 bestätigen. Dies geschieht speziell während einer EKG-Messung mit vielen eingehenden Daten (vom EKG zur Android App), aber keine ausgehenden Daten. Die "normale" Bluetooth-Kommunikation mit einigen ein- und ausgehenden Daten scheint von Zeit zu Zeit nicht betroffen zu sein.

nach 6 Sekunden wir die gleichen adb Log-Meldungen von JJM berichteten siehe

dm_pm_timer expires 
dm_pm_timer expires 0 
proc dm_pm_timer expires 
btm_sec_disconnected - Clearing Pending flag 

Dieser Timer Ablauf auf der Android Seite löst etwas (Schlussausgangsstrom, da keine abgehenden Daten?) Auf dem externen Bluetooth-EKG die in turn sendet einen EKG-spezifischen Befehl, den wir auf dem Eingabestream erhalten, den wir nie auf dem Nexus 4 mit Android 4.2 erhalten.

Wenn Sie die Android-App-Implementierung ändern, um gelegentlich einen willkürlichen "keep alive" -Befehl an das EKG zu senden, wird das Problem gelöst. Der Timer-Ablauf erscheint nicht mehr in den AdB-Protokollen und die EKG-Messung verhält sich nun genauso wie bei Android 4.2.

Danke an JJM für die Hinweise.

1

Ich fand auf StackOverflow eine Antwort, die mir half, das Problem zu beheben. Ich nehme an, es hat etwas damit zu tun, dass InputStream und OutputStream nicht richtig geschlossen und nulled werden, ebenso wie die Bluetooth-Buchse. Nach der Verwendung dieser Funktion:

in ConnectedThread und rufen Sie es bei Bedarf, entfernte ich dieses Problem. Es könnte auch ein Problem beim Lesen aus dem inputStream sein, vielleicht weil beim Lesen nichts darin war.

Ich schlage vor, dass Sie eine boolesche Funktion readWrite(), dass, wenn Sie in outputStream schreiben lesen Sie auch den inputStream und senden Sie den readBuffer an UI mit mHandler.Wenn sowohl Lesen als auch Schreiben in Ordnung sind, dann geben Sie true zurück, wenn einer von ihnen schiefgegangen ist, geben Sie false zurück und verwenden Sie resetConection, bevor Sie ConnectedThread schließen.

Es funktionierte sehr schön für mich.

UPDATE: (30-SEPT-2013) Ich benutze meine App und bekomme immer noch den hci_status = 36 nach ein paar Minuten. Ich habe eine App, die sich mit einem externen Bluetooth-Gerät verbindet. Ich sende Daten und empfange Daten ca.. 3 mal/sek. Ich verwende ein Thread.sleep (300) zwischen Schreibvorgängen. In meinen Tests habe ich diesen Fehler nach ein paar Minuten bis zu fast 30 Minuten beim Ausführen der App bekommen.

Jede Rückmeldung ist willkommen!

Verwandte Themen