2012-12-25 103 views
2

我正在處理以藍牙連接爲核心部分的應用程序。目前該應用程序已成功連接到藍牙設備並與其進行通信。現在的主要問題是,我們用來收集數據的設備在閒置狀態後進入睡眠模式。檢測藍牙設備的睡眠狀態Android

我的問題是,如何檢測到設備處於睡眠模式,以便我的應用程序可以要求用戶喚醒設備?

我通過SSP連接。連接代碼是來自API演示的藍牙聊天應用程序的精確副本。

睡眠模式 - 器件(不移動)到我的應用程序被連接在電池的運行,所以優化電池的使用如果Android應用不以1點分鐘的設備到設備的任何請求進入睡眠模式(可以關閉而不丟失連接)。因此,我的應用程序需要捕獲這種情況,並讓用戶知道設備處於睡眠模式並將其喚醒,以便它可以響應應用程序請求。 這是我可以解釋睡眠模式的最佳方式。請記住藍牙設備的睡眠模式,而不是android手機。

+0

你的睡眠模式是指你能解釋一下情景 –

+0

@ricintech請檢查問題,如果您使用的藍牙套接字連接,那麼它不會1後斷開再次添加睡眠模式信息... –

+1

min請檢查您是否在您的活動的onDestroy()方法中使套接字爲null。 –

回答

0

解決方案--- 我知道這不是完美的,但我仍米工作就可以了... 每當連接中斷,我得到我使用的遠程設備處於睡眠模式或遙不可及的或死的套接字錯誤。此外,我改變了我的代碼,以便我不需要UUID(現在是低級別連接)代碼如下。

