使用新的定位API减少摩擦

原标题:Reduce friction with the new Location APIs
链接:https://android-developers.googleblog.com/2017/06/reduce-friction-with-new-location-apis.html
作者:Aaron Stacy (Google Play服务软件工程师)
翻译:arjinmc

11.0.0版Google Play服务SDK包含了一种访问LocationServices的新方式 。新的API不需要你的应用来手动管理与Google Play服务的连接GoogleApiClient。这减少了你的应用程序中的样板和常见陷阱。

请阅读下面的更多内容,或者直接访问GitHub上更新的位置示例

为什么不使用GoogleApiClient?

LocationServices API允许你访问设备位置,设置geo(地理围栏),提示用户启用设备上的位置等。为了访问这些服务,该应用必须连接到Google Play服务,这可能涉及容易出错的连接逻辑。例如,你可以在下面的应用程序中发现崩溃吗?

注意:我们假设我们的应用程序具有 ACCESS_FINE_LOCATION使用LocationServices API获取用户确切位置所需的权限。

public class MainActivity extends AppCompatActivity implements
        GoogleApiClient.OnConnectionFailedListener {

  @Override
  public void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    GoogleApiClient client = new GoogleApiClient.Builder(this)
        .enableAutoManage(this, this)
        .addApi(LocationServices.API)
        .build();
    client.connect();

    PendingResult result = 
         LocationServices.FusedLocationApi.requestLocationUpdates(
                 client, LocationRequest.create(), pendingIntent);

    result.setResultCallback(new ResultCallback() {
      @Override
      public void onResult(@NonNull Status status) {
        Log.d(TAG, "Result: " + status.getStatusMessage());
      }
    });
  }

  // ...
}

如果你指着requestLocationUpdates()的调用,你是对的!那个调用会抛出一个IllegalStateException,因为 GoogleApiClient还没有连接。调用connect()是异步的。

虽然上面的代码看起来应该起作用,但是它缺少一个ConnectionCallbacks参数给GoogleApiClient构建器。呼叫请求位置更新只能在onConnected回调触发后进行:

public class MainActivity extends AppCompatActivity implements 
        GoogleApiClient.OnConnectionFailedListener,
        GoogleApiClient.ConnectionCallbacks {

  private GoogleApiClient client;

  @Override
  protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    client = new GoogleApiClient.Builder(this)
        .enableAutoManage(this, this)
        .addApi(LocationServices.API)
        .addConnectionCallbacks(this)
        .build();

    client.connect();
  }

  @Override
  public void onConnected(@Nullable Bundle bundle) {
    PendingResult result = 
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    client, LocationRequest.create(), pendingIntent);

    result.setResultCallback(new ResultCallback() {
      @Override
      public void onResult(@NonNull Status status) {
        Log.d(TAG, "Result: " + status.getStatusMessage());
      }
    });
  }

  // ...
}

现在的代码可以工作,但它不理想,由于以下几个原因:

  • 如果你想要在多个Activity中访问位置服务,那么很难将其重构为共享类。
  • onCreate即使在稍后(例如,在用户输入之后)不需要位置服务,应用程序也会乐观地连接。
  • 它无法处理应用程序无法连接到Google Play服务的情况。
  • 开始进行位置更新之前,有很多样板连接逻辑。

更好的开发者体验

新的LocationServicesAPI更简单,并且使你的代码更少出错。连接逻辑被自动处理,你只需要附加一个完成监听器:

public class MainActivity extends AppCompatActivity {

  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    FusedLocationProviderClient client =
            LocationServices.getFusedLocationProviderClient(this);

    client.requestLocationUpdates(LocationRequest.create(), pendingIntent)
        .addOnCompleteListener(new OnCompleteListener() {
          @Override
          public void onComplete(@NonNull Task task) {
            Log.d("MainActivity", "Result: " + task.getResult());
          }
        });
  }
}

新的API可以通过以下几种方式改进代码:

  • API调用自动等待服务连接建立,从而消除了onConnected在发出请求之前等待的需要。
  • 它使用Task API,使编写异步操作变得更加容易。
  • 代码是独立的,可以很容易地被移动到一个共享的实用程序类或类似的。
  • 你不需要了解开始编码的底层连接过程。

所有回调发生了什么?

新的API会自动解决你的某些连接失败,因此你需要编写代码以提示用户更新Google Play服务。连接问题将失败任务回调到ApiException而不是在全局曝光的连接故障onConnectionFailed)方法:

client.requestLocationUpdates(LocationRequest.create(), pendingIntent)
    .addOnFailureListener(new OnFailureListener() {
      @Override
      public void onFailure(@NonNull Exception e) {
        if (e instanceof ApiException) {
          Log.w(TAG, ((ApiException) e).getStatusMessage());
        } else {
          Log.w(TAG, e.getMessage());
        }
      }
    });

自己尝试一下

在自己的应用程序中尝试使用新的LocationServicesAPI,或者转到GitHub上的Android paly位置示例,并查看更多示例,说明新客户端如何减少样板和简化逻辑。

results matching ""

    No results matching ""