1

Je suis nouveau au développement d'applications Android, et c'est ma première tentative d'obtenir un périphérique Android pour parler à un périphérique BLE (qui va parler à un microcontrôleur). Le but est d'envoyer une valeur, dans ce cas la chaîne "verte" ou "bleue" convertie en octets, pour indiquer au microcontrôleur d'allumer une LED.Android BLE NullPointerException en essayant d'écrire caractéristique

Comme je ne connais pas bien le Bluetooth, j'ai cherché en ligne plusieurs sources pour aider à mettre du code ensemble. Maintenant, quand j'arrive au point où je suis connecté à un appareil et tenter d'envoyer un signal, je reçois ce code d'erreur:

java.lang.NullPointerException: Tentative d'invoquer la méthode virtuelle « android.bluetooth booléenne .BluetoothGattCharacteristic.setValue (byte []) 'sur une référence d'objet null à com.example.andres.battle_bots.DeviceControlActivity.makeChange (DeviceControlActivity.java:366) sur com.example.andres.battle_bots.DeviceControlActivity.access $ 800 (DeviceControlActivity. java: 52) à com.example.andres.battle_bots.DeviceControlActivity $ 3.onClick (DeviceControlActivity.java:151)

I Je ne sais pas exactement ce qui me manque, puisque j'instancie les variables que j'utilise avant de les utiliser et l'exception est toujours levée. Il y a la possibilité que je ne comprenne pas le code que j'adapte. J'ai jusqu'ici 2 activités, DeviceScanActivity, qui analyse les périphériques et les connexions, et DeviceControlActivity, qui est l'endroit où l'interaction principale du périphérique se produit et l'erreur se produit. Voici le code:

import android.app.Activity; 
import android.bluetooth.BluetoothGattCharacteristic; 
import android.bluetooth.BluetoothGattService; 
import android.content.BroadcastReceiver; 
import android.content.ComponentName; 
import android.content.Context; 
import android.content.Intent; 
import android.content.IntentFilter; 
import android.content.ServiceConnection; 
import android.os.Bundle; 
import android.os.IBinder; 
import android.util.Log; 
import android.view.Menu; 
import android.view.MenuItem; 
import android.view.View; 
import android.widget.ExpandableListView; 
import android.widget.ImageButton; 
import android.widget.SeekBar; 
import android.widget.SimpleExpandableListAdapter; 
import android.widget.TextView; 

import java.util.ArrayList; 
import java.util.HashMap; 
import java.util.List; 
import java.util.UUID; 



public class DeviceControlActivity extends Activity { 
private final static String TAG = DeviceControlActivity.class.getSimpleName(); 

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

private int[] RGBFrame = {0, 0, 0}; 
private TextView isSerial; 
private TextView mConnectionState; 
private TextView mDataField; 
private String mDeviceName; 
private String mDeviceAddress; 
// private ExpandableListView mGattServicesList; 
private BluetoothLeService mBluetoothLeService; 
private boolean mConnected = false; 
private BluetoothGattCharacteristic characteristicTX; 
private BluetoothGattCharacteristic characteristicRX; 


public final static UUID HM_RX_TX = 
     UUID.fromString(SampleGattAttributes.HM_RX_TX); 

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

// 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(TAG, "Unable to initialize Bluetooth"); 
      finish(); 
     } 
     // Automatically connects to the device upon successful start-up initialization. 
     mBluetoothLeService.connect(mDeviceAddress); 
    } 

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

// Handles various events fired by the Service. 
// ACTION_GATT_CONNECTED: connected to a GATT server. 
// ACTION_GATT_DISCONNECTED: disconnected from a GATT server. 
// ACTION_GATT_SERVICES_DISCOVERED: discovered GATT services. 
// ACTION_DATA_AVAILABLE: received data from the device. This can be a result of read 
//      or notification operations. 
private final BroadcastReceiver mGattUpdateReceiver = new BroadcastReceiver() { 
    @Override 
    public void onReceive(Context context, Intent intent) { 
     final String action = intent.getAction(); 
     if (BluetoothLeService.ACTION_GATT_CONNECTED.equals(action)) { 
      mConnected = true; 
      updateConnectionState(R.string.connected); 
      invalidateOptionsMenu(); 
     } else if (BluetoothLeService.ACTION_GATT_DISCONNECTED.equals(action)) { 
      mConnected = false; 
      updateConnectionState(R.string.disconnected); 
      invalidateOptionsMenu(); 
      clearUI(); 
     } else if (BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED.equals(action)) { 
      // Show all the supported services and characteristics on the user interface. 
      displayGattServices(mBluetoothLeService.getSupportedGattServices()); 
     } else if (BluetoothLeService.ACTION_DATA_AVAILABLE.equals(action)) { 
      displayData(intent.getStringExtra(mBluetoothLeService.EXTRA_DATA)); 
     } 
    } 
}; 

