I have got following problem.
My application architecture more or less consits of 3 main parts:
- Devices view (shows available BLE devices)
- BLE service (handles BLE connections and data)
- Services view (shows services for particular device)
My issue is with passing BluetoothGATTService to the intent second time (first time it works).
More or less actions are like this:
- choose device, for which you want to show services
- send intent with device and action to perform to the BLEService
- BLEService performs service discovery and sends intent with services back
- BroadcastReceiver receives intent properly and wats to start new activity using data in received intent.
And on the last step there is a problem as I cannot put ArrayList to the intent/bundle as it causes exception:
E/AndroidRuntime: FATAL EXCEPTION: main Process: com.projects.dawid.gattclient, PID: 4133 java.lang.RuntimeException: Parcel: unable to marshal value android.bluetooth.BluetoothGattService@ef62956 at android.os.Parcel.writeValue(Parcel.java:1337) at android.os.Parcel.writeList(Parcel.java:711) at android.os.Parcel.writeValue(Parcel.java:1284) at android.os.Parcel.writeArrayMapInternal(Parcel.java:638) at android.os.BaseBundle.writeToParcelInner(BaseBundle.java:1313) at android.os.Bundle.writeToParcel(Bundle.java:1096) at android.os.Parcel.writeBundle(Parcel.java:663) at android.content.Intent.writeToParcel(Intent.java:7838) at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:2530)
for me it's very very strange, as if the operation is unsupported, then we would get this exception on sending ArrayList of services from BLEService to the BroadcastReceiver, not now.
Source code:
BLEService to Broadcast receiver code
private void notifyServicesDiscovered(BluetoothGatt gatt) {
Intent intent = new Intent();
intent.setAction(BLEService.RESPONSE);
intent.putExtra(BLEService.RESPONSE, BLEService.Responses.SERVICES_DISCOVERED);
intent.putExtra(BLEService.Responses.DEVICE, gatt.getDevice());
intent.putParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST, getArrayListServices(gatt));
LocalBroadcastManager.getInstance(mServiceContext).sendBroadcast(intent);
}
@NonNull
private ArrayList<BluetoothGattService> getArrayListServices(BluetoothGatt gatt) {
ArrayList<BluetoothGattService> services = new ArrayList<>();
services.addAll(gatt.getServices());
return services;
}
This works fine. Now
Broadcast receiver to new activity code
After recognizing the proper intent to handle this method is invoked
private void createViewWithServices(Intent intent) {
Log.i(TAG, "creating new activity!");
BluetoothDevice device = intent.getParcelableExtra(BLEService.Responses.DEVICE);
ArrayList<BluetoothGattService> services = intent.getParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST);
Intent serviceShowIntent = new Intent(mActivityContext, ServiceShowActivity.class);
serviceShowIntent.putExtra(BLEService.Responses.DEVICE, device);
serviceShowIntent.putParcelableArrayListExtra(BLEService.Responses.SERVICES_LIST, services); //this line causes error
mActivityContext.startActivity(serviceShowIntent); // here exception is thrown
}
Can anyone explain me the mistery lying behind this? I just cannot understand why first code is just fine, while second fails with exception.
Already tried doing things in lots of different ways, but all of them failed. I was even exchanging bundles between intents as their contents are same, but this also failed, copying list items makes no difference.
EDIT
refering to the AndroidRuntime error: Parcel: unable to marshal value error. Difference is, that I am using objects of classes provided by android itself, that is BluetoothGATTService, which do implement parcelable interface refering to the https://developer.android.com/reference/android/bluetooth/BluetoothGattService.html