1

Я новый разработчик Android, и я пытаюсь отправить данные с помощью BLE 4.3, основанный на примере проекта Gatt android.Ошибка исключения исключающего указателя при отправке признака BLE android

Я использую характеристики, чтобы поместить данные, которые я хочу передать.

Когда я пытаюсь передать, я использую третью службу в списке DeviceControlActivity проекта, появляется текстовое диалоговое окно для ввода текста. Когда я нажимаю OK, идея заключается в том, чтобы начать передачу, но я получаю ошибку NullPointerException.

Я не знаю, почему возникает эта ошибка и как я могу ее решить.

Это мой полный код, если это полезно

package com.example.blem; 

public class DeviceControlActivity extends Activity { 

public static final String EXTRAS_DEVICE_NAME = "DEVICE_NAME"; 
public static final String EXTRAS_DEVICE_ADDRESS = "DEVICE_ADDRESS"; 

private TextView mConnectionState; 
private TextView mDataField; 
private TextView mRssiField; 
private String mDeviceName; 
private String mDeviceAddress; 
private ExpandableListView mGattServicesList; 
private BluetoothLeService mBluetoothLeService; 
private ArrayList<ArrayList<BluetoothGattCharacteristic>> mGattCharacteristics = 
     new ArrayList<ArrayList<BluetoothGattCharacteristic>>(); 
private boolean mConnected = false; 
private BluetoothGattCharacteristic mNotifyCharacteristic; 
private BluetoothGattCharacteristic mWriteCharacteristic; 
Button Escritor; 
byte hello []={0}; 

private final String LIST_NAME = "NAME"; 
private final String LIST_UUID = "UUID"; 

BluetoothGattCharacteristic characteristic; 

public BluetoothGatt mBluetoothGatt; 
// Code to manage Service lifecycle. 
private final ServiceConnection mServiceConnection = new ServiceConnection() { 

    @Override 
    public void onServiceConnected(ComponentName componentName, IBinder service) { 
     mBluetoothLeService = ((BluetoothLeService.LocalBinder) service).getService(); 
     if (!mBluetoothLeService.initialize()) { 
      Log.e("Unable to initialize Bluetooth"); 
      finish(); 
     } 
     // Automatically connects to the device upon successful start-up initialization. 
     mBluetoothLeService.connect(mDeviceAddress); 
     mBluetoothLeService.setBLEServiceCb(mDCServiceCb); 
    } 

    @Override 
    public void onServiceDisconnected(ComponentName componentName) { 
     mBluetoothLeService = null; 
    } 
}; 

// If a given GATT characteristic is selected, check for supported features. This sample 
// demonstrates 'Read' and 'Notify' features. See 
// http://d.android.com/reference/android/bluetooth/BluetoothGatt.html for the complete 
// list of supported characteristic features. 
private final ExpandableListView.OnChildClickListener servicesListClickListner = 
     new ExpandableListView.OnChildClickListener() { 
      @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 
      @Override 
      public boolean onChildClick(ExpandableListView parent, View v, int groupPosition, 
             int childPosition, long id) { 
       if (mGattCharacteristics != null) { 
        final BluetoothGattCharacteristic characteristic = 
          mGattCharacteristics.get(groupPosition).get(childPosition); 
        final int charaProp = characteristic.getProperties(); 
        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_READ) > 0) { 
         // If there is an active notification on a characteristic, clear 
         // it first so it doesn't update the data field on the user interface. 
         Log.d("BluetoothGattCharacteristic has PROPERTY_READ, so send read request"); 

         if (mNotifyCharacteristic != null) { 
          mBluetoothLeService.setCharacteristicNotification(
            mNotifyCharacteristic, false); 
          mNotifyCharacteristic = null; 
         } 
         mBluetoothLeService.readCharacteristic(characteristic); 
        } 

        if ((charaProp & BluetoothGattCharacteristic.PROPERTY_NOTIFY) > 0) { 
         Log.d("BluetoothGattCharacteristic has PROPERTY_NOTIFY, so send notify request"); 

         mNotifyCharacteristic = characteristic; 
         mBluetoothLeService.setCharacteristicNotification(
           characteristic, true); 
        } 

        if (((charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE) | 
          (charaProp & BluetoothGattCharacteristic.PROPERTY_WRITE_NO_RESPONSE)) > 0) { 
         Log.d("BluetoothGattCharacteristic has PROPERY_WRITE | PROPERTY_WRITE_NO_RESPONSE"); 

         mWriteCharacteristic = characteristic; 
         // popup an dialog to write something. 
         showCharactWriteDialog(); 
        } 
        return true; 
       } 
       return false; 
      } 
}; 

private void showCharactWriteDialog() { 
    DialogFragment newFrame = new BleCharacterDialogFragment(); 
    newFrame.show(getFragmentManager(), "blewrite"); 
} 

private void clearUI() { 
    mGattServicesList.setAdapter((SimpleExpandableListAdapter) null); 
    mDataField.setText(R.string.no_data); 
} 

