2015-02-27 6 views
1

У меня есть этот код в приложении для Android, который я редактировал, но у меня возникла проблема с получением значения параметра, установленного на mHumidity (TextView). значение, отображаемое как-то вроде [email protected] что-то вроде этого. Но мое ожидаемое значение 0 или 1 с помощью кнопки толкнули на моем BLE устройствоЗначение характеристики низкой энергии Bluetooth bluetooth

/** 
* Created by Dave Smith 
* Double Encore, Inc. 
* MainActivity 
*/ 
public class MainActivity extends Activity implements BluetoothAdapter.LeScanCallback { 
     private static final String TAG = "BluetoothGattActivity"; 

     private static final String DEVICE_NAME = "Light"; 

     /* Humidity Service */ 
     private static final UUID HUMIDITY_SERVICE = UUID.fromString("29e70001-9227-e097-3473-09a5cc69a43a"); 
     private static final UUID HUMIDITY_DATA_CHAR = UUID.fromString("29e70002-9227-e097-3473-09a5cc69a43a"); 
     private static final UUID HUMIDITY_CONFIG_CHAR = UUID.fromString("29e70003-9227-e097-3473-09a5cc69a43a"); 

     /* Client Configuration Descriptor */ 
     private static final UUID CONFIG_DESCRIPTOR = UUID.fromString("00002902-0000-1000-8000-00805f9b34fb"); 


    private BluetoothAdapter mBluetoothAdapter; 
    private SparseArray<BluetoothDevice> mDevices; 

    private BluetoothGatt mConnectedGatt; 

    private TextView mTemperature, mHumidity, mPressure; 

    private ProgressDialog mProgress; 