public class HHDBapiBTService { 
// Debugging 
private static final String TAG = "HHDBapiBTService"; 
private static final boolean D = true; 

private BluetoothSocket mmSocket = null; 
private InputStream mmInStream = null; 
private OutputStream mmOutStream = null; 

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


// Constants that indicate the current connection state 
public static final int STATE_NONE = 0; // we're doing nothing 
public static final int STATE_LISTEN = 1; // now listening for incoming 
              // connections 
public static final int STATE_CONNECTING = 2; // now initiating an outgoing 
               // connection 
public static final int STATE_CONNECTED = 3; // now connected to a remote 
               // device 

public static final int STATE_SLEEP = 4; // now connected to a remote 
// device 


/** 
* Constructor. Prepares a new BluetoothChat session. 
* 
* @param context 
*   The UI Activity Context 
* @param handler 
*   A Handler to send messages back to the UI Activity 
*/ 
public HHDBapiBTService(Context context, Handler handler) { 
    mAdapter = BluetoothAdapter.getDefaultAdapter(); 
    mState = STATE_NONE; 
    mHandler = handler; 
} 

/** 
* Set the current state of the chat connection 
* 
* @param state 
*   An integer defining the current connection state 
*/ 
public synchronized void setState(int state) { 
    if (D) 
     Log.d(TAG, "setState() " + mState + " -> " + state); 
    mState = state; 

    // Give the new state to the Handler so the UI Activity can update 
    mHandler.obtainMessage(GlobalValues.MESSAGE_STATE_CHANGE, state, -1) 
      .sendToTarget(); 
} 

/** 
* Return the current connection state. 
*/ 
public synchronized int getState() { 
    return mState; 
} 

public void setHandler(Handler handler) { 
    mHandler = handler; 
} 

/** 
* Start the chat service. Specifically start AcceptThread to begin a 
* session in listening (server) mode. Called by the Activity onResume() 
*/ 
public synchronized void start() { 
    if (D) 
     Log.d(TAG, "start"); 

    // Cancel any thread attempting to make a connection 
    if (mConnectThread != null) { 
     mConnectThread.cancel(); 
     mConnectThread = null; 
    } 

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

    setState(STATE_LISTEN); 
} 

/** 
* Start the ConnectThread to initiate a connection to a remote device. 
* 
* @param device 
*   The BluetoothDevice to connect 
*/ 
public synchronized void connect(BluetoothDevice device) { 
    if (D) 
     Log.d(TAG, "connect to: " + device); 

    // Cancel any thread attempting to make a connection 
    if (mState == STATE_CONNECTING) { 
     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 connect with the given device 
    mConnectThread = new ConnectThread(device); 
    mConnectThread.start(); 
    setState(STATE_CONNECTING); 
} 

/** 
* Start the ConnectedThread to begin managing a Bluetooth connection 
* 
* @param socket 
*   The BluetoothSocket on which the connection was made 
* @param device 
*   The BluetoothDevice that has been connected 
*/ 
public synchronized void connected(BluetoothSocket socket, 
     BluetoothDevice device) { 
    if (D) 
     Log.d(TAG, "connected"); 

    // Cancel the thread that 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 transmissions 
    mConnectedThread = new ConnectedThread(socket); 
    mConnectedThread.start(); 

    setState(STATE_CONNECTED); 
} 

/** 
* Stop all threads 
*/ 
public synchronized void stop() { 
    if (D) 
     Log.d(TAG, "stop"); 
    if (mConnectThread != null) { 
     mConnectThread.cancel(true); 
     mConnectThread = null; 
    } 
    if (mConnectedThread != null) { 
     mConnectedThread.cancel(); 
     mConnectedThread = null; 
    } 

    setState(STATE_NONE); 
} 

/** 
* Write to the ConnectedThread in an unsynchronized manner 
* 
* @param out 
*   The bytes to write 
* @see ConnectedThread#write(byte[]) 
*/ 
public void write(byte[] out) { 
    if(getState() == STATE_SLEEP){ 
     connectionLost(); 
     return; 
    } 
    // Create temporary object 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (mState != STATE_CONNECTED) 
      return; 
     r = mConnectedThread; 

    } 
    // Perform the write unsynchronized 
    r.write(out); 
} 

public void closeConnection(){ 
    ConnectedThread r; 
    // Synchronize a copy of the ConnectedThread 
    synchronized (this) { 
     if (mState != STATE_CONNECTED) 
      return; 
     r = mConnectedThread; 
    } 
    r.cancel(); 
} 

/** 
* Indicate that the connection attempt failed and notify the UI Activity. 
*/ 
private void connectionFailed() { 
    if(getState() != STATE_LISTEN){ 
     setState(STATE_LISTEN); 

     // Send a failure message back to the Activity 
     Message msg = mHandler.obtainMessage(GlobalValues.MESSAGE_SHOW_TOAST); 
     Bundle bundle = new Bundle(); 
     bundle.putString(GlobalValues.TOAST, "HHD device is in sleep mode or out-of range. Please shake the HHD device to make it active."); 
     msg.setData(bundle); 
     mHandler.sendMessage(msg); 
    } 
} 

/** 
* Indicate that the connection was lost and notify the UI Activity. 
*/ 
private void connectionLost() { 
    //setState(STATE_LISTEN); 

    // Send a failure message back to the Activity 
    /*Message msg = mHandler.obtainMessage(GlobalValues.MESSAGE_SHOW_TOAST); 
    Bundle bundle = new Bundle(); 
    bundle.putString(GlobalValues.TOAST, "Device connection was lost"); 
    msg.setData(bundle); 
    mHandler.sendMessage(msg);*/ 
    setState(STATE_SLEEP); 
    Message msg = mHandler.obtainMessage(
         GlobalValues.MESSAGE_REMOTE_DEVICE_LOST); 
    mHandler.sendMessage(msg); 
} 


/** 
* This thread runs while attempting to make an outgoing connection with a 
* device. It runs straight through; the connection either succeeds or 
* fails. 
*/ 
private class ConnectThread extends Thread { 
    private BluetoothSocket mmSocket; 
    private final BluetoothDevice mmDevice; 

    public ConnectThread(BluetoothDevice device) { 
     mmDevice = device; 
    } 

