I am just learning how to develop for Android Wear, I have created a full screen Activity for Smart Watches and in my mobile part of the application I get some JSON data and cre
In my app I've created a lightweight class, specially for sending it from phone to watch. Because the code is shared between mobile and wearable parts of app it can be easily packed and restored on both devices without code duplication. It provides Bundle
-like mechanism, but using DataMap
.
Sample implementation:
public class MyObject {
public final long itemId;
public final long sortOrder;
public final String priceString;
public MyObject(long itemId, long sortOrder, String priceString) {
this.itemId = itemId;
this.sortOrder = sortOrder;
this.priceString = priceString;
}
public MyObject(DataMap map) {
this(map.getLong("itemId"),
map.getLong("sortOrder"),
map.getString("priceString")
);
}
public DataMap putToDataMap(DataMap map) {
map.putLong("itemId", itemId);
map.putLong("sortOrder", sortOrder);
map.putString("priceString", priceString);
return map;
}
}
Writing such class will let you consider the what actually needs to be send between devices to send as little as possible. It will also not break when any field will be added or removed (in oppose to the next solution).
If you don't want to write the new class and want to reuse your existing code you can try to use the code below. It will let you stay with only Parcelable
interface (without need to implement Serializable
interface). I haven't tested it while sending across devices but it successes to marshall()
and unmarshall()
byte array to/from Parcel and store it in DataMap
.
NOTE: I don't know exactly how Google Play Services hold all these DataApi
data, but I'm afraid that something may break when such class will be updated.
For example the class will be updated on Android Wear, user will launch the app that would try to read the current data from DataApi
(that was "serialized" using old version of this class) and try to read it from byte[]
as if it was updated version. These concerns should be tested, but I don't think that they made DataApi
so primitive "just because" or to make harder to develop apps on Wear.
I strongly recommend to use Bundle
-like solution and to not use the Parcelable
solution.
Use this at your own risk.
import android.os.Parcel;
import android.os.Parcelable;
import com.google.android.gms.wearable.DataMap;
/**
* <p>Allows to put and get {@link Parcelable} objects into {@link DataMap}</p>
* <b>USAGE:</b>
* <p>
* <b>Store object in DataMap:</b><br/>
* DataMapParcelableUtils.putParcelable(dataMap, "KEY", myParcelableObject);
* </p><p>
* <b>Restore object from DataMap:</b><br/>
* myParcelableObject = DataMapParcelableUtils.getParcelable(dataMap, "KEY", MyParcelableObject.CREATOR);
* </p>
* I do <b>not recommend</b> to use this method - it may fail when the class that implements {@link Parcelable} would be updated. Use it at your own risk.
* @author Maciej Ciemięga
*/
public class DataMapParcelableUtils {
public static void putParcelable(DataMap dataMap, String key, Parcelable parcelable) {
final Parcel parcel = Parcel.obtain();
parcelable.writeToParcel(parcel, 0);
parcel.setDataPosition(0);
dataMap.putByteArray(key, parcel.marshall());
parcel.recycle();
}
public static <T> T getParcelable(DataMap dataMap, String key, Parcelable.Creator<T> creator) {
final byte[] byteArray = dataMap.getByteArray(key);
final Parcel parcel = Parcel.obtain();
parcel.unmarshall(byteArray, 0, byteArray.length);
parcel.setDataPosition(0);
final T object = creator.createFromParcel(parcel);
parcel.recycle();
return object;
}
}
The code is also available on GitHub.