How to correctly register DATA_CHANGED Data API ev

2019-09-14 18:23发布

问题:

I'm developing an Android app to collect data from an Android Wear. A WearableListenerService is used in the handheld device to receive data from the watch via Data API.

But I noticed that if the app in handheld device is forcibly stopped, either from Settings -> Apps or by adb during development, while the app in wearable is still running, it won't be able to receive data again even it's manually restarted.

This won't happen if the wearable is not running the app.

To restart capturing the data in handheld, I have to stop Google Play Services and re-launch my app.

My WearableListenerService:

public class WearableSensorListener extends WearableListenerService {
    public static final String SENSOR_RESULT = "minimal_intent_service.result";
    public static final String SENSOR_MESSAGE = "minimal_intent_service.message";
    private static final String DATA_API_PATH = "/wearable-sensor";
    //    private GoogleApiClient googleApiClient;
    private LocalBroadcastManager localBroadcastManager = LocalBroadcastManager.getInstance(this);

    @Override
    public void onDataChanged(DataEventBuffer dataEvents) {
        Log.i(this.getClass().toString(), "Got data at " + System.currentTimeMillis());
        for (DataEvent dataEvent : dataEvents) {
            Log.i(this.getClass().toString(), "Got event: " + dataEvent.toString());
            if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
                String path = dataEvent.getDataItem().getUri().getPath();
                if (path.equals(DATA_API_PATH)) {
                    DataMap dataMap = DataMapItem.fromDataItem(dataEvent.getDataItem()).getDataMap();
                    int type = dataMap.getInt("TYPE");
                    long time = dataMap.getLong("TIME");
                    float[] data = dataMap.getFloatArray("DATA");
                    String message = String.format(Locale.UK, "TYPE: %d, TIME: %d, DATA: %s",
                            type,
                            time,
                            Arrays.toString(data));

                    showSensorResult(message);
                }
            }
        }
    }

    private void showSensorResult(String message) {
        Intent intent = new Intent(SENSOR_RESULT);
        if (message != null)
            intent.putExtra(SENSOR_MESSAGE, message);
        localBroadcastManager.sendBroadcast(intent);
    }
}

AndroidManifest.xml in handheld:

<service
        android:name=".WearableSensorListener"
        android:enabled="true"
        android:exported="true">
    <intent-filter>
        <action android:name="com.google.android.gms.wearable.DATA_CHANGED"/>
        <data android:host="*"
              android:scheme="wear"
              android:pathPrefix="/wearable-sensor"/>
    </intent-filter>
</service>

It seems the listener won't be cleared after the app crash/stop. Is there any workaround to handle this?

回答1:

It seems the listener won't be cleared after the app crash/stop.

Why should it? You've registered to that action through manifest and haven't unregistered from anywhere.

You can disable the component from onDataChanged() with PackageManager. setComponentEnabledSetting() API.

Set the enabled setting for a package component (activity, receiver, service, provider). This setting will override any enabled state which may have been set by the component in its manifest.