    @Override 
    protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 
     requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS); 
     setContentView(R.layout.activity_main); 
     setProgressBarIndeterminate(true); 
     /* 
     * We are going to display the results in some text fields 
     */ 
    // mTemperature = (TextView) findViewById(R.id.text_temperature); 
     mHumidity = (TextView) findViewById(R.id.text_humidity); 
    // mPressure = (TextView) findViewById(R.id.text_pressure); 
     /* 
     * Bluetooth in Android 4.3 is accessed via the BluetoothManager, rather than 
     * the old static BluetoothAdapter.getInstance() 
     */ 
     BluetoothManager manager = (BluetoothManager) getSystemService(BLUETOOTH_SERVICE); 
     mBluetoothAdapter = manager.getAdapter(); 

     mDevices = new SparseArray<BluetoothDevice>(); 

     /* 
     * A progress dialog will be needed while the connection process is 
     * taking place 
     */ 
     mProgress = new ProgressDialog(this); 
     mProgress.setIndeterminate(true); 
     mProgress.setCancelable(false); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     /* 
     * We need to enforce that Bluetooth is first enabled, and take the 
     * user to settings to enable it if they have not done so. 
     */ 
     if (mBluetoothAdapter == null || !mBluetoothAdapter.isEnabled()) { 
      //Bluetooth is disabled 
      Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE); 
      startActivity(enableBtIntent); 
      finish(); 
      return; 
     } 

     /* 
     * Check for Bluetooth LE Support. In production, our manifest entry will keep this 
     * from installing on these devices, but this will allow test devices or other 
     * sideloads to report whether or not the feature exists. 
     */ 
     if (!getPackageManager().hasSystemFeature(PackageManager.FEATURE_BLUETOOTH_LE)) { 
      Toast.makeText(this, "No LE Support.", Toast.LENGTH_SHORT).show(); 
      finish(); 
      return; 
     } 

     clearDisplayValues(); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     //Make sure dialog is hidden 
     mProgress.dismiss(); 
     //Cancel any scans in progress 
     mHandler.removeCallbacks(mStopRunnable); 
     mHandler.removeCallbacks(mStartRunnable); 
     mBluetoothAdapter.stopLeScan(this); 
    } 

    @Override 
    protected void onStop() { 
     super.onStop(); 
     //Disconnect from any active tag connection 
     if (mConnectedGatt != null) { 
      mConnectedGatt.disconnect(); 
      mConnectedGatt = null; 
     } 
    } 

    @Override 
    public boolean onCreateOptionsMenu(Menu menu) { 
     // Add the "scan" option to the menu 
     getMenuInflater().inflate(R.menu.main, menu); 
     //Add any device elements we've discovered to the overflow menu 
     for (int i=0; i < mDevices.size(); i++) { 
      BluetoothDevice device = mDevices.valueAt(i); 
      menu.add(0, mDevices.keyAt(i), 0, device.getName()); 
     } 

     return true; 
    } 

    @Override 
    public boolean onOptionsItemSelected(MenuItem item) { 
     switch (item.getItemId()) { 
      case R.id.action_scan: 
       mDevices.clear(); 
       startScan(); 
       return true; 
      default: 
       //Obtain the discovered device to connect with 
       BluetoothDevice device = mDevices.get(item.getItemId()); 
       Log.i(TAG, "Connecting to "+device.getName()); 
       /* 
       * Make a connection with the device using the special LE-specific 
       * connectGatt() method, passing in a callback for GATT events 
       */ 
       mConnectedGatt = device.connectGatt(this, false, mGattCallback); 
       //Display progress UI 
       mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Connecting to "+device.getName()+"...")); 
       return super.onOptionsItemSelected(item); 
     } 
    } 

    private void clearDisplayValues() { 
     //mTemperature.setText("---"); 
     mHumidity.setText("---"); 

    } 


    private Runnable mStopRunnable = new Runnable() { 
     @Override 
     public void run() { 
      stopScan(); 
     } 
    }; 
    private Runnable mStartRunnable = new Runnable() { 
     @Override 
     public void run() { 
      startScan(); 
     } 
    }; 

    private void startScan() { 
     mBluetoothAdapter.startLeScan(this); 
     setProgressBarIndeterminateVisibility(true); 

     mHandler.postDelayed(mStopRunnable, 2500); 
    } 

    private void stopScan() { 
     mBluetoothAdapter.stopLeScan(this); 
     setProgressBarIndeterminateVisibility(false); 
    } 

    /* BluetoothAdapter.LeScanCallback */ 

    @Override 
    public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) { 
     Log.i(TAG, "New LE Device: " + device.getName() + " @ " + rssi); 
     /* 
     * We are looking for SensorTag devices only, so validate the name 
     * that each device reports before adding it to our collection 
     */ 
     if (DEVICE_NAME.equals(device.getName())) { 
      mDevices.put(device.hashCode(), device); 
      //Update the overflow menu 
      invalidateOptionsMenu(); 
     } 
    } 

    /* 
    * In this callback, we've created a bit of a state machine to enforce that only 
    * one characteristic be read or written at a time until all of our sensors 
    * are enabled and we are registered to get notifications. 
    */ 

    private BluetoothGattCallback mGattCallback = new BluetoothGattCallback() { 


     private void readNextSensor(BluetoothGatt gatt) { 
      BluetoothGattCharacteristic characteristic; 
        Log.d(TAG, "Reading humidity"); 
        characteristic = gatt.getService(HUMIDITY_SERVICE).getCharacteristic(HUMIDITY_DATA_CHAR); 
      mHandler.sendEmptyMessage(MSG_DISMISS); 
      Log.i(TAG, "All Sensors Enabled"); 
      gatt.readCharacteristic(characteristic); 
     } 

     /* 
     * Enable notification of changes on the data characteristic for each sensor 
     * by writing the ENABLE_NOTIFICATION_VALUE flag to that characteristic's 
     * configuration descriptor. 
     */ 
     private void setNotifyNextSensor(BluetoothGatt gatt) { 
      BluetoothGattCharacteristic characteristic; 
        Log.d(TAG, "Set notify humidity"); 
        characteristic = gatt.getService(HUMIDITY_SERVICE).getCharacteristic(HUMIDITY_DATA_CHAR); 
      mHandler.sendEmptyMessage(MSG_DISMISS); 
      Log.i(TAG, "All Sensors Enabled"); 
      //Enable local notifications 
      gatt.setCharacteristicNotification(characteristic, true); 
      //Enabled remote notifications 
      BluetoothGattDescriptor desc = characteristic.getDescriptor(CONFIG_DESCRIPTOR); 
      desc.setValue(BluetoothGattDescriptor.ENABLE_NOTIFICATION_VALUE); 
      gatt.writeDescriptor(desc); 
     } 



     /* OK */ 

     @Override 
     public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) { 
      Log.d(TAG, "Connection State Change: "+status+" -> "+connectionState(newState)); 
      if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_CONNECTED) { 
       /* 
       * Once successfully connected, we must next discover all the services on the 
       * device before we can read and write their characteristics. 
       */ 
       gatt.discoverServices(); 
       mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Discovering Services...")); 
      } else if (status == BluetoothGatt.GATT_SUCCESS && newState == BluetoothProfile.STATE_DISCONNECTED) { 
       /* 
       * If at any point we disconnect, send a message to clear the weather values 
       * out of the UI 
       */ 
       mHandler.sendEmptyMessage(MSG_CLEAR); 
      } else if (status != BluetoothGatt.GATT_SUCCESS) { 
       /* 
       * If there is a failure at any stage, simply disconnect 
       */ 
       gatt.disconnect(); 
      } 
     } 

     @Override 
     public void onServicesDiscovered(BluetoothGatt gatt, int status) { 
      Log.d(TAG, "Services Discovered: "+status); 
      mHandler.sendMessage(Message.obtain(null, MSG_PROGRESS, "Enabling Sensors...")); 
      /* 
      * With services discovered, we are going to reset our state machine and start 
      * working through the sensors we need to enable 
      */ 
     // enableNextSensor(gatt); 
     readNextSensor(gatt); 
     } 

     @Override 
     public void onCharacteristicRead(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { 
      //For each read, pass the data up to the UI thread to update the display 
      if (HUMIDITY_DATA_CHAR.equals(characteristic.getUuid())) { 
       mHandler.sendMessage(Message.obtain(null, MSG_HUMIDITY, characteristic)); 
      } 

      //After reading the initial value, next we enable notifications 
      setNotifyNextSensor(gatt); 
     } 

     @Override 
     public void onCharacteristicWrite(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, int status) { 
      //After writing the enable flag, next we read the initial value 
      readNextSensor(gatt); 
     } 

     @Override 
     public void onCharacteristicChanged(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic) { 
      /* 
      * After notifications are enabled, all updates from the device on characteristic 
      * value changes will be posted here. Similar to read, we hand these up to the 
      * UI thread to update the display. 
      */ 

      if (HUMIDITY_DATA_CHAR.equals(characteristic.getUuid())) { 
       mHandler.sendMessage(Message.obtain(null, MSG_HUMIDITY, characteristic)); 
      } 

     } 

     @Override 
     public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status) { 
      //Once notifications are enabled, we move to the next sensor and start over with enable 

      readNextSensor(gatt); 
     } 

     @Override 
     public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) { 
      Log.d(TAG, "Remote RSSI: "+rssi); 
     } 

     private String connectionState(int status) { 
      switch (status) { 
       case BluetoothProfile.STATE_CONNECTED: 
        return "Connected"; 
       case BluetoothProfile.STATE_DISCONNECTED: 
        return "Disconnected"; 
       case BluetoothProfile.STATE_CONNECTING: 
        return "Connecting"; 
       case BluetoothProfile.STATE_DISCONNECTING: 
        return "Disconnecting"; 
       default: 
        return String.valueOf(status); 
      } 
     } 
    }; 

    /* 
    * We have a Handler to process event results on the main thread 
    */ 
    private static final int MSG_HUMIDITY = 101; 
    private static final int MSG_PROGRESS = 201; 
    private static final int MSG_DISMISS = 202; 
    private static final int MSG_CLEAR = 301; 
    private Handler mHandler = new Handler() { 
     @Override 
     public void handleMessage(Message msg) { 
      BluetoothGattCharacteristic characteristic; 
      switch (msg.what) { 
       case MSG_HUMIDITY: 
        characteristic = (BluetoothGattCharacteristic) msg.obj; 
        if (characteristic.getValue() == null) { 
         Log.w(TAG, "Error obtaining humidity value"); 
         return; 
        } 
        updateHumidityValues(characteristic); 
        break; 
       case MSG_PROGRESS: 
        mProgress.setMessage((String) msg.obj); 
        if (!mProgress.isShowing()) { 
         mProgress.show(); 
        } 
        break; 
       case MSG_DISMISS: 
        mProgress.hide(); 
        break; 
       case MSG_CLEAR: 
        clearDisplayValues(); 
        break; 
      } 
     } 
    }; 

    /* Methods to extract sensor data and update the UI */ 

    private void updateHumidityValues(BluetoothGattCharacteristic characteristic) { 

     mHumidity.setText(String.valueOf(characteristic)); 

    } 
} 
//   double humidity = SensorTagData.extractHumidity(characteristic); 
//   mHumidity.setText(String.format("%.0f%%", humidity)); 

