Why does Wearable.DataApi.getFdForAsset produce a result with status 4005 (Asset Unavailable)?

蹲街弑〆低调 提交于 2019-12-07 13:36:44

问题


I've written an Android Wear application which receives an image wrapped in an Asset from a phone app using the Data API. The app used to work fine and has not been changed in ages but recently I started to find the image passed from the phone app was failing to be rendered on the screen of the wearable. On investigation I found that one of the methods, getFdForAsset was failing with a wearable status code of 4005 which means Asset Unavailable. See https://developers.google.com/android/reference/com/google/android/gms/wearable/WearableStatusCodes

I process data events in a call to my wearable app's onDataChanged method like this:

    public void onDataChanged(DataEventBuffer dataEvents) {
    LOGD(TAG, "XXXX MainActivity.onDataChanged()");

    final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
    dataEvents.close();

    LOGD(TAG, "onDataChanged data event count=" + events.size());
    for (DataEvent event : events) {
        if (event.getType() == DataEvent.TYPE_CHANGED) {
            String path = event.getDataItem().getUri().getPath();
            if (IMAGE_PATH.equals(path)) {
                DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                LOGD(TAG, "onDataChanged getting image asset");
                Asset photo = dataMapItem.getDataMap()
                        .getAsset(IMAGE_KEY);
                LOGD(TAG, "onDataChanged photo asset="+photo);
                final String toi_name = dataMapItem.getDataMap().getString(GYBO_NAME);
                final String toi_info = dataMapItem.getDataMap().getString(GYBO_INFO);
                current_toi_name = toi_name;
                current_toi_info = toi_info;
                LOGD(TAG, "onDataChanged TOI name="+toi_name);
                LOGD(TAG, "onDataChanged TOI info="+toi_info);
                Bitmap bitmap = loadBitmapFromAsset(google_api_client, photo);

And then attempt to create a Bitmap from the Asset in this method:

    private Bitmap loadBitmapFromAsset(GoogleApiClient apiClient, Asset asset) {
    if (asset == null) {
        throw new IllegalArgumentException("XXXX Asset must be non-null");
    }

    DataApi.GetFdForAssetResult result = Wearable.DataApi.getFdForAsset(
            apiClient, asset).await();
    if (result == null) {
        Log.w(TAG, "XXXX getFdForAsset returned null");
        return null;
    }

    if (result.getStatus().isSuccess()) {
        Log.d(TAG, "XXXX loadBitmapFromAsset getFdForAsset was successful");
    } else {
        Log.d(TAG, "XXXX loadBitmapFromAsset getFdForAsset was not successful. Error="+result.getStatus().getStatusCode()+":"+result.getStatus().getStatusMessage());
        // Seeing status code 4005 here which means Asset Unavailable
    }

    InputStream assetInputStream = result.getInputStream();
    if (assetInputStream == null) {
        Log.w(TAG, "XXXX Requested an unknown Asset");
        result.release();
        return null;
    }
    result.release();
    return BitmapFactory.decodeStream(assetInputStream);
}

The Asset object itself is not null, so it's coming across from the mobile app OK. And the path of the data event is being correctly recognised as being one which contains an image.

Does anyone have any idea as to why I'm getting this result and how to resolve it?

Thanks


回答1:


one important thing... wearable as well as mobile module have to have the same signing certificate; just make sure if you define it via your build.gradle it's the same. this affects transferring assets... other data were synced w/o issues even with different certificates;

I was recently fighting with this issue and found this was the cause of ASSET_UNAVAILABLE, while adding wear module to existing app which had custom debug signing certificate defined in build.gradle - I had to have this certificate even for wearable for asset sync to work.




回答2:


How are you sending the image? I found that if I used Asset.createFromUri(), it didn't work and gave me the ASSET UNAVAILABLE error. But when I switched to Asset.createFromFd(), it worked.

Here's the code that worked for me:

    private static Asset createAssetFromBitmap(String imagePath) throws FileNotFoundException {
        // creating from Uri doesn't work: gives a ASSET_UNAVAILABLE error
        //return Asset.createFromUri(Uri.parse(imagePath));

        final File file = new File(imagePath);    
        final ParcelFileDescriptor fd = ParcelFileDescriptor.open(file, ParcelFileDescriptor.MODE_READ_ONLY);

        return Asset.createFromFd(fd);
    }


来源:https://stackoverflow.com/questions/32227254/why-does-wearable-dataapi-getfdforasset-produce-a-result-with-status-4005-asset

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!