Reputation: 13
I am developing an app that lets the user connect to a BLE device, and then after reading 20 values from the BLE peripheral, it moves to a new activity/screen where I make an image out of the 20 values that I read. I want to then be able to read a new set of 20 values but without leaving the screen that is showing the image. How can I achieve this?
In the activity where I read BLE characteristics, I have this function:
public class BluetoothLeService extends Service {
private final static String TAG = BluetoothLeService.class.getSimpleName();
....
public int read_counter = 0;
public int measurement_arr[] = new int[20];
// Implements callback methods for GATT events that the app cares about. For example,
// connection change and services discovered.
private final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
....
@Override
public void onCharacteristicRead(BluetoothGatt gatt,
BluetoothGattCharacteristic characteristic,
int status) {
if (status == BluetoothGatt.GATT_SUCCESS) { // IF THE READ OPERATION WAS SUCCESSFUL.
broadcastUpdate(ACTION_DATA_AVAILABLE, characteristic);
}
}
public void readCharacteristic(BluetoothGattCharacteristic characteristic) {
if (mBluetoothAdapter == null || mBluetoothGatt == null) {
Log.w(TAG, "BluetoothAdapter not initialized");
return;
}
mBluetoothGatt.readCharacteristic(characteristic);
}
....
private void broadcastUpdate(final String action,
final BluetoothGattCharacteristic characteristic) {
final Intent intent = new Intent(action);
final byte[] data = characteristic.getValue(); // data is presented as a byte array over BLE characteristics.
measurement_arr[read_counter] = (int) data[0]; // Read data byte.
// Use hex formatting.
if (data != null && data.length > 0) {
final StringBuilder stringBuilder = new StringBuilder(data.length);
for(byte byteChar : data)
stringBuilder.append(String.format("%02X ", byteChar));
intent.putExtra(EXTRA_DATA, new String(data) + "\n" + stringBuilder.toString()); // THIS IS WHERE DATA IS BEING READ.
}
read_counter += 1; // after value read, increment the count.
if (read_counter < 20){ // Receive 20 packets of data.
Log.d("MEASUREMENT", "Reading new characteristic");
readCharacteristic(characteristic);
}
else {
Log.d("Finished BLE read", "Moving to next activity.");
read_counter = 0;
// Go to next activity where we show image.
Intent show_image = new Intent(this, Reconstruction.class);
show_image.putExtra("myArr", measurement_arr); // Go to acivity where we reconstruct image.
show_image.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(show_image);
}
sendBroadcast(intent);
}
My 2nd activity, which displays the image using a Canvas then has the following code.
public class Reconstruction extends AppCompatActivity {
public int data[] = new int[20];
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(new MyView(this));
// Get Bundle object that contain the array
Bundle extras = getIntent().getExtras();
// Extract the array from the Bundle object
data = extras.getIntArray("myArr");
// Output the array
for(int item:data){
Log.i("2nd_ACTIVITY", String.valueOf(item));
}
}
public class MyView extends View
{
Paint paint = null;
public MyView(Context context)
{
super(context);
paint = new Paint();
}
@Override
protected void onDraw(Canvas canvas)
{
... make image
...After making the image, how do I go back to the readCharacteristic function from the previous activity, but without changing what the display is showing?
}
}
}
I have read online some things about passing the context of my second activity to the first, but I don't quite understand this, and I am also not quite sure how Context works.
Upvotes: 1
Views: 190
Reputation: 1567
Don't use a link to the activity inside another activity. It can lead to memory leak.
Regarding your question, you can use Broadcast receivers to communicate between activities or use a Service which will communicate with your BLE device
Simple usage of Broadcast Receiver:
class YourActivity extends Activity {
private BroadcastReceiver mMyReceiver;
protected void onCreate(Bundle data) {
...
mMyReceiver = new MyReceiver();
}
public void onStart() {
registerReceiver(mMyReceiver, new IntentFilter("your action"));
}
public void onStop() {
unregisterReceiver(mMyReceiver);
}
public void onDestroy() {
mMyReceiver = null;
}
// Inner class has a link to YourActivity instance
private class MyReceiver extends BroadcastReceiver {
public void onReceive(Intent intent) {
// procces messages here
}
}
}
// Calling:
context.sendBroadcast(new Intent("your action"));
Upvotes: 1