2015-05-13 106 views
14

我試圖用廣播接收器捕獲藍牙狀態更改。Android廣播接收器藍牙事件捕獲

我的清單:

<uses-permission android:name="android.permission.BLUETOOTH" /> 
<application> 
    <activity 
     android:name=".MainActivity" 
     android:label="@string/app_name" > 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 

    <receiver android:name=".BluetoothBroadcastReceiver" 
       android:label="@string/app_name"> 
     <intent-filter> 
      <action android:name="android.bluetooth.adapter.action.STATE_CHANGED" /> 
      <action android:name="android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED" /> 
      <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> 
      <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" /> 
     </intent-filter> 
    </receiver> 
</application> 

接收onReceive方法:

public void onReceive(Context context, Intent intent) { 

    String action = intent.getAction(); 
    Log.d("BroadcastActions", "Action "+action+"received"); 
    int state; 
    BluetoothDevice bluetoothDevice; 

    switch(action) 
    { 
     case BluetoothAdapter.ACTION_STATE_CHANGED: 
      state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, -1); 
      if (state == BluetoothAdapter.STATE_OFF) 
      { 
       Toast.makeText(context, "Bluetooth is off", Toast.LENGTH_SHORT).show(); 
       Log.d("BroadcastActions", "Bluetooth is off"); 
      } 
      else if (state == BluetoothAdapter.STATE_TURNING_OFF) 
      { 
       Toast.makeText(context, "Bluetooth is turning off", Toast.LENGTH_SHORT).show(); 
       Log.d("BroadcastActions", "Bluetooth is turning off"); 
      } 
      else if(state == BluetoothAdapter.STATE_ON) 
      { 
       Log.d("BroadcastActions", "Bluetooth is on"); 
      } 
      break; 

     case BluetoothDevice.ACTION_ACL_CONNECTED: 
      bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      Toast.makeText(context, "Connected to "+bluetoothDevice.getName(), 
        Toast.LENGTH_SHORT).show(); 
      Log.d("BroadcastActions", "Connected to "+bluetoothDevice.getName()); 
      break; 

     case BluetoothDevice.ACTION_ACL_DISCONNECTED: 
      bluetoothDevice = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE); 
      Toast.makeText(context, "Disconnected from "+bluetoothDevice.getName(), 
        Toast.LENGTH_SHORT).show(); 
      break; 
    } 
} 

我啓動應用程序,然後按Home鍵最小化。轉到設置並打開藍牙,但沒有任何反應。雖然我期望吐司和logcat消息。這裏有什麼問題?

+0

不確定,這可能是因爲廣播註冊的方式。我會嘗試在服務器上註冊,而不是在運行時註冊,看看是否有改變。 –

+0

@VladimirLichonos是的,我試圖添加服務,我註冊接收器。它看起來像這樣'IntentFilter fltr = new IntentFilter(BluetoothDevice.ACTION_ACL_CONNECTED); fltr.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); fltr.addAction(BluetoothAdapter.ACTION_CONNECTION_STATE_CHANGED); fltr.addAction(BluetoothAdapter.ACTION_STATE_CHANGED); registerReceiver(brecv,fltr);'其中'brecv'是CustomBluetoothReceiver的一個對象。沒有任何變化。 –

+0

你是否在某個地方開始服務? – osayilgan

回答

35

爲了趕藍牙狀態變化(STATE_OFFSTATE_TURNING_ONSTATE_ONSTATE_TURNING_OFF),這樣做在你的活動:

首先,添加藍牙允許您AndroidManifest文件:

<uses-permission android:name="android.permission.BLUETOOTH" /> 

創建BroadcastReceiver在您的活動或服務中:

private final BroadcastReceiver mBroadcastReceiver1 = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     final String action = intent.getAction(); 

     if (action.equals(BluetoothAdapter.ACTION_STATE_CHANGED)) { 
      final int state = intent.getIntExtra(BluetoothAdapter.EXTRA_STATE, BluetoothAdapter.ERROR); 
      switch(state) { 
       case BluetoothAdapter.STATE_OFF: 
        .. 
        break; 
       case BluetoothAdapter.STATE_TURNING_OFF: 
        .. 
        break; 
       case BluetoothAdapter.STATE_ON: 
        .. 
        break; 
       case BluetoothAdapter.STATE_TURNING_ON: 
        .. 
        break; 
      } 

     } 
    } 
}; 

創建一個IntentFilter d用的BroadcastReceiver註冊它到活動/服務在onCreate()方法:

@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 

    IntentFilter filter1 = new IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED); 
    registerReceiver(mBroadcastReceiver1, filter1); 

    ... 
} 

註銷的BroadcastReceiver在onDestroy()方法:

@Override 
protected void onDestroy() { 
    super.onDestroy(); 

    unregisterReceiver(mBroadcastReceiver1); 
} 

