如何从 ConnectionsClient 方法返回的 Task<Void> 中获取状态?

How do I get the status from the Task<Void> returned by ConnectionsClient methods?

我正在使用 ConnectionsClient API, including startAdvertising(), which returns a Task<Void>. The javadoc for startAdvertising() 包含此语句:

Possible result status codes include:

  • STATUS_OK if advertising started successfully.
  • STATUS_ALREADY_ADVERTISING if the app is already advertising.
  • STATUS_OUT_OF_ORDER_API_CALL if the app is currently connected to remote endpoints; call stopAllEndpoints() first.

如何在调用 startAdvertising() 后获取这些状态值?

我知道任务 API 使我能够创建一个 OnSuccessListener and OnFailureListener,但我希望能够区分不同的失败案例(具体来说,STATUS_ALREADY_ADVERTISING 是良性失败).因为类型是 Task<Void>,所以在传递给 onSuccess() 方法时调用 getResult() 不会提供有用的信息。

所有状态码都在ConnectionsStatusCodes class. In startAdvertising method, the third param is a ConnectionLifecycleCallback中,您可以用它来接收这些状态码。例如:

final Activity activity = this;
final ConnectionLifecycleCallback callback = new ConnectionLifecycleCallback() {
    @Override
    public void onConnectionInitiated(String endpointId, ConnectionInfo connectionInfo) {

    }

    @Override
    public void onConnectionResult(String endpointId, ConnectionResolution resolution) {
        int statusCode = resolution.getStatus().getStatusCode();
        switch (statusCode) {
            case ConnectionsStatusCodes.STATUS_OK:
                break;
            case ConnectionsStatusCodes.STATUS_ALREADY_ADVERTISING:
                break;
            case ConnectionsStatusCodes.STATUS_OUT_OF_ORDER_API_CALL:
                break;  
        }
    }

    @Override
    public void onDisconnected(String endpointId) {

    }
};

Nearby.getConnectionsClient(activity).startAdvertising("name", "serviceId", callback, new AdvertisingOptions.Builder().build());

这是将任务转换为状态代码的辅助方法。此示例方法是阻塞的,但在异步时看起来很相似。 try/catch 直接映射到 OnSuccessListener/OnFailureListener.

import static com.google.android.gms.common.api.CommonStatusCodes.ERROR;
import static com.google.android.gms.common.api.CommonStatusCodes.SUCCESS;

import android.support.annotation.CheckResult;
import com.google.android.gms.common.api.ApiException;
import com.google.android.gms.tasks.Task;
import com.google.android.gms.tasks.Tasks;
import java.util.concurrent.ExecutionException;

@CheckResult
public static int waitForTask(String methodName, Task<?> task) {
  try {
    Tasks.await(task);
    return SUCCESS;
  } catch (InterruptedException | ExecutionException e) {    
    if (e instanceof InterruptedException) {
      Thread.currentThread().interrupt();
    }

    Exception taskException = task.getException();
    if (taskException instanceof ApiException) {
      return ((ApiException) taskException).getStatusCode();
    }

    return ERROR;
  }
}