0

Я пытаюсь подключиться к слою данных на носимом устройстве с помощью 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.

ответ

0

Быстро глядя на свой код, я могу видеть несколько вопросов:

  • В FetchDataTask, в doInBackground, вы строите GoogleApiClient, но вы никогда не называли подключения(), чтобы установить соединение
  • В requestUpdate(), кажется, что есть непревзойденные фигурные скобки и т. д. Кроме того, для потока, который вы там создали, я не вижу, чтобы вы когда-либо называли его «start()».
  • Всякий раз, когда вы вызываете await() на любой из асинхронных вызовов, убедитесь, что вы указали таймаут, чтобы он не застрял навсегда, и после этого проверьте, чтобы вызов был успешным, прежде чем использовать результат.
+0

Я не заметил, что я никогда не называл 'connect()', что могло бы вызвать проблему. Но я добавил 'googleApiClient.connect()' to' doInBackground() ', и я все равно получаю тот же самый код ошибки тайм-аута. 'AsyncTask' не имеет метода' start() ', я считаю, что функция execute()' аналогична. Что касается 'await()', это было действительно просто для целей тестирования, я планирую добавить ответные обратные вызовы в готовом коде. – Bryan

+0

Кроме того, я просто просмотрел его дальше, похоже, что 'googleApiClient.blockingConnect (30, TimeUnit.SECONDS)' действует как вызов 'connect()'. Задокументировано здесь: https://developers.google.com/android/reference/com/google/android/gms/common/api/GoogleApiClient.html – Bryan

+0

Вы правы в отношении несогласованных фигурных скобок и вызова 'start()', I думал, что вы имели в виду «AsyncTask». Когда я скопировал код, он немного перепутался, я, должно быть, пропустил это, когда попытался это исправить. Это было правильно в исходном коде, я просто исправил его в вопросе. – Bryan

Смежные вопросы