Android Wear Watchface Settings on host
Asked Answered
C

2

3

I currently have an android wear watchface developed. I however would now like to create a settings section on the host app that would allow the user to customize the watchface. I am new to the android development so I am curious on the correct way to do this.

Is there a way to update a sharedpreference on the host and then push or sync that with the sharedpreference on the wear device? Or is there a totally different way I should be looking at this?

Cida answered 22/7, 2014 at 18:11 Comment(0)
W
14

You can use the DataApi or MessageApi to sync your watchface configuration between Phone and Watch devices.

Please take a look at the documentation and choose the one more appropriate to your needs:
https://developer.android.com/training/wearables/data-layer/index.html https://developer.android.com/training/wearables/data-layer/data-items.html
https://developer.android.com/training/wearables/data-layer/messages.html


Here is an example with the use of DataApi.

Everything pushed to the DataApi is shared between devices and available of both of them. You can change this data on both sides and the other side will be notified about such change immediately (when devices are connected to each other). You can also read this data at any moment (for example when user will choose your watchface on the Watch - the configuration data will be already waiting for you there).

On the phone side:

public class WatchfaceConfigActivity extends Activity {
    private GoogleApiClient mGoogleApiClient;

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

        mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(new ConnectionCallbacks() {
                    @Override
                    public void onConnected(Bundle connectionHint) {
                    }
                    @Override
                    public void onConnectionSuspended(int cause) {
                    }
            })
            .addOnConnectionFailedListener(new OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(ConnectionResult result) {
                    }
                })
            .addApi(Wearable.API)
            .build();
        mGoogleApiClient.connect();
    }

and every time you want to sync new fconfiguration with the Android Wear device you have to put a DataRequest via Wearable DataApi:

    private void syncConfiguration() {
        if(mGoogleApiClient==null)
            return;

        final PutDataMapRequest putRequest = PutDataMapRequest.create("/CONFIG");
        final DataMap map = putRequest.getDataMap();
        map.putInt("mode", 1);
        map.putInt("color", Color.RED);
        map.putString("string_example", "MyWatchface");
        Wearable.DataApi.putDataItem(mGoogleApiClient,  putRequest.asPutDataRequest());
    }
}


On the Watch side:

You need to create a class that extends WearableListenerService:

public class DataLayerListenerService extends WearableListenerService {

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        super.onDataChanged(dataEvents);

        final List<DataEvent> events = FreezableUtils.freezeIterable(dataEvents);
        for(DataEvent event : events) {
            final Uri uri = event.getDataItem().getUri();
            final String path = uri!=null ? uri.getPath() : null;
            if("/CONFIG".equals(path)) {
                final DataMap map = DataMapItem.fromDataItem(event.getDataItem()).getDataMap();
                // read your values from map:
                int mode = map.getInt("mode");
                int color = map.getInt("color");
                String stringExample = map.getString("string_example");
            }
        }
    }
}

and declare it in your AndroidManifest:

<service android:name=".DataLayerListenerService" >
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.BIND_LISTENER" />
    </intent-filter>
</service>

Notice that this is only an example of usage. Maybe (instead of registering an instance of WearableListenerService) there will be better for you to create an instance of mGoogleApiClient inside your Watchface directly and add a DataListener there:

    Wearable.DataApi.addListener(mGoogleApiClient, new DataListener() {
        @Override
        public void onDataChanged(DataEventBuffer dataEvents) {
            // read config here and update the watchface
        }
    });

Maybe you don't need shared data - then you can communicate using MessageApi and send messages only when new configuration is saved or then watch wants to read current configuration from phone.

Wishywashy answered 22/7, 2014 at 19:25 Comment(2)
Wow - Thank you for your response! I was expecting a sentence or two to get me thinking in the general path, but you went above and beyond. I will do some reading on the links and info you provided and see what I can get going!Cida
No problem. After studying these documentations think of which of these solutions is will be better for your needs (because every case is slightly different). You can always use these snippets as a support:)Array
J
1

There isn't a shared preferences across the mobile and wear modules per se, but you can send messages and/or update assets that a listener will detect. For example, whenever you change a preference on the phone, you could also send a message to the watch using the Message API. On the watch, you should implement a WearableListenerService with an onMessageReceived method, in which you can parse the message and take an appropriate action, such as setting a preference on the watch.

Check out the Android Developers training guide: https://developer.android.com/training/wearables/data-layer/index.html

Jitney answered 22/7, 2014 at 19:16 Comment(1)
Thank you for your advice... this will get me heading in the right direction!Cida

© 2022 - 2024 — McMap. All rights reserved.