Torben G
Torben G

Reputation: 790

Syncing Data Items between Mobile Device and Wear

I am trying to sync Data between my Mobile Device and my Wear. But without any success. I did everything from the developer docs I think.

This is the MainActivity of my mobile Code:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;

import com.google.android.gms.tasks.OnSuccessListener;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.wearable.DataClient;
import com.google.android.gms.wearable.DataItem;
import com.google.android.gms.wearable.PutDataMapRequest;
import com.google.android.gms.wearable.PutDataRequest;
import com.google.android.gms.wearable.Wearable;

import java.util.Date;

public class MainActivity extends AppCompatActivity {

    Button button;
    private static final String COUNT_KEY = "com.example.torbengab.sendwatchmessage";

    DataClient mDataClient;


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

        button = findViewById(R.id.button2);

        button.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                sendStuff();
            }
        });
    }

    private void sendStuff() {
        mDataClient = Wearable.getDataClient(this);
        PutDataMapRequest putDataMapReq = PutDataMapRequest.create("/message").setUrgent();
        putDataMapReq.getDataMap().putInt(COUNT_KEY, 123);
        PutDataRequest putDataReq = putDataMapReq.asPutDataRequest().setUrgent();
        Task<DataItem> putDataTask = mDataClient.putDataItem(putDataReq);

        putDataTask.addOnSuccessListener(new OnSuccessListener<DataItem>() {
            @Override
            public void onSuccess(DataItem dataItem) {
                Toast.makeText(getApplicationContext(), "sending :)", Toast.LENGTH_LONG).show();
            }
        });
    }
}

I am getting the putDataTask.addOnSuccessListener onSuccess callback. So I think this part works fine. And here is the Wear Project MainActivity:

import android.net.Uri;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.wearable.activity.WearableActivity;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.wearable.CapabilityClient;
import com.google.android.gms.wearable.CapabilityInfo;
import com.google.android.gms.wearable.DataClient;
import com.google.android.gms.wearable.DataEvent;
import com.google.android.gms.wearable.DataEventBuffer;
import com.google.android.gms.wearable.DataItem;
import com.google.android.gms.wearable.DataMap;
import com.google.android.gms.wearable.DataMapItem;
import com.google.android.gms.wearable.MessageClient;
import com.google.android.gms.wearable.MessageEvent;
import com.google.android.gms.wearable.Wearable;

public class MainActivity extends WearableActivity implements DataClient.OnDataChangedListener,
        MessageClient.OnMessageReceivedListener,
        CapabilityClient.OnCapabilityChangedListener {

    private TextView mTextView;
    private static final String COUNT_KEY = "com.example.torbengab.sendwatchmessage";


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

        mTextView = (TextView) findViewById(R.id.text);

        // Enables Always-on
        setAmbientEnabled();
    }

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

        // Instantiates clients without member variables, as clients are inexpensive to create and
        // won't lose their listeners. (They are cached and shared between GoogleApi instances.)
        Wearable.getDataClient(this).addListener(this);
        Wearable.getMessageClient(this).addListener(this);
        Wearable.getCapabilityClient(this)
                .addListener(
                        this, Uri.parse("wear://"), CapabilityClient.FILTER_REACHABLE);
    }

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

        Wearable.getDataClient(this).removeListener(this);
        Wearable.getMessageClient(this).removeListener(this);
        Wearable.getCapabilityClient(this).removeListener(this);
    }

    @Override
    public void onDataChanged(@NonNull DataEventBuffer dataEventBuffer) {
        Toast.makeText(getApplicationContext(), "yey", Toast.LENGTH_LONG).show();
        for (DataEvent event : dataEventBuffer) {
            if (event.getType() == DataEvent.TYPE_CHANGED) {
                // DataItem changed
                DataItem item = event.getDataItem();
                if (item.getUri().getPath().compareTo("/message") == 0) {
                    DataMap dataMap = DataMapItem.fromDataItem(item).getDataMap();
                    Toast.makeText(getApplicationContext(), String.valueOf(dataMap.getInt(COUNT_KEY)), Toast.LENGTH_LONG).show();
                }
            } else if (event.getType() == DataEvent.TYPE_DELETED) {
                // DataItem deleted
            }
        }
    }

    @Override
    public void onCapabilityChanged(@NonNull CapabilityInfo capabilityInfo) {
        Toast.makeText(getApplicationContext(), "yey", Toast.LENGTH_LONG).show();

    }

    @Override
    public void onMessageReceived(@NonNull MessageEvent messageEvent) {
        Toast.makeText(getApplicationContext(), "yey", Toast.LENGTH_LONG).show();

    }
}

Maybe I have to add permissions to the manifest file, but I found nothing online. It would very cool if one of you could help me. Thanks.

Upvotes: 5

Views: 1610

Answers (1)

aminator
aminator

Reputation: 481

I managed to get it working with these 3 steps:

1. The receiving side implements a CHANGE listener

Thus putDataMapReq.getDataMap().putInt(COUNT_KEY, 123); works only once. You need to change the value 123 each time the sendStuff() method gets called.

2. Both modules mobile & wear must have the very same application id set in the build.gradle file


    android {
        defaultConfig {
            applicationId "com.example.myapp"
            minSdkVersion 15
            targetSdkVersion 24
            versionCode 1
            versionName "1.0"
        }
        ...
    }

https://developer.android.com/studio/build/application-id

3. Both modules mobile & wear must have the same signature

you need to

a) Generate an upload key and keystore

  • In the menu bar, click Build > Build > Generate Signed Bundle/APK.

  • In the Generate Signed Bundle or APK dialog, select Android App Bundle or APK and click Next.

  • Below the field for Key store path, click Create new.

  • On the New Key Store window, provide the information for your keystore and key

b) Sign your app with your key

  • If you don’t currently have the Generate Signed Bundle or APK dialog open, click Build > Generate Signed Bundle/APK.

  • In the Generate Signed Bundle or APK dialog, select either Android App Bundle or APK and click Next.

  • Select a module from the drop down.

  • Specify the path to your keystore, the alias for your key, and enter the passwords for both.

and because the signature gets invalid as soon as the code is changed

c) Configure the build process to automatically sign your app

  • In the Project window, right click on your app and click Open Module Settings.

  • On the Project Structure window, under Modules in the left panel, click the module you would like to sign.

  • Click the Signing tab, then click Add .

  • Select your keystore file, enter a name for this signing configuration (as you may create more than one), and enter the required information.

  • Click the Build Types tab.

  • Click the release build.

  • Under Signing Config, select the signing configuration you just created.

finally you should

d) Remove signing information from your build files

which is very well documented right here (all step a-d):

https://developer.android.com/studio/publish/app-signing

Upvotes: 6

Related Questions