@TargetApi(Build.VERSION_CODES.HONEYCOMB) 
@Override 
public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.gatt_services_characteristics); 

    final Intent intent = getIntent(); 
    mDeviceName = intent.getStringExtra(EXTRAS_DEVICE_NAME); 
    mDeviceAddress = intent.getStringExtra(EXTRAS_DEVICE_ADDRESS); 

    // Sets up UI references. 
    ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress); 
    mGattServicesList = (ExpandableListView) findViewById(R.id.gatt_services_list); 
    mGattServicesList.setOnChildClickListener(servicesListClickListner); 
    mConnectionState = (TextView) findViewById(R.id.connection_state); 
    mDataField = (TextView) findViewById(R.id.data_value); 
    mRssiField = (TextView) findViewById(R.id.signal_rssi); 

    //Escritor = (Button) findViewById(R.id.escrito); 

    /*Escritor.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 

      characteristic.setValue(new byte[] {(byte) 0xFF}); 
      writeCharacteristicValue(characteristic); 

      Toast.makeText(getApplicationContext(), "Se envío el dato", 
        Toast.LENGTH_SHORT).show(); 

      return; 
     } 
    });*/ 

    getActionBar().setTitle(mDeviceName); 
    getActionBar().setDisplayHomeAsUpEnabled(true); 
    Intent gattServiceIntent = new Intent(this, BluetoothLeService.class); 
    bindService(gattServiceIntent, mServiceConnection, BIND_AUTO_CREATE); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    //registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); 
    if (mBluetoothLeService != null) { 
     final boolean result = mBluetoothLeService.connect(mDeviceAddress); 
     Log.d("Connect request result=" + result); 
    } 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
    //unregisterReceiver(mGattUpdateReceiver); 
} 

@Override 
protected void onDestroy() { 
    super.onDestroy(); 
    unbindService(mServiceConnection); 
    mBluetoothLeService = null; 
} 

@Override 
public boolean onCreateOptionsMenu(Menu menu) { 
    getMenuInflater().inflate(R.menu.gatt_services, menu); 
    if (mConnected) { 
     menu.findItem(R.id.menu_connect).setVisible(false); 
     menu.findItem(R.id.menu_disconnect).setVisible(true); 
    } else { 
     menu.findItem(R.id.menu_connect).setVisible(true); 
     menu.findItem(R.id.menu_disconnect).setVisible(false); 
    } 
    return true; 
} 

@TargetApi(Build.VERSION_CODES.ECLAIR) 
@Override 
public boolean onOptionsItemSelected(MenuItem item) { 
    switch(item.getItemId()) { 
     case R.id.menu_connect: 
      mBluetoothLeService.connect(mDeviceAddress); 
      return true; 
     case R.id.menu_disconnect: 
      mBluetoothLeService.disconnect(); 
      return true; 
     case android.R.id.home: 
      onBackPressed(); 
      return true; 
    } 
    return super.onOptionsItemSelected(item); 
} 

private void updateConnectionState(final int resourceId) { 
    runOnUiThread(new Runnable() { 
     @Override 
     public void run() { 
      mConnectionState.setText(resourceId); 
     } 
    }); 
} 

private void displayData(String data) { 
    if (data != null) { 
     mDataField.setText(data); 
    } 
} 

private void displayRssi(String rssi) { 
    if (rssi != null) { 
     //Log.d("-- dispaly Rssi: " + rssi); 
     mRssiField.setText(rssi); 
    } 
} 
// Demonstrates how to iterate through the supported GATT Services/Characteristics. 
// In this sample, we populate the data structure that is bound to the ExpandableListView 
// on the UI. 
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR2) 
private void displayGattServices(List<BluetoothGattService> gattServices) { 
    Log.d("displayGATTServices"); 

    if (gattServices == null) return; 
    String uuid = null; 
    String unknownServiceString = getResources().getString(R.string.unknown_service); 
    String unknownCharaString = getResources().getString(R.string.unknown_characteristic); 
    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>(); 
    ArrayList<ArrayList<HashMap<String, String>>> gattCharacteristicData 
      = new ArrayList<ArrayList<HashMap<String, String>>>(); 
    mGattCharacteristics = new ArrayList<ArrayList<BluetoothGattCharacteristic>>(); 

    // Loops through available GATT Services. 
    for (BluetoothGattService gattService : gattServices) { 
     HashMap<String, String> currentServiceData = new HashMap<String, String>(); 
     uuid = gattService.getUuid().toString(); 
     currentServiceData.put(
       LIST_NAME, SampleGattAttributes.lookup(uuid, unknownServiceString)); 
     currentServiceData.put(LIST_UUID, uuid); 
     gattServiceData.add(currentServiceData); 

     ArrayList<HashMap<String, String>> gattCharacteristicGroupData = 
       new ArrayList<HashMap<String, String>>(); 
     List<BluetoothGattCharacteristic> gattCharacteristics = 
       gattService.getCharacteristics(); 
     ArrayList<BluetoothGattCharacteristic> charas = 
       new ArrayList<BluetoothGattCharacteristic>(); 

     // Loops through available Characteristics. 
     for (BluetoothGattCharacteristic gattCharacteristic : gattCharacteristics) { 
      charas.add(gattCharacteristic); 
      HashMap<String, String> currentCharaData = new HashMap<String, String>(); 
      uuid = gattCharacteristic.getUuid().toString(); 
      currentCharaData.put(
        LIST_NAME, SampleGattAttributes.lookup(uuid, unknownCharaString)); 
      currentCharaData.put(LIST_UUID, uuid); 
      gattCharacteristicGroupData.add(currentCharaData); 
     } 
     mGattCharacteristics.add(charas); 
     gattCharacteristicData.add(gattCharacteristicGroupData); 
    } 

    SimpleExpandableListAdapter gattServiceAdapter = new SimpleExpandableListAdapter(
      this, 
      gattServiceData, 
      android.R.layout.simple_expandable_list_item_2, 
      new String[] {LIST_NAME, LIST_UUID}, 
      new int[] { android.R.id.text1, android.R.id.text2 }, 
      gattCharacteristicData, 
      android.R.layout.simple_expandable_list_item_2, 
      new String[] {LIST_NAME, LIST_UUID}, 
      new int[] { android.R.id.text1, android.R.id.text2 } 
    ); 
    mGattServicesList.setAdapter(gattServiceAdapter); 
} 

