¿Puedo enviar objetos personalizados a Android Wear?
Estoy aprendiendo cómo desarrollar para Android Wear, he creado una actividad de pantalla completa para relojes inteligentes y en mi parte móvil de la aplicación obtengo algunos datos de JSON y crear una lista de objetos personalizados a partir de esto.
En mi aplicación para móviles, muestro la información de estos objetos en un ListView.
- ¿Está utilizando Serializable en Android mal?
- Fragmento se bloquea con el paquete: no se puede marshal error de valor cuando onPause método se llama
- Cómo detener ProGuard de eliminar la interfaz Serializable de una clase
- Android ArrayList de objetos personalizados - Guardar en SharedPreferences - Serializable?
- Estado de restauración después de que el proceso se destruye
En la parte de desgaste de mi aplicación quiero mostrar una versión limitada de esta lista, por ejemplo, los 3 primeros de la lista se mostrará en mi aplicación de pantalla completa en el Wearable.
Mi problema es que no parece ser una forma de enviar objetos parcelables a Android Wear, no hay opción para ponerParcelable en el DataItem.
Parece que la única opción es enviar un objeto en bytes, como esto:
public void sendWearableData(GoogleApiClient aGoogleApiClient, ArrayList<MyObject> myObjectList, String path) { googleApiClient = aGoogleApiClient; byte[] testBytes = new byte[0]; if (googleApiClient.isConnected()) { PutDataMapRequest dataMapRequest = PutDataMapRequest.create(path); try { testBytes = BytesUtils.toByteArray(myObjectList); } catch (IOException e) { e.printStackTrace(); } dataMapRequest.getDataMap().putByteArray(Constants.TEST_KEY, testBytes); PutDataRequest request = dataMapRequest.asPutDataRequest(); Wearable.DataApi.putDataItem(googleApiClient, request); } }
Así que tengo que convertir mi objeto en bytes, enviarlo a Android Wear y convertirlo de nuevo? Esto significa que mis objetos que he implementado Parcelable en para que pueda enviarlos a través de Intents ahora también necesitan implementar Serializable, es esto correcto o hay una mejor manera de hacerlo?
- ArrayList no se puede convertir en clase personalizada extendiendo ArrayList
- Casting objetos a subclases de una superclase Parcelable?
- Problema serializable de Android
- Pasar argumento entre Actividades - nulo
- Objeto serializable en la intención que devuelve como String
- Persistencia de un objeto Parcelable en Android
- Cómo pasar un socket Bluetooth a otra actividad mediante la interfaz de la aplicación
- Android: guarda datos parcelables en un archivo
Solución tipo paquete:
En mi aplicación he creado una clase ligera, especialmente para enviarla de teléfono a ver. Debido a que el código se comparte entre partes móviles y usables de la aplicación, puede ser fácilmente embalado y restaurado en ambos dispositivos sin duplicación de código. Proporciona Bundle
como mecanismo, pero utilizando DataMap
.
Ejemplo de implementación:
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; } }
La escritura de esa clase le permitirá considerar lo que realmente necesita ser enviado entre dispositivos para enviar lo menos posible. También no se romperá cuando se agregue o se quite cualquier campo (en oposición a la siguiente solución).
Respondiendo a sus preocupaciones Parcelable:
Si no desea escribir la nueva clase y desea volver a utilizar su código existente, puede intentar utilizar el código siguiente. Le permitirá permanecer con sólo interfaz Parcelable
(sin necesidad de implementar la interfaz Serializable
). No lo he probado mientras que envié a través de dispositivos pero éxitos a marshall()
y el unmarshall()
arsenal del byte a / de paquete y lo almacena en DataMap
.
NOTA: No sé exactamente cómo los Servicios de Google Play contienen todos estos datos de DataApi
, pero me temo que algo se puede romper cuando se actualice dicha clase.
Por ejemplo, la clase se actualizará en Android Wear, el usuario lanzará la aplicación que intentaría leer los datos actuales de DataApi
(que fue "serializada" usando la versión antigua de esta clase) e intentar leerla desde byte[]
como si Se actualizó la versión. Estas preocupaciones deben ser probadas, pero no creo que hicieron DataApi
tan primitivo "sólo porque" o hacer más difícil desarrollar aplicaciones en Wear.
Recomiendo encarecidamente el uso de la solución Bundle
like y no utilizar la solución Parcelable
.
Usa esto bajo tu propio riesgo.
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; } }
El código también está disponible en GitHub .
- Cómo emular una etiqueta nfc en un teléfono Android
- Android Tamaño de diálogo de tamaño fijo: ¿Qué es Major & Minor?