private void clearUI() { 
//  mDataField.setText(R.string.no_data); 
} 

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

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

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

    ImageButton U1 = (ImageButton) findViewById(R.id.up_btn1); 
    U1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
      if(mBluetoothLeService != null) { 
       String codeGreen = "green"; 
       makeChange(codeGreen); 
      } 
     } 
    }); 

    ImageButton R1 = (ImageButton) findViewById(R.id.right_btn1); 
    R1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    ImageButton D1 = (ImageButton) findViewById(R.id.down_btn1); 
    D1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    ImageButton L1 = (ImageButton) findViewById(R.id.left_btn1); 
    L1.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    ImageButton U2 = (ImageButton) findViewById(R.id.up_btn2); 
    U2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      if(mBluetoothLeService != null) { 
       String codeBlue = "blue"; 
       makeChange(codeBlue); 
      } 
     } 
    }); 

    ImageButton R2 = (ImageButton) findViewById(R.id.right_btn2); 
    R2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    ImageButton D2 = (ImageButton) findViewById(R.id.down_btn2); 
    D2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    ImageButton L2 = (ImageButton) findViewById(R.id.left_btn2); 
    L2.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    ImageButton BLE = (ImageButton) findViewById(R.id.ble_btn); 
    BLE.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
      Intent intent = new Intent(DeviceControlActivity.this, com.example.andres.battle_bots.DeviceScanActivity.class); 
      startActivity(intent); 
     } 
    }); 

    ImageButton Options = (ImageButton) findViewById(R.id.options_btn); 
    Options.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View view) { 
      //Do something with Bluetooth 
     } 
    }); 

    // Sets up UI references. 
    // ((TextView) findViewById(R.id.device_address)).setText(mDeviceAddress); 
    // mConnectionState = (TextView) findViewById(R.id.connection_state); 
    // is serial present? 
    // isSerial = (TextView) findViewById(R.id.isSerial); 
/* 
    mDataField = (TextView) findViewById(R.id.data_value); 
    mRed = (SeekBar) findViewById(R.id.seekRed); 
    mGreen = (SeekBar) findViewById(R.id.seekGreen); 
    mBlue = (SeekBar) findViewById(R.id.seekBlue); 

    readSeek(mRed, 0); 
    readSeek(mGreen, 1); 
    readSeek(mBlue, 2); 
*/ 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
    registerReceiver(mGattUpdateReceiver, makeGattUpdateIntentFilter()); 
    if (mBluetoothLeService != null) { 
     final boolean result = mBluetoothLeService.connect(mDeviceAddress); 
     Log.d(TAG, "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; 
} 

@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); 
    } 
} 


// 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. 
private void displayGattServices(List<BluetoothGattService> gattServices) { 
    if (gattServices == null) return; 
    String uuid = null; 
    String unknownServiceString = getResources().getString(R.string.unknown_service); 
    ArrayList<HashMap<String, String>> gattServiceData = new ArrayList<HashMap<String, String>>(); 


    // 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)); 

     // If the service exists for HM 10 Serial, say so. 
     if (SampleGattAttributes.lookup(uuid, unknownServiceString) == "HM 10 Serial") { 
//    isSerial.setText("Yes, serial :-)"); 
     } else { 
//    isSerial.setText("No, serial :-("); 
     } 
     currentServiceData.put(LIST_UUID, uuid); 
     gattServiceData.add(currentServiceData); 

     // get characteristic when UUID matches RX/TX UUID 
     characteristicTX = gattService.getCharacteristic(BluetoothLeService.UUID_HM_RX_TX); 
     characteristicRX = gattService.getCharacteristic(BluetoothLeService.UUID_HM_RX_TX); 
    } 

} 

private static IntentFilter makeGattUpdateIntentFilter() { 
    final IntentFilter intentFilter = new IntentFilter(); 
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_CONNECTED); 
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_DISCONNECTED); 
    intentFilter.addAction(BluetoothLeService.ACTION_GATT_SERVICES_DISCOVERED); 
    intentFilter.addAction(BluetoothLeService.ACTION_DATA_AVAILABLE); 
    return intentFilter; 
} 

// on change of bars write char 
private void makeChange(String str) { 
    Log.d(TAG, "Sending result=" + str); 
    final byte[] tx = str.getBytes(); 
    if (mConnected) { 
     characteristicTX.setValue(tx); 
     mBluetoothLeService.writeCharacteristic(characteristicTX); 
     mBluetoothLeService.setCharacteristicNotification(characteristicRX, true); 
     Log.d(TAG,"Success"); 
    } 
    else 
    { 
     Log.d(TAG,"Failed"); 
    } 
} 
} 

Toute aide est grandement appréciée. Vous seriez certainement en train de me faciliter la vie, et je pourrais aider d'autres personnes qui se lancent dans le développement Android/Bluetooth. Merci!

Répondre

0

Il s'avère que mes caractéristiques étaient nulles puisque l'UUID que j'ai reçu du service n'était pas égal à ce que j'attendais. Une fois que j'ai édité l'exemple de code pour attendre l'UUID associé au module bluetooth que j'utilisais, le code a fonctionné.