GoogleServices之GooglePlayService Accessing Google APIS(访问谷歌APIS)官方文档翻译
GoogleServices之GooglePlayService Accessing Google APIS(访问谷歌APIS)官方文档翻译
AccessingGoogle APIs(访问谷歌APIS)
当你想要连接到一个GoogleplayService库中提供的API,(比如:google+,Games,或者drive),你需要创建一个GoogleApiClient
的实例。Google API Client提供了一个公共的入口点给所有的谷歌服务以及在用户设备和每个谷歌服务之间管理网络连接。
这个指南示例你如何使用Google API Client:
1, 连接到一个或者多个Googleplayservice是异步的和失败处理。
2, 执行同步和异步API调用很多Google APIClient
注意:如果你已经有先有的应用使用子类GooglePlayServicesClient
连接到Googleplayservice,你应当尽可能迁移到GoogleApiClient
。
图1.一个插图显示了Google APS客户端是如何给连接和调用许多有效的Google Play services 提供接口,像 Games和Drive
Connecting toREST APIs
如果你想使用GoogleAPI,但不包括Google Play services,你可以适当的RESTAPI连接,但是你必须获取一个 OAuth 2.0的令牌。获取更多信息,请阅读:Authorizing with Google for REST APIs.
开始前,你必须先安装GooglePlay services库(版本号为15或者更高)为你的安卓SDK。如果你还没有准备好,请按照以下说明去做:Set Up Google Play Services SDK.
Start a Connection 开始连接
一旦你的项目引用Google Play services 库,你就可以使用GoogleApiClient.Builder
APIs在你的activity的oncreate方法里创建GoogleApiClient
实例。 GoogleApiClient.Builder
这个类提供的方法允许你指定你想使用的Google APIs和你想得到的OAuth 2.0作用域。例如:这里是一个GoogleApiClient
使用Google Drive service连接的实例。
GoogleApiClient mGoogleApiClient=new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.build();
你可以通过追加addApi()
和 addScope()
.添加多个APIS和多个scopes给相同的 GoogleApiClient
。
重点:为了避免客户端在没有安装Android Wear app的设备上连接错误,请使用一个单独的 GoogleApiClient
实例仅仅访问 Wearable
API。获取更多的信息,请看:Access the Wearable API
在开始连接之前你要调用GoogleApiClient
的connect()
方法,你必须为回调接口 ConnectionCallbacks
and OnConnectionFailedListener
指定一个实现。当连接Google Play services成功,失败或者暂停时这些接口会接受异步方法connect()
的回调。
例如:这里是一个实现了回调接口并且将他们添加到GoogleAPI客户端的activity
import gms.common.api.*;
import gms.drive.*;
import android.support.v4.app.FragmentActivity;
public classMyActivityextendsFragmentActivity
implements ConnectionCallbacks, OnConnectionFailedListener {
private GoogleApiClient mGoogleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
// Create a GoogleApiClient instance
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
...
}
@Override
public void onConnected(Bundle connectionHint){
// Connected to Google Play services!
// The good stuff goes here.
}
@Override
public void onConnectionSuspended(int cause){
// The connection has been interrupted.
// Disable any UI components that depend on Google APIs
// until onConnected() is called.
}
@Override
public void onConnectionFailed(ConnectionResult result){
// This callback is important for handling errors that
// may occur while attempting to connect with Google.
//
// More about this in the next section.
...
}
}
定义了回调接口,你将准备调用connect()
. 为了优雅的管理连接的生命周期,你应该调用connect()
. 在activity的onStart()方法(除非你想晚一点连接)然后调用disconnect()
在onStop()方法中。例如:
@Override
protected void onStart(){
super.onStart();
if (!mResolvingError){ // more about this later
mGoogleApiClient.connect();
}
}
@Override
protected void onStop(){
mGoogleApiClient.disconnect();
super.onStop();
}
但是,如果您运行这段代码时,很有可能会失败,应用程序将接收调用onConnectionFailed()并发生SIGN_IN_REQUIRED错误,因为没有指定的用户帐户,下一节将展示如何处理这个错误等等。
Handleconnection failures(处理连接失败)
当你接收回调调用onConnectionFailed()
,你应该调用ConnectionResult
对象提供的 hasResolution()
方法。如果返回true,你可以请求用户立即采取行动通过调用ConnectionResult对象的startResolutionForResult()
方法处理错误。这个 startResolutionForResult()
方法的行为跟startActivityForResult()
比较相似,并启动适当的activity为用户解决错误(比如像一个选择账户的acticity)
如果hasResolution()
返回false,你应该通过错误代码调用 GooglePlayServicesUtil.getErrorDialog()
,它会通过GooglePlayServices适当的错误给你返回一个dialog. 这个对话框 提供了一个简单的错误解释信息,但他也有肯呢过提供一个action去启动一个activity去解决错误(比如当用户需要安装新版本的GoogleplayService)
比如,你应该像这样调用 onConnectionFailed()
public class MyActivity extends FragmentActivity
implements ConnectionCallbacks, OnConnectionFailedListener {
// Requestcode to use when launching the resolution activity
private staticfinalint REQUEST_RESOLVE_ERROR=1001;
// Uniquetag for the error dialog fragment
private staticfinalString DIALOG_ERROR="dialog_error";
// Bool totrack whether the app is already resolving an error
private boolean mResolvingError=false;
...
@Override
public void onConnectionFailed(ConnectionResult result){
if (mResolvingError){
// Already attempting to resolve an error.
//如果正在解决这个错误,什么也不做
return;
} elseif(result.hasResolution()){
try {
mResolvingError = true;
result.startResolutionForResult(this, REQUEST_RESOLVE_ERROR);
} catch(SendIntentException e){
// There was an error with theresolution intent. Try again.
mGoogleApiClient.connect();
}
} else{
// Show dialog usingGooglePlayServicesUtil.getErrorDialog()
showErrorDialog(result.getErrorCode());
mResolvingError = true;
}
}
// The restof this code is all about building the error dialog
/* Creates adialog for an error message */
private void showErrorDialog(int errorCode){
// Create a fragment for the error dialog
ErrorDialogFragment dialogFragment = new ErrorDialogFragment();
// Pass the error that should be displayed
Bundle args = new Bundle();
args.putInt(DIALOG_ERROR, errorCode);
dialogFragment.setArguments(args);
dialogFragment.show(getSupportFragmentManager(),"errordialog");
}
/* Calledfrom ErrorDialogFragment when the dialog is dismissed. */
public void onDialogDismissed(){
mResolvingError = false;
}
/* Afragment to display an error dialog */
public staticclassErrorDialogFragmentextendsDialogFragment{
public ErrorDialogFragment(){}
@Override
public Dialog onCreateDialog(Bundle savedInstanceState){
// Get the error code and retrieve theappropriate dialog
int errorCode = this.getArguments().getInt(DIALOG_ERROR);
return GooglePlayServicesUtil.getErrorDialog(errorCode,
this.getActivity(), REQUEST_RESOLVE_ERROR);
}
@Override
public void onDismiss(DialogInterface dialog){
((MainActivity)getActivity()).onDialogDismissed();
}
}
}
一旦用户通过提供的 startResolutionForResult()
orGooglePlayServicesUtil.getErrorDialog()
完成解决,你的activity会在onActivityResult()方法里接受处理结果码RESULT_OK
。你可以继续调用connect()
比如:
@Override
protected void onActivityResult(int requestCode,int resultCode,Intent data){
if (requestCode== REQUEST_RESOLVE_ERROR){
mResolvingError = false;
if (resultCode== RESULT_OK){
// Make sure the app is not alreadyconnected or attempting to connect
if (!mGoogleApiClient.isConnecting()&&
!mGoogleApiClient.isConnected()){
mGoogleApiClient.connect();
}
}
}
}
在上面的代码中,你可能注意到布尔变量mResolvingError。他追踪应用状态当用户正在解决错误时避免重复尝试解决相同的问题。例如,当选择用户的对话框正在展现解决SIGN_IN_REQUIRED
这个错误,用户有可能旋转屏幕。就会再次调用OnStart()重新展现你的activity,这个时候再次调用 connect()
。就会有一次调用startResolutionForResult()
返回相同的结果并创建有一个账户选择对话框展现在已存在的对话框前面。
这个布尔值会有效的在activity切换时被保存起来,下一节将做进一步解释。
Maintainstate while resolving an error
解决错误并维护状态
为了避免之前尝试解决错误时又执行 onConnectionFailed()
中的代码,你需要保留一个布尔变量来跟踪你的应用当前是否在解决这个问题。
上面的代码示例,你应该在每次调用 startResolutionForResult()
或者从GooglePlayServicesUtil.getErrorDialog()
得到一个显示的对话框都要设置一个布尔值为true.知道你在onActivityResult()方法中接收到处理结果为 RESULT_OK
时再次将布尔值设置为false.
为保持布尔值在acticity重启时不会变化,应该将布尔值保存在onSaveInstanceState()
:中
private static final String STATE_RESOLVING_ERROR = "resolving_error";
@Override
protected void onSaveInstanceState(Bundle outState){
super.onSaveInstanceState(outState);
outState.putBoolean(STATE_RESOLVING_ERROR, mResolvingError);
}
然后在oncreat()中恢复保存的状态:
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
...
mResolvingError = savedInstanceState != null
&& savedInstanceState.getBoolean(STATE_RESOLVING_ERROR,false);
}
现在你可以安全的运行你的应用并连接到googleplayservice.如何使用 GoogleApiClient
去执行读取和写入请求 Google Play services,下一节讨论:
Accessthe Wearable API(方位穿戴API)
在没有安装Android Wear app的设备上,连接请求包含 Wearable
API 会发生错误,错误码为API_UNAVAILABLE
。如果你的应用除了访问其他的Google APIs 还要访问Wearable
API ,使用一个单独的GoogleApiClient
实例去访问Wearable
API。这个方法使您在不用搭配穿戴设备上能够访问其他的Google APIs。
当你使用单独的GoogleApiClient
实例仅仅去访问Wearable API,你要确定Android Wear app在设备上是否已经安装。
// Connection failed listener method for a client thatonly
// requestsaccess to the Wearable API
@Override
public void onConnectionFailed(ConnectionResult result){
if (result.getErrorCode()==ConnectionResult.API_UNAVAILABLE){
// The Android Wear app is not installed
}
...
}
Communicate with Google Services
与谷歌服务通信
一旦连接,你的客户端就能使用特定的服务APIS为你的应用授权读写调用。按照特定的API和范围你添加你的 GoogleApiClient
实例。
注意:之前调用特定的谷歌服务,你可能首先需要在谷歌开发者控制台注册你的APP.特定的说明请参考适合你所用的API入门指南。诸如:Google Drive or Google+
当你使用Google API Client,执行读写请求的时候,他立即作为一个PendingResult
对象返回。这是一个表示请求的对象,他还没有交付给谷歌服务。
例如:这是一个从 Google Drive请求读取文件提供的PendingResult
对象,
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, filename));
PendingResult result = Drive.DriveApi.query(mGoogleApiClient, query);
一旦你有了这个 PendingResult
,你可以继续使用同步或者异步请求。
Usingasynchronous calls 使用异步调用
为了使用异步请求,PendingResult
需要调用 setResultCallback()
并提供一个实现ResultCallback
接口的实现类。例如,这是执行异步请求:
private void loadFile(String filename){
// Create aquery for a specific filename in Drive.
Query query =newQuery.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, filename))
.build();
// Invokethe query asynchronously with a callback method
Drive.DriveApi.query(mGoogleApiClient, query)
.setResultCallback(newResultCallback<DriveApi.MetadataBufferResult>(){
@Override
public void onResult(DriveApi.MetadataBufferResult result) {
// Success! Handle the query result.
...
}
});
}
当你的应用在 onResult()
方法中收到一个Result
对象时,他将按照你使用的Api交付相应子类的实例,比如:DriveApi.MetadataBufferResult
.
Usingsynchronous calls 使用同步调用
如果你想要你的代码按照你严格定义的顺序运行,或许因为一个调用的结果是另一个需要的参数,你可以使用 PendingResult
.的 await()
方法进行同步请求。这个阻塞线程会交付一个你使用API的子类实例直到请求完成后返回结果。如:MetadataBufferResult
因为调用await()会阻塞线程知道结果返回,重点是你永远不要在你的UI线程中调用执行。所以你想执行同步请求Googleplayservices,你应该创建一个新的线程,比如使用AsyncTask执行这个请求。例如:这里是如何使用同步请求googlepalyservice访问相同的文件。
private void loadFile(String filename){
new GetFileTask().execute(filename);
}
private classGetFileTaskextendsAsyncTask<String,Void,Void> {
protected void doInBackground(String filename){
Query query = new Query.Builder()
.addFilter(Filters.eq(SearchableField.TITLE, filename))
.build();
// Invoke the query synchronously
DriveApi.MetadataBufferResult result=
Drive.DriveApi.query(mGoogleApiClient, query).await();
// Continue doing other stuff synchronously
...
}
}
小提示:你也可以队列阅读请求而不用连接 Google Play services.。例如:不管Google API Client是否连接,执行一个方法从Google Drive读取文件,然后一旦确立了连接,就会执行读取请求并接收结果。然而,当你的Google API Client 没有连接的时候如果你调用他们进行写入请求将会发生错误。
GoogleServices之GooglePlayService Accessing Google APIS(访问谷歌APIS)官方文档翻译相关推荐
- 没法访问谷歌 wifi_如何设置Google WiFi系统
没法访问谷歌 wifi Mesh Wi-Fi networking is all the rage lately, and even Google has gotten in on the fun. ...
- Google镜像搭建:利用 Cloudflare Workers 搭建访问谷歌镜像站点,可自行绑定域名
利用 Cloudflare Workers 搭建访问谷歌镜像站点 CF-Worker-Dir是一款适用于Cloudflare Worker平台上的云函数程序,可以使用它在一分钟内搭建属于自己的站点. ...
- Google Colab——用谷歌免费GPU跑你的深度学习代码
Google Colab简介 Google Colaboratory是谷歌开放的一款研究工具,主要用于机器学习的开发和研究.这款工具现在可以免费使用,但是不是永久免费暂时还不确定.Google Col ...
- Google Spanner:谷歌的全球分布式数据库
目录 1. 介绍 2. 实现 3. TrueTime 4. 并发控制 5. 实验分析 6. 相关工作 7. 未来的工作 8. 总结 Spanner: Google' s Globally-Distri ...
- Gmail,google.com等谷歌英文网站被封解决办法
<script type="text/javascript"></script> <script src="http://pagead2.g ...
- Google中国(谷歌)汉化大事记
Google从微软挖来李开复,让其掌舵Google中国,这有了一个熟悉中国市场的领导人.李开复在中国素有"学生教父"之称,在中国青年学生中的口碑非常好.当初他单枪匹马创办微软中国研 ...
- 【历史上的今天】4 月 12 日:Google 中文名称谷歌发布;Fire TV 问世;登上太空的计算器
整理 | 王启隆 透过「历史上的今天」,从过去看未来,从现在亦可以改变未来. 今天是 2022 年 4 月 12 日,每年的这一天是世界航天日,全名载人空间飞行国际日:在 1961 年的 4 月 12 ...
- Google中文名定“谷歌” CEO施密特来华揭名
Google中文名定"谷歌" CEO施密特来华揭名 2006年04月13日 09:16:27 来源:本网综合 [字号 大 中 小] [留言] [打印] [关闭] [Email推荐 ...
- Google百度和谷歌的那些事
这篇文章很棒,我读了多遍.觉得应该让更多人读到,所以转载了. -- Google百度和谷歌的那些事 作者: virushuo 发表于 2010-01-14 22:01 最后更新于 2010-01-14 ...
最新文章
- 【小白的CFD之旅】16 流程
- Go 指针 unsafe.Pointer
- linux笔记之 搭建本地yum源,网卡的基本操作
- 和套套一样,一次性橡胶手套制作现场, 这鬼畜的画风
- idea中HTML可以打debug吗,Intellij IDEA中使用Debug调试
- 被引用的外部JS存在window.onload时,判断当前页面是否已存在window.onload,并进行相应处理...
- JAVA中注解controller_SpringMVC之基于注解的Controller
- 微软企业库4.1学习笔记(三十六)日志模块 简介
- virbr0 虚拟网卡卸载方法
- 云原生数据仓库从托管到原生的演进实践
- 金蝶软件和用友软件部署在阿里云ECS具体方法及教程
- 微信支付商户朋友圈广告
- 公务员计算机职称有哪些,2017职称考试有哪些
- android 矢量粒子动画,Android碎裂的粒子效果
- 某Java大佬在地表最强Java企业(阿里)面试总结
- 人们说程序员很高大上,程序员是做编程的,编程又是做什么呢?
- FM立体声 matlab 左右,FM立体声收音机的制作
- 软件的生命周期SDLC
- U盘Linux启动引导
- 基于数据结构和C语言实现公交管理系统(含文档和代码)数据结构课程设计