2013-08-24 6 views
5

私はbluetoothChatに基づいて簡単なアプリケーションを作成しました。私は電話とブルートゥースモジュール間でSPPプロファイルを使用して通信します。電話機は常に通信を開始します。アプリケーションはNexus 3とSamsung Galaxy 3を使用して、Android 4.2でうまく機能しました。 Android 4.3へのアップデート後、アプリケーションはもう動作しません。私はいつも接続して、私はoutpustreamを送信し、適切なデータを受け取ることができますが、最初のoutputstreamコマンドの後、アプリケーションは常に6秒後に切断されます。 以下のlogcatに示すように、入力ストリームにタイマーの問題があるようです。Android 4.2からAndroid 4.3へのアップデート後にBluetooth SPPプロファイルを使用しているアプリケーションがありません

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 

dm_pm_timerとは何ですか? 安全で安全でないrfcomを使って、私は別の方法で接続しようとしました。私は、ブルートゥースチャットがバッファを受け取るように最適化されていないことを知っているので、私はそれを修正しました。私はoutpustreamにもflushコマンドを使用しましたが、効果はありません。

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

    } 

回避策がありますか?それとも私のコード内の任意の明白な間違い

おかげ

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

あなたは、私が直面しているものと同じものを見つけることができますか? – PankajAndroid

答えて

2

は、私の周りの仕事を見つけました。数秒間ストリーミングがない場合は切断されます。私は、何らかの出力や入力ストリーミングを毎秒何回かすることができました。

11

Android 4.2から4.3にアップグレードした後、GoogleのNexus 4アプリから外部のBluetooth ECG(医療機器)に通信すると、6秒後にBluetooth切断が確認できます。これは、多くの受信データ(ECGからAndroidアプリまで)を含むECG測定中に特に発生しますが、送信データはありません。 「通常の」ブルートゥース通信では、時折送受信される一部のデータには影響がないようです。私たちは、Android側でこのタイマーの有効期限は、その中に、外部のBluetooth ECG上で何か(なしアウトバウンドデータので、出力ストリームを閉じて?)をトリガーするJJM

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

によって報告された同じadbのログメッセージを参照してください6秒後

Android 4.2搭載のNexus 4で受信できない入力ストリームで受信したECG固有のコマンドが送信されます。

Androidアプリの実装を変更して、ECGに任意の「keep alive」コマンドを送信して問題を解決します。タイマーの有効期限はもうadbログには表示されず、ECG測定はAndroid 4.2と同じように動作するようになりました。

ヒントのJJMに感謝します。

1

私は問題を解決するのに役立つ答えをStackOverflowで見つけました。私はそれがinputStreamと何かを持っていると思います。outputStreamは正しく閉じられず、ヌルルードされていません。またBluetoothソケットもあります。この関数を使用した後:ConnectedThread内の

を必要に応じて呼び出し、それを削除しました。また、inputStreamからの読み込みで問題になる可能性があります。おそらく、読み込みを試みているときに何もなかったからです。

あなたはoutputStreamに書き込むたびにinputStreamを読み込んで、mHandlerを使ってreadBufferをUIに送るreadWrite()ブール関数を実行することをお勧めします。readとwriteの両方が正常であれば、trueを返し、そうでなければfalseを返し、resetConectionを使用してConnectedThreadを終了します。

非常にうまく機能しました。

アップデート:(30-SEPT-2013) 私のアプリケーションを実行していますが、数分後にはまだhci_status = 36になります。私は、外部のBluetoothデバイスに接続するアプリを持っています。私はデータを送信しており、およそデータを受信して​​います。 3回/秒。私は書き込みの間にThread.sleep(300)を使用しています。私のテストでは、アプリを実行するときに数分後にこのエラーが発生しました。

フィードバックは高く評価されています。

関連する問題