Cannot send an Asset to an Android Wear device

ぐ巨炮叔叔 提交于 2019-12-12 07:17:04

问题


I'm trying to send an Asset to my Sony SmartWatch3. I followed the Google's documentation (https://developer.android.com/training/wearables/data-layer/assets.html) but it doesn't work.

My handheld activity's code :

public class MainActivityHandheld extends ActionBarActivity
{
    private GoogleApiClient mGoogleApiClient;
    private static final String MY_KEY = "com.example.andy.key.mykey";

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main_activity_handheld);

        Button button = (Button) findViewById(R.id.button);
        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendDataToWearable();
            }
        });

        Log.i("ANDY", "mGoogleApiClient before creation -- Handheld");
        mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {
                @Override
                public void onConnected(Bundle connectionHint) {
                    Log.d("tag", "onConnected: " + connectionHint);
                    // Now you can use the Data Layer API
                }

                @Override
                public void onConnectionSuspended(int cause) {
                    Log.d("tag", "onConnectionSuspended: " + cause);
                }
            })
            .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                @Override
                public void onConnectionFailed(ConnectionResult result) {
                    Log.d("tag", "onConnectionFailed: " + result);
                }
            })
            // Request access only to the Wearable API
            .addApi(Wearable.API)
            .build();
        Log.i("ANDY", "mGoogleApiClient after creation -- Handheld");
    }

    @Override
    protected void onStart() {
        super.onStart();
        Log.i("ANDY", "mGoogleApiClient before connect -- Handheld");
        mGoogleApiClient.connect();
        Log.i("ANDY", "mGoogleApiClient after connect -- Handheld");
    }

    @Override
    protected void onStop() {
        Log.i("ANDY", "mGoogleApiClient before disconnect -- Handheld");
        mGoogleApiClient.disconnect();
        Log.i("ANDY", "mGoogleApiClient after disconnect -- Handheld");
        super.onStop();
    }

    private void sendDataToWearable()
    {
        try 
        {
            Log.i("ANDY", "Before send -- Handheld");
            Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
            Asset asset = createAssetFromBitmap(bitmap);
            PutDataRequest request = PutDataRequest.create("/image");
            request.putAsset("profileImage", asset);
            Wearable.DataApi.putDataItem(mGoogleApiClient, request);
            Log.i("ANDY", "After send -- Handheld");
        }
        catch (Exception ex)
        {
            ex.printStackTrace();
            Log.i("ANDY", "Exception -- Handheld : " + ex.getStackTrace().toString());
        }
    }

    private static Asset createAssetFromBitmap(Bitmap bitmap) {
        final ByteArrayOutputStream byteStream = new ByteArrayOutputStream();
        bitmap.compress(Bitmap.CompressFormat.PNG, 100, byteStream);
        return Asset.createFromBytes(byteStream.toByteArray());
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main_activity_handheld, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

My wearable activity's code :

public class MainActivityWear extends Activity implements
    DataApi.DataListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {

private TextView mTextView;
private GoogleApiClient mGoogleApiClient;
private static final String MY_KEY = "com.example.andy.key.mykey";

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main_activity_wear);
    final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
        @Override
        public void onLayoutInflated(WatchViewStub stub) {
            mTextView = (TextView) stub.findViewById(R.id.text);
        }
    });

    Log.i("ANDY", "mGoogleApiClient before creation -- Wearable");
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            // Request access only to the Wearable API
            .addApi(Wearable.API)
            .build();
    Log.i("ANDY", "mGoogleApiClient after creation -- Wearable");
}

@Override
protected void onResume() {
    super.onResume();
    Log.i("ANDY", "mGoogleApiClient after connect (OnResume) -- Wearable");
    mGoogleApiClient.connect();
    Log.i("ANDY", "mGoogleApiClient after connect (OnResume) -- Wearable");
}