private DCServiceCb mDCServiceCb = new DCServiceCb(); 

public class DCServiceCb implements BluetoothLeService.BLEServiceCallback { 

    @Override 
    public void displayRssi(final int rssi) { 
     runOnUiThread(new Runnable() { 
       @Override 
       public void run() { 
        DeviceControlActivity.this.displayRssi(String.valueOf(rssi)); 
       } 
      } 
     ); 
    } 

    @Override 
    public void displayData(final String data) { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       DeviceControlActivity.this.displayData(data); 
      } 
     }); 
    } 

    @Override 
    public void notifyConnectedGATT() { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       mConnected = true; 
       updateConnectionState(R.string.connected); 
       invalidateOptionsMenu(); 
      } 
     }); 
    } 

    @Override 
    public void notifyDisconnectedGATT() { 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       mConnected = false; 
       updateConnectionState(R.string.disconnected); 
       invalidateOptionsMenu(); 
       clearUI(); 
      } 
     }); 
    } 

    @Override 
    public void displayGATTServices() { 
     Log.d("displayGATTServices."); 
     runOnUiThread(new Runnable() { 
      @Override 
      public void run() { 
       if (mBluetoothLeService != null) { 
        DeviceControlActivity.this.displayGattServices(
          mBluetoothLeService.getSupportedGattServices()); 
       } 
      } 
     }); 
    } 
} 

@SuppressLint("ValidFragment") 
public class BleCharacterDialogFragment extends DialogFragment { 

    @Override 
    public View onCreateView(LayoutInflater inflater, ViewGroup container, 
          Bundle savedInstanceState) { 
     View v = inflater.inflate(R.layout.write_charact_dialog, container, false); 
     final EditText ed = (EditText) v.findViewById(R.id.charact_value); 
     Button ok = (Button) v.findViewById(R.id.dialog_confirm); 
     Button cancel = (Button) v.findViewById(R.id.dialog_cancel); 

     ok.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       characteristic.setValue(hello); 
       //characteristic.setValue("FF"); 
       //characteristic.setValue(new byte[] {(byte) 0xFF}); 
       writeCharacteristicValue(characteristic); 

       Toast.makeText(getApplicationContext(), "Se envío el dato", 
         Toast.LENGTH_SHORT).show(); 
       dismiss(); 
       return; 
      } 
     }); 

     cancel.setOnClickListener(new View.OnClickListener() { 
      @Override 
      public void onClick(View v) { 
       dismiss(); 
      } 
     }); 

     return v; 
    } 
} 

public void writeCharacteristicValue(BluetoothGattCharacteristic characteristica) 
{ 
    byte[] value= {(byte) 0xFF}; 
    characteristica.setValue(bytesToHex(value)); 
    boolean status = mBluetoothGatt.writeCharacteristic(characteristica); 
} 

final protected static char[] hexArray = "ABCDEF".toCharArray(); 

public String bytesToHex(byte[] bytes) 
{ 
    char[] hexChars = new char[bytes.length * 2]; 
    int v; 
    for (int j = 0; j < bytes.length; j++) 
    { 
     v = bytes[j] & 0xFF; 
     hexChars[j * 2] = hexArray[v >>> 4]; 
     hexChars[j * 2 + 1] = hexArray[v & 0x0F]; 
    } 
    return new String(hexChars); 
} 

}

Может кто-нибудь сказать, что я делаю неправильно?

Спасибо за заранее

+2

Посмотрите на стек и посмотрите причину, вызванную частью. – Raghunandan

ответ

0

без трассировки стека это невозможно по-настоящему отладки, но от взглядов его вы не используете onServicesDiscovered() и onCharacteristicRead() обратных вызовов ждать всех служб и соответствующих характеристик быть читайте, чтобы вы понятия не имели, когда происходят эти события и, следовательно, они могут продолжить