问题
I have had an Android Wear app on the market for about 10 months now and it's stopped working (Not sure when it stopped working).
I'm trying to update my wearable application with some statistics that I record in my mobile app. As I say, this used to work fine and reliably. I even added the timestamp to this so it was unique as the onDataChanged
is only called if data has changed. This guarantees that.
My Issue
I can submit the PutDataMapRequest
fine by calling Wearable.DataApi.putDataItem
and I get a successful callback in my ResultCallback
.
The onDataChanged
usually gets called in the end but the delay is just too much and more than it used to be. Whatsmore, I know it's being set correctly because I have an app that I launch, in which I have an Activity
that I go and get the DataItems
and there is a backlog there. I am having the same issue with onDataChanged
in this Activity
also.
What I Have Done
- Made sure the versionCode and versionName matches across both module
build.gradle
files. - Ensured both
build.gradle
files use the same versions of the support and google services libraries. - Ensured both classes are connecting to
GoogleApiClient
- Made sure the data is different each time to force it to call
onDataChanged
in the service. I don't need this but just to get it working.
My Code
Mobile
if (mGoogleApiClient.isConnected()) {
PutDataMapRequest putDataMapRequest = PutDataMapRequest.create(path);
putDataMapRequest.getDataMap().putString("content", content);
putDataMapRequest.getDataMap().putString("title", title);
putDataMapRequest.getDataMap().putLong("timestamp", DateTime.now().getMillis());
PutDataRequest request = putDataMapRequest.asPutDataRequest();
Wearable.DataApi.putDataItem(mGoogleApiClient, request)
.setResultCallback(new ResultCallback<DataApi.DataItemResult>() {
@Override
public void onResult(DataApi.DataItemResult dataItemResult) {
if (!dataItemResult.getStatus().isSuccess()) {
Log.e("WearDevice", "buildWatchOnlyNotification(): Failed to set the data, "
+ "status: " + dataItemResult.getStatus().getStatusCode());
} else {
Log.d(LOG_TAG, "Notificaiton result callback returned successfully: "+dataItemResult.getDataItem().toString());//: "+node.getDisplayName());
}
}
});
}
Wear
I have a service which extends WearableListenerService
. This is declared in the manifest like so.
<service android:name=".NotificationUpdateService">
<intent-filter>
<action android:name="com.google.android.gms.wearable.BIND_LISTENER"/>
</intent-filter>
</service>
Here is my service.
@Override
public void onCreate() {
super.onCreate();
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
mGoogleApiClient.connect();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
if (MainActivity.DEBUGGING)
Log.d(LOG_TAG, "onDataChanged");
for (DataEvent dataEvent : dataEvents) {
if (dataEvent.getType() == DataEvent.TYPE_CHANGED) {
DataMap dataMap = DataMapItem.fromDataItem(dataEvent.getDataItem()).getDataMap();
String content = dataMap.getString("content");
String title = dataMap.getString("title");
if ("/mydatapath".equals(dataEvent.getDataItem().getUri().getPath())) {
buildWearableOnlyNotification(title, content, false);
}
}
}
}
The buildWearableOnlyNotification
method creates and starts a foreground notification and this works fine when it's actually called.
回答1:
You now need to set the urgent flag if you want your data to be synced immediately, otherwise the framework will batch up those calls and do them in one call which means you can see up to 30 minutes delay; it is a change made in the most recent Play Services to preserve the battery when such immediate data sync is not really needed.
来源:https://stackoverflow.com/questions/33900980/is-dataapi-reliable-and-practically-real-time-extremely-delayed