爲了捕捉設備(SCAN_MODE_NONESCAN_MODE_CONNECTABLESCAN_MODE_CONNECTABLE_DISCOVERABLE的可發現的變化),創建另一個BroadcastReceiver並向您的Activity註冊/取消註冊,如上所述。那些BroadcastReceiver的唯一區別是第一個使用BluetoothAdapter.EXTRA_STATE而另一個使用BluetoothAdapter.EXTRA_SCAN_MODE。下面是示例代碼的BroadcastReceiver捕捉可發現性的變化:

創建過濾器和在onCreate()方法註冊它:

IntentFilter filter2 = new IntentFilter(); 
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_STARTED); 
filter2.addAction(BluetoothAdapter.ACTION_DISCOVERY_FINISHED); 
filter2.addAction(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED); 
registerReceiver(mBroadcastReceiver2, filter2); 

在活動/服務創建BroadcastReciver捉可發現性的變化:

private final BroadcastReceiver mBroadcastReceiver2 = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     final String action = intent.getAction(); 

     if(action.equals(BluetoothAdapter.ACTION_SCAN_MODE_CHANGED)) { 

      int mode = intent.getIntExtra(BluetoothAdapter.EXTRA_SCAN_MODE, BluetoothAdapter.ERROR); 

      switch(mode){ 
       case BluetoothAdapter.SCAN_MODE_CONNECTABLE_DISCOVERABLE: 
        .. 
        break; 
       case BluetoothAdapter.SCAN_MODE_CONNECTABLE: 
        .. 
        break; 
       case BluetoothAdapter.SCAN_MODE_NONE: 
        .. 
        break; 
      } 
     } 
    } 
}; 

最後在onDestroy()取消註冊:

unregisterReceiver(mBroadcastReceiver2); 

請注意,您不需要將任何<intent-filter><receiver>添加到您的AndroidManifest文件,除非您需要添加藍牙許可。

如果你想趕上(ACTION_ACL_CONNECTEDACTION_ACL_DISCONNECTEDACTION_ACL_DISCONNECT_REQUESTED),現在你需要一個<intent-filter>添加到您的AndroidManifest文件:

<intent-filter> 
    <action android:name="android.bluetooth.device.action.ACL_CONNECTED" /> 
    <action android:name="android.bluetooth.device.action.ACL_DISCONNECTED" /> 
</intent-filter> 

創建過濾器和onCreate()方法進行註冊:

IntentFilter filter3 = new IntentFilter(); 
filter3.addAction(BluetoothDevice.ACTION_ACL_CONNECTED); 
filter3.addAction(BluetoothDevice.ACTION_ACL_DISCONNECTED); 
registerReceiver(mBroadcastReceiver3, filter3); 

然後在您的活動/服務中創建BroadcastReceiver:

private final BroadcastReceiver mBroadcastReceiver3 = new BroadcastReceiver() { 

    @Override 
    public void onReceive(Context context, Intent intent) { 
     String action = intent.getAction(); 

     switch (action){ 
      case BluetoothDevice.ACTION_ACL_CONNECTED: 
       .. 
       break; 
      case BluetoothDevice.ACTION_ACL_DISCONNECTED: 
       .. 
       break; 
     } 
    } 
}; 

最後,註銷:

unregisterReceiver(mBroadcastReceiver3); 

如果您想了解更多關於狀態常量,這是從文檔:

public static final String EXTRA_STATE

用作在一個整型附加域ACTION_STATE_CHANGED意圖請求 當前的電源狀態。可能的值有:STATE_OFF, STATE_TURNING_ON,STATE_ON,STATE_TURNING_OFF

public static final String EXTRA_SCAN_MODE

用作在ACTION_SCAN_MODE_CHANGED意圖一個整型附加域,以 請求當前的掃描模式。可能的值有:SCAN_MODE_NONE, SCAN_MODE_CONNECTABLE,SCAN_MODE_CONNECTABLE_DISCOVERABLE

+1

我想在我的應用程序中使用Connect Disconnect廣播我有相同的代碼,但我在Manifest本身中註冊了廣播。問題是我隨機接收廣播隨機設備..我使用Android M(6.0)我剛剛配對設備也收到廣播,有時也沒有配對,也有設備也不在配對模式,那麼也可以請幫幫我? – AdiAtAnd

+0

奧利奧做了些什麼改變?這似乎不再起作用 – behelit

+0

https://developer.android.com/guide/components/broadcasts.html#receiving_broadcasts:「從Android 8.0(API級別26)開始,系統對清單聲明的接收器施加了額外的限制。如果您的應用程序的目標是API級別26或更高,則無法使用清單爲大多數隱式廣播聲明接收方(廣播不專門針對您的應用程序)。「 – xvlcw

0

你的主要問題;)您不能使用 「開關」 字符串比較。

至少直到VERSION_INT 18(含)。版本19以Java 7開始。