Я пытаюсь подключиться к слою данных на носимом устройстве с помощью Activity
, который реализует DataApi.DataListener
. В onStart()
устройство подключается к клиенту API Google и вызывается onConnected()
. От onConnected()
Я вызываю другой метод, который отправляет сообщение в карманный компьютер для обновления данных и запускает новый AsyncTask
для получения данных с уровня данных. Это мой Activity
:Неисправность Подключение к изношенному слою данных
public class DataLayerActivity extends Activity implements DataApi.Listener,
GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener {
private ArrayList<myObject> mObjects = new ArrayList<>();
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Wearable.API).addConnectionCallbacks(this)
.addOnConnectionFailedListener(this).build();
}
@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();
}
@Override
public void onConnected(Bundle bundle) {
Wearable.DataApi.addListener(mGoogleApiClient, this);
requestUpdate();
}
@Override
public void onConnectionSuspended(int cause) {
Timber.d("Connection Suspended");
}
@Override
public void onConnectionFailed(ConnectionResult result) {
Timber.d("Connection Failed with result: " + result);
}
@Override
public void onDataChanged(DataEventBuffer dataEvents) {
}
private void requestUpdate() {
new Thread(new Runnable() {
@Override
public void run() {
NodeApi.GetConnectedNodesResult nodes = Wearable.NodeApi.getConnectedNodes(mGoogleApiClient).await();
for(Node node : nodes.getNodes()) {
Wearable.MessageApi.sendMessage(getGoogleApiClient(), node.getId(), "/path", null).setResultCallback(onMessageResult());
}
}
}).start();
try {
Uri uri = Uri.parse("/path");
mObjects = new FetchDataTask(this).execute(uri).get();
} catch(InterruptedException | ExecutionException exception) {
Timber.e(exception, "Fetch Data Failed");
}
}
protected ResultCallback<MessageApi.SendMessageResult> onMessageResult() {
if(!result.getStatus().isSuccess()) {
Timber.d("Failed to Connect with status " + result.getStatus());
}
}
}
И это FetchDataTask
:
public class FetchDataTask extends AsyncTask<Uri, Void, ArrayList<myObject>> {
private Context mContext;
private ArrayList<myObject> mObjects = new ArrayList<>();
public FetchDataTask(Context context) {
mContext = context;
}
@Override
protected ArrayList<myObject> doInBackground(Uri... params) {
GoogleApiClient googleApiClient = new GoogleApiClient
.Builder(mContext).addApi(WearableAPI).build();
ConnectionResult connectionResult = googleApiClient.blockingConnect(30, TimeUnit.SECONDS);
if(!connectionResult.isSuccess() || !googleApiClient.isConnected()) {
Timber.e("Failed to Connect with error code: " + connectionResult.getErrorCode());
return null;
}
...
return mObjects;
}
}
В результате подключения всегда возвращается с error code 14, который является тайм-аут соединения. Поэтому я попытался передать уже подключенный GoogleApiClient
от DataLayerActivity
в качестве параметра до FetchDataTask
и использовать его для процессов. Но когда я звоню Wearable.DataApi.getDataItem().await()
или Werable.NodeApi.getLocalNode().await()
в пределах doInBackground()
, await()
никогда не заканчивается, и мое приложение останавливается. Но я никогда не получаю сообщений об ошибках от onConnectionSuspended()
или onConnectionFailed()
. Я не могу понять, почему соединение с слоем данных истекает в моем AsyncTask
. Я знаю, что это можно сделать, так как это делается в AttractionsActivity в приложении примера XYZTouristAttractions.
Я не заметил, что я никогда не называл 'connect()', что могло бы вызвать проблему. Но я добавил 'googleApiClient.connect()' to' doInBackground() ', и я все равно получаю тот же самый код ошибки тайм-аута. 'AsyncTask' не имеет метода' start() ', я считаю, что функция execute()' аналогична. Что касается 'await()', это было действительно просто для целей тестирования, я планирую добавить ответные обратные вызовы в готовом коде. – Bryan
Кроме того, я просто просмотрел его дальше, похоже, что 'googleApiClient.blockingConnect (30, TimeUnit.SECONDS)' действует как вызов 'connect()'. Задокументировано здесь: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient.html – Bryan
Вы правы в отношении несогласованных фигурных скобок и вызова 'start()', I думал, что вы имели в виду «AsyncTask». Когда я скопировал код, он немного перепутался, я, должно быть, пропустил это, когда попытался это исправить. Это было правильно в исходном коде, я просто исправил его в вопросе. – Bryan