我可以将自定义对象发送到Android Wear吗?

Don*_*rty 12 android serializable parcelable android-wear-data-api wear-os

我刚刚学习如何开发Android Wear,我已经为智能手表创建了一个全屏活动,在我的应用程序的移动部分,我获得了一些JSON数据,并从中创建了一个自定义对象列表.

在我的移动应用程序中,我在ListView中显示这些对象的信息.

在我的应用程序的Wear部分,我想显示此列表的限制版本,例如列表中的前3个将显示在Wearable上的全屏应用程序上.

我的问题是,似乎没有办法将Parcelable Objects发送到Android Wear,因此在DataItem中没有putParcelable选项.

看起来唯一的选择是以字节为单位发送对象,如下所示:

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

所以我必须将我的对象转换为字节,将其发送到Android Wear并将其转换回来?这意味着我已经实现了Parcelable的对象,所以我现在可以通过Intents发送它们也需要实现Serializable,这是正确的还是有更好的方法呢?

Mac*_*ęga 17

捆绑式解决方案:

在我的应用程序中,我创建了一个轻量级的类,专门用于从手机发送到手表.由于代码在应用程序的移动和可穿戴部分之间共享,因此可以在两个设备上轻松打包和恢复,而无需重复代码.它提供了Bundle类似机制,但使用DataMap.

示例实施:

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

编写这样的类将让您考虑实际需要在设备之间发送的内容尽可能少地发送.当添加或删除任何字段时,它也不会中断(与下一个解决方案相反).

回答你的Parcelable问题:

如果您不想编写新类并希望重用现有代码,可以尝试使用下面的代码.它将让您只使用Parcelable接口(无需实现Serializable接口).我没有在发送设备时测试它,但是它成功地marshall()unmarshall()/或从Parcel 传送字节数组并存储它DataMap.

注意:我不确切知道Google Play服务如何保存所有这些DataApi数据,但我担心在更新此类课程时可能会出现问题.
例如,该类将在Android Wear上更新,用户将启动将尝试从当前数据读取的应用程序DataApi(使用此类的旧版本"序列化")并尝试从其中读取它,byte[]就像它是更新版本一样.应该测试这些问题,但我不认为它们是DataApi如此原始的"仅仅因为"或者更难以在Wear上开发应用程序.

我强烈建议使用Bundle类似的解决方案,不要使用Parcelable解决方案.
使用此风险需要您自担风险.

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

该代码也可以在GitHub上获得.