ответ

2

Значение признака является byte[], а не строка. Когда вы выполняете String.valueOf (character), вы печатаете имя и ссылку объекта в куче, а не фактическое значение.

Что вам нужно сделать, так это преобразовать массив в нечто полезное. Это очень зависит от службы BLE и ее сопутствующей характеристики. Но скажем, что это всего один байт со значением.

/* Methods to extract sensor data and update the UI */ 

private void updateHumidityValues(BluetoothGattCharacteristic characteristic) { 
    short lsb = characteristic.getValue()[0] & 0xff; 
    mHumidity.setText(String.valueOf(lsb)); 

} 
+0

спасибо, брату, я попробую и обновите результат –

+0

Извините за такой глупый вопрос, но как будет выглядеть это в случае 2 байта? ... getValue() [0] & 0xff; –

+0

Я думаю, вы пытаетесь получить ** короткий **, тогда как ваша оценка возвращает ** int **. –

0

Я думаю, вы должны использовать characteristic.getValue() для печати значения характеристики.

т.е.

mHumidity.setText(String.valueOf(characteristic.getValue())); 

И это кэшировать значение, чтобы получить последнее значение, вам может понадобиться вызвать readCharacteristic (характерный).

Пожалуйста, обратитесь этой страница для получения более подробной информации:https://developer.android.com/reference/android/bluetooth/BluetoothGattCharacteristic.html

0

Если вы используете

characteristic.getProperties() 

Это скажут вам, как получить значение более непосредственно. Например, если требуется ваша недвижимость поплавок, вы можете использовать

float char_float_value = characteristic.getFloatValue(BluetoothGattCharacteristic.FORMAT_FLOAT,1); 

Это даст вам значение с плавающей точкой характеристики. Вам просто нужно значение getProperties() int, а затем получить соответствующий FORMAT (Float, int (multiple), string)

Смежные вопросы