Search code examples
androidwear-osandroid-wear-data-api

Unable to push data to android wear (Emulator)


I have been trying to push data to the android wear emulator. But all in vain. My listener on the emulator is not receiving any calls whatsoever. If anyone else has tried working on wear and pushing data to wear please HELP.

This is what my receiver code looks like

 private GoogleApiClient mGoogleApiClient;

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

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addApi(Wearable.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    final WatchViewStub stub = (WatchViewStub) findViewById(R.id.watch_view_stub);
    stub.setOnLayoutInflatedListener(new WatchViewStub.OnLayoutInflatedListener() {
        @Override
        public void onLayoutInflated(WatchViewStub stub) {
            ivQrImage = (ImageView) stub.findViewById(R.id.ivQRImage);
        }
    });
}

@Override
public void onDataChanged(DataEventBuffer dataEvents) {
    for (DataEvent event : dataEvents) {
        if (event.getType() == DataEvent.TYPE_CHANGED &&
                event.getDataItem().getUri().getPath().equals("/image")) {
            final DataMapItem dataMapItem = DataMapItem.fromDataItem(event.getDataItem());
            final Asset profileAsset = dataMapItem.getDataMap().getAsset("profileImage");
            final Bitmap bitmap = loadBitmapFromAsset(profileAsset);
            Log.d(TAG, ""+bitmap);
            if (null != bitmap) {
                ivQrImage.setImageBitmap(bitmap);
                bitmap.recycle();
            }

        }
    }
}

@Override
protected void onStart() {
    super.onStart();

    mGoogleApiClient.connect();
}

@Override
protected void onStop() {
    if (null != mGoogleApiClient && mGoogleApiClient.isConnected()) {
        Wearable.DataApi.removeListener(mGoogleApiClient, this);
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

public Bitmap loadBitmapFromAsset(Asset asset) {
    if (asset == null) {
        throw new IllegalArgumentException("Asset must be non-null");
    }
    ConnectionResult result =
            mGoogleApiClient.blockingConnect(TIMEOUT_MS, 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);
}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
    Log.d(TAG,"Connection Failed");
}

@Override
public void onConnected(Bundle bundle) {
    Wearable.DataApi.addListener(mGoogleApiClient, this);
    Wearable.MessageApi.addListener(mGoogleApiClient, this);
}

This is how I am pushing

private void pushImageToWear() {

    Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.qr_code);
    Asset asset = createAssetFromBitmap(bitmap);
    PutDataMapRequest dataMap = PutDataMapRequest.create("/image");
    dataMap.getDataMap().putAsset("profileImage", asset);
    PutDataRequest request = dataMap.asPutDataRequest();
    PendingResult<DataApi.DataItemResult> pendingResult = Wearable.DataApi
            .putDataItem(mGoogleApiClient, request);

}

I also have the following in my manifest for the Android Wear activity

<activity
        android:name=".QRCodeReceptionActivity"
        android:label="@string/app_name"
        android:exported="true"
        android:allowEmbedded="true"
        android:taskAffinity=""
        android:theme="@android:style/Theme.DeviceDefault.Light">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>

P.S. There is nothing extraordinary which I am doing. Just followed the tutorial given on the developer site.


Solution

  • Sorry that I use Answer, but I need a reputation of 50 to comment :(

    I had the same problem here https://stackoverflow.com/... , but now I fixed it.

    Ok I share with you all problems I ran into:

    First in the AndroidManifest.xml files on the mobile add the following:

    <meta-data android:name="com.google.android.gms.version" android:value="@integer/google_play_services_version" />
    

    Second what confused me a bit was, that onDataChanged() is only called when the DataItem inside is really "changed". So it works maybe for the first time, but later nothing will happen.

    I changed the code on the mobile, so everytime I try to send data it has a different timestamp:

    Asset asset = createAssetFromBitmap(bitmap);
            PutDataMapRequest request = PutDataMapRequest.create("/image");
            DataMap map = request.getDataMap();
            map.putLong("time", new Date().getTime()); // MOST IMPORTANT LINE FOR TIMESTAMP
            map.putAsset("profileImage", asset);
            Wearable.DataApi.putDataItem(mGoogleApiClient, request.asPutDataRequest());
    

    I found out in this IO Video

    The rest of the code looks like yours. I hope this help.