    @SuppressLint("NewApi") 
    protected boolean simpleComm(Integer port) { 
     // byte [] inputBytes = null; 

     // The documents tell us to cancel the discovery process. 
     mAdapter.cancelDiscovery(); 

     Log.d(this.toString(), "Port = " + port); 
     try { 
      Method m = mmDevice.getClass().getMethod("createRfcommSocket", 
        new Class[] { int.class }); 
      mmSocket = (BluetoothSocket) m.invoke(mmDevice, port); 

      // debug check to ensure socket was set. 
      assert (mmSocket != null) : "Socket is Null"; 

      mAdapter.cancelDiscovery(); 
      // attempt to connect to device 
      mmSocket.connect(); 
      try { 
       Log.d(this.toString(), 
         "************ CONNECTION SUCCEES! *************"); 

       // Reset the ConnectThread because we're done 
       /*synchronized (HHDBapiBTService.this) { 
        mConnectThread = null; 
       }*/ 

       connected(mmSocket, mmDevice); 
       return true; 
      } finally { 
       // close the socket and we are done. 
       // //mmSocket.close(); 
      } 
      // IOExcecption is thrown if connect fails. 
     } catch (IOException ex) { 
      Log.e(this.toString(), "IOException " + ex.getMessage()); 
      if (port == 256) { 
       connectionFailed(); 
       try { 
        mmSocket.close(); 
        mmSocket = null; 
       } catch (IOException e) { 
        // TODO Auto-generated catch block 
        e.printStackTrace(); 
       } 

      } 
     } catch (NoSuchMethodException ex) { 
      Log.e(this.toString(), 
        "NoSuchMethodException " + ex.getMessage()); 
     } catch (IllegalAccessException ex) { 
      Log.e(this.toString(), 
        "IllegalAccessException " + ex.getMessage()); 
     } catch (InvocationTargetException ex) { 
      Log.e(this.toString(), 
        "InvocationTargetException " + ex.getMessage()); 
     }catch (NullPointerException ex) { 
      Log.e(this.toString(), 
        "NullPointerException " + ex.getMessage()); 
     } 
     return false; 
    } 

    public void run() { 
     for (Integer port = 1; port <= 256; port++) { 
      if (simpleComm(Integer.valueOf(port))) 
       break; 
     } 

    } 

    public void cancel() { 
     /*if (mmSocket != null) { 
      try { 
       mmSocket.close(); mmSocket = null; 
      } catch (IOException e) { 
       Log.e(TAG, "close() of connect secure socket failed", e); 
      } 
     }*/ 
    } 

    public void cancel(boolean val) { 
     if (mmSocket != null) { 
      try { 
       mmSocket.close(); mmSocket = null; 
      } catch (IOException e) { 
       Log.e(TAG, "close() of connect secure socket failed", e); 
      } 
     } 
    } 

} 

/** 
* This thread runs during a connection with a remote device. It handles all 
* incoming and outgoing transmissions. 
*/ 
private class ConnectedThread extends Thread { 

    private Logger logger; 

    public ConnectedThread(BluetoothSocket socket) { 
     Log.d(TAG, "create ConnectedThread"); 
     mmSocket = socket; 
     InputStream tmpIn = null; 
     OutputStream tmpOut = null; 

     // Get the BluetoothSocket input and output streams 
     try { 
      tmpIn = socket.getInputStream(); 
      tmpOut = socket.getOutputStream(); 
     } catch (IOException e) { 
      Log.e(TAG, "temp sockets not created", e); 
     } 

     logger = Logger.getInstance(); 

     mmInStream = tmpIn; 
     mmOutStream = tmpOut; 

    } 

    @Override 
    public void run() { 
     byte[] buffer = new byte[1024]; 
     int bytes; 
     // Keep listening to the InputStream while connected 
     //Logic to parse the Inputstream 
       } catch (IOException e) { 
        HHDBapiBTService.this.stop(); 
        Log.e(TAG, "disconnected", e); 
        //connectionLost(); 
        break; 
       } 
      } 
     } 
    } 

    /** 
    * Write to the connected OutStream. 
    * 
    * @param buffer 
    *   The bytes to write 
    */ 

    public void write(byte[] buffer) { 
     try { 
      mmOutStream.write(buffer); 
     } catch (IOException e) { 
      connectionLost(); 
      Log.e(TAG, "Exception during write", e); 
     } 
    } 

    public void cancel() { 
     try { 
      mmSocket.close(); 
     } catch (IOException e) { 
      Log.e(TAG, "close() of connect socket failed", e); 
     } 
    } 

} 
}