@Override
protected void onPause() {
    super.onPause();
    Log.i("ANDY", "mGoogleApiClient before removeListener & disconnect -- Wearable");
    Wearable.DataApi.removeListener(mGoogleApiClient, this);
    mGoogleApiClient.disconnect();
    Log.i("ANDY", "mGoogleApiClient after removeListener & disconnect -- Wearable");
}

@Override
public void onConnected(Bundle connectionHint) {
    Log.i("ANDY", "mGoogleApiClient before addListener -- Wearable");
    Wearable.DataApi.addListener(mGoogleApiClient, this);
    Log.i("ANDY", "mGoogleApiClient after addListener -- Wearable");
    // Now you can use the Data Layer API
}

@Override
public void onConnectionSuspended(int cause) {
    Log.d("tag", "onConnectionSuspended: " + cause);
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.d("tag", "onConnectionFailed: " + result);
}

@Override
public void onDataChanged(DataEventBuffer dataEvents) {

    Log.i("ANDY", "onDataChanged before boucle event -- Wearable");

    for (DataEvent event : dataEvents)
    {
        if (event.getType() == DataEvent.TYPE_CHANGED) {
            // DataItem changed
            DataItem item = event.getDataItem();
            if (item.getUri().getPath().compareTo("/image") == 0)
            {
                Log.i("ANDY", "onDataChanged before get Asset -- Wearable");
                DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
                Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage");
                Bitmap bitmap = loadBitmapFromAsset(profileAsset);
                // Do something with the bitmap

                Log.i("ANDY", "onDataChanged after get Asset -- Wearable");

                try
                {
                    Log.i("ANDY", "onDataChanged before deserialize -- Wearable");
                    ArrayList<MyObject> myObjectArrayList = (ArrayList<MyObject>) Serializer.deserialize(array);
                    Log.i("ANDY", "onDataChanged after deserialize -- Wearable");
                }
                catch (Exception e) {
                    e.printStackTrace();
                    Log.i("ANDY", "onDataChanged exception -- Wearable :" + e.getStackTrace().toString());
                }
            }
        } else if (event.getType() == DataEvent.TYPE_DELETED) {
            // DataItem deleted
        }
    }
}

public Bitmap loadBitmapFromAsset(Asset asset) {
    if (asset == null) {
        throw new IllegalArgumentException("Asset must be non-null");
    }
    ConnectionResult result =
           mGoogleApiClient.blockingConnect(100, TimeUnit.MILLISECONDS);
    if (!result.isSuccess()) {
        return null;
    }
    // convert asset into a file descriptor and block until it's ready
    InputStream assetInputStream = Wearable.DataApi.getFdForAsset(
            mGoogleApiClient, asset).await().getInputStream();
            mGoogleApiClient.disconnect();

    if (assetInputStream == null) {
        Log.w(TAG, "Requested an unknown Asset.");
        return null;
    }
    // decode the stream into a bitmap
    return BitmapFactory.decodeStream(assetInputStream);
}
}

The execution of the Handheld's code works fine (the logs are correctly displayed) but the program doesn't enter to the onDataChanged's wearable method. However, when I try to send an Integer instead of an Asset it works fine:

PutDataRequest request = PutDataRequest.create("/array");
request.putInt("array", 90);
Wearable.DataApi.putDataItem(mGoogleApiClient, request);

Any ideas? I don't understand what's going on.


回答1:


It's tricky, but in order to get invoked the content of the data has to change. Try adding the timestamp to the DataMap. E.g.

PutDataMapRequest request = PutDataMapRequest.create("/image");
Asset asset = createAssetFromBitmap(bitmap);
request.putAsset("profileImage", asset);
DataMap dataMap = request.getDataMap(); 
dataMap.putLong("timestamp", System.currentTimeMillis());
PutDataRequest dataRequest = request.asPutDataRequest();      
Wearable.DataApi.putDataItem(mGoogleApiClient, dataRequest);


来源:https://stackoverflow.com/questions/28631002/cannot-send-an-asset-to-an-android-wear-device

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