2017-04-20 104 views
0

我想實現一個掃描BLE設備的android應用程序。因爲我需要一些信標的距離信息,所以我想連續讀取RSSI。目前我能夠顯示RSSI,但值不會改變。應用程序讀取一次值並不更新值。我使用gitHub的示例BLE應用程序作爲基礎。如何連續顯示BLE設備的RSSI?

這是我的藍牙設備:

class DeviceHolder{ 
    BluetoothDevice device; 
    int rssi; 
    public DeviceHolder(BluetoothDevice device, int rssi){ 
     this. device = device; 
     this.rssi = rssi; 
    } 
} 

名單適配器:

private class LeDeviceListAdapter extends BaseAdapter { 
    private ArrayList<BluetoothDevice> mLeDevices; 
    private ArrayList<DeviceHolder> mLeHolders; 
    private LayoutInflater mInflator; 

    public LeDeviceListAdapter() { 
     super(); 
     mLeDevices = new ArrayList<BluetoothDevice>(); 
     mLeHolders = new ArrayList<DeviceHolder>(); 
     mInflator = DeviceScanActivity.this.getLayoutInflater(); 
    } 
    public void addDevice(DeviceHolder deviceHolder) { 
     if(!mLeDevices.contains(deviceHolder.device)) { 
      mLeDevices.add(deviceHolder.device); 
      mLeHolders.add(deviceHolder); 
     } 
    } 

和掃描回調:

private BluetoothAdapter.LeScanCallback mLeScanCallback = 
     new BluetoothAdapter.LeScanCallback() { 

      @Override 
      public void onLeScan(final BluetoothDevice device, int rssi, byte[] scanRecord) { 
       DeviceHolder deviceHolder = new DeviceHolder(device,rssi); 
       runOnUiThread(new DeviceAddTask(deviceHolder)); 
      } 
     }; 

class DeviceAddTask implements Runnable { 
    DeviceHolder deviceHolder; 

    public DeviceAddTask(DeviceHolder deviceHolder) { 
     this.deviceHolder = deviceHolder; 
    } 

    public void run() { 
     mLeDeviceListAdapter.addDevice(deviceHolder); 
     mLeDeviceListAdapter.notifyDataSetChanged(); 
    } 
} 

藍牙GattCallback在BluetoothLeService活動如下所示:

private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 
    @Override 
    public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 
     String intentAction; 
     if (newState == BluetoothProfile.STATE_CONNECTED) { 
      intentAction = ACTION_GATT_CONNECTED; 
      mConnectionState = STATE_CONNECTED; 
      boolean rssiStatus = mBluetoothGatt.readRemoteRssi(); 
      broadcastUpdate(intentAction); 
      Log.i(TAG, "Connected to GATT server."); 
      // Attempts to discover services after successful connection. 
      Log.i(TAG, "Attempting to start service discovery:" + 
        mBluetoothGatt.discoverServices()); 

     } else if (newState == BluetoothProfile.STATE_DISCONNECTED) { 
      intentAction = ACTION_GATT_DISCONNECTED; 
      mConnectionState = STATE_DISCONNECTED; 
      Log.i(TAG, "Disconnected from GATT server."); 
      broadcastUpdate(intentAction); 
     } 
    } 

    @Override 
    public void onServicesDiscovered(BluetoothGatt gatt, int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      broadcastUpdate(ACTION_GATT_SERVICES_DISCOVERED); 
     } else { 
      Log.w(TAG, "onServicesDiscovered received: " + status); 
     } 
    } 

    @Override 
    public void onCharacteristicRead(BluetoothGatt gatt, 
            BluetoothGattCharacteristic characteristic, 
            int status) { 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
     } 
    } 

    @Override 
    public void onCharacteristicChanged(BluetoothGatt gatt, 
             BluetoothGattCharacteristic characteristic) { 
     broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic); 
    } 

    public void onReadRemoteRssi(BluetoothGatt gatt, 
           int rssi, int status){ 
     super.onReadRemoteRssi(gatt, rssi, status); 
     if (status == BluetoothGatt.GATT_SUCCESS) { 
      Log.d(TAG, String.format("BluetoothGatt ReadRssi[%d]", rssi)); 
     } else { 
      Log.w(TAG, "onReadRemoteRssi received: " + status); 
     } 
     broadcastUpdate(ACTION_RSSI_VALUE_READ, rssi); 

    } 
}; 

private void broadcastUpdate(final String action) { 
    final Intent intent = new Intent(action); 
    sendBroadcast(intent); 
} 

private void broadcastUpdate(final String action, int rssi){ 
    Log.d(TAG, "broadcastUpdate - rssi"); 
    final Intent intent = new Intent(action); 
    intent.putExtra(DeviceControlActivity.EXTRAS_DEVICE_RSSI, rssi); 
    intent.setAction(ACTION_RSSI_VALUE_READ); 
    sendBroadcast(intent); 
} 

我擡頭互聯網和#2的指導,但所提供的解決方案並沒有爲我工作。我正在使用Android 6.01的三星Galaxy S5。 是否有人在暗示如何連續地顯示RSSI用於非連接的設備(在掃描)?任何關於錯誤執行的提示都是受歡迎的。

非常感謝您的幫助!

Sayus

PS:onReadRemoteRssi實現,因爲我想讀RSSI當設備被conected爲好。這個功能在這個時候並不重要,只是很好。

回答

0

你的應用程序讀取RSSI值一次,因爲當你添加一個新的BluetoothDevice到您的適配器,它會檢查它是否已經包含了一個不更新。 mDeviceRssi.put(device, rssi)

if(!mLeDevices.contains(deviceHolder.device)) { 
     mLeDevices.add(deviceHolder.device); 
     mLeHolders.add(deviceHolder); 
    } 

相反,在那裏你更新設備的RSSI值我將創建一個Map<BluetoothDevice,Integer>

+0

非常感謝您的回答!現在我明白了這個問題。而且我也明白,我應該只更新列出的設備。由於我是新android開發我會很感激,如果你能提供有關地圖以及如何使用它在我的代碼多一點信息。一個有用的鏈接也足夠了。再次感謝! – Sayus