如何在Android应用程序中设置Google驱动器凭据?
该应用程序在“谷歌API控制台”中注册为“已安装应用程序”-似乎这是Android应用程序的正确设置,不是吗 所以我确实有一个客户端Id,没有秘密Id。为了澄清这一点:它不是Web应用程序,也不是Google Drive应用程序——它是一个Android应用程序,可以访问Google Drive云中的其他用户数据 在应用程序中,我获取帐户(works),并请求令牌(works)。现在我想用这个令牌和客户端Id连接到Google Drive。结果是“401,无效凭证”。这个代码怎么了如何在Android应用程序中设置Google驱动器凭据?,android,oauth-2.0,google-drive-api,Android,Oauth 2.0,Google Drive Api,该应用程序在“谷歌API控制台”中注册为“已安装应用程序”-似乎这是Android应用程序的正确设置,不是吗 所以我确实有一个客户端Id,没有秘密Id。为了澄清这一点:它不是Web应用程序,也不是Google Drive应用程序——它是一个Android应用程序,可以访问Google Drive云中的其他用户数据 在应用程序中,我获取帐户(works),并请求令牌(works)。现在我想用这个令牌和客户端Id连接到Google Drive。结果是“401,无效凭证”。这个代码怎么了 public
public class ActivityMain extends Activity implements DialogInterface.OnClickListener {
// https://developers.google.com/drive/scopes
private static final String AUTH_TOKEN_TYPE = "oauth2:https://www.googleapis.com/auth/drive";
// https://code.google.com/apis/console/
private static final String CLIENT_ID = "999999999999999.apps.googleusercontent.com";
private AccountManager accountManager;
private Account[] accounts;
private String authName;
private String authToken;
@Override
public void onClick(final DialogInterface dialogInterface, final int item) {
processAccountSelected(accounts[item]);
}
@Override
public void onCreate(final Bundle bundle) {
super.onCreate(bundle);
setContentView(R.layout.activitymain);
accountManager = AccountManager.get(this);
accounts = accountManager.getAccountsByType("com.google");
if (accounts == null || accounts.length == 0) {
// TODO
} else if (accounts.length == 1) {
processAccountSelected(accounts[0]);
} else if (accounts.length > 1) {
showDialog(MyConstants.DIALOG_ACCOUNTCHOSER);
}
}
@Override
protected Dialog onCreateDialog(final int id) {
switch (id) {
case MyConstants.DIALOG_ACCOUNTCHOSER:
AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder(this);
String[] names = new String[accounts.length];
for (int i = 0; i < accounts.length; i++) {
names[i] = accounts[i].name;
}
alertDialogBuilder.setItems(names, this);
alertDialogBuilder.setTitle("Select a Google account");
return alertDialogBuilder.create();
}
return null;
}
private void processAccountSelected(final Account account) {
if (account != null) {
authName = account.name.toString();
if (!Tools.isEmpty(authName)) {
Toast.makeText(this, authName, Toast.LENGTH_LONG).show();
accountManager.getAuthToken(account, AUTH_TOKEN_TYPE, null, this,
new AccountManagerCallback<Bundle>() {
public void run(final AccountManagerFuture<Bundle> future) {
try {
authToken = future.getResult().getString(
AccountManager.KEY_AUTHTOKEN);
processTokenReceived();
} catch (OperationCanceledException exception) {
// TODO
} catch (Exception exception) {
Log.d(this.getClass().getName(), exception.getMessage());
}
}
}, null);
}
}
}
private void processListFiles(final Drive drive) {
List<File> result = new ArrayList<File>();
Files.List request = null;
try {
request = drive.files().list();
} catch (IOException exception) {
}
do {
try {
FileList files = request.execute();
result.addAll(files.getItems());
request.setPageToken(files.getNextPageToken());
} catch (IOException exception) {
// --> 401 invalid credentials
}
} while (request.getPageToken() != null && request.getPageToken().length() > 0);
}
private void processTokenReceived() {
if (!Tools.isEmpty(authToken)) {
final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = new GsonFactory();
GoogleCredential credential = new GoogleCredential();
credential.setAccessToken(authToken);
Drive drive = new Drive.Builder(transport, jsonFactory, credential)
.setApplicationName(getString(R.string.txt_appname))
.setJsonHttpRequestInitializer(new GoogleKeyInitializer(CLIENT_ID))
.build();
if (drive != null) {
processListFiles(drive);
}
}
}
}
是的,文档很难理解 换衣服
new GoogleKeyInitializer(CLIENT_ID)
到
它应该会起作用
您可以在Google的API访问页面的SIMPLE API访问部分(API键)下找到您的
SIMPLE API访问
。如果此部分不可用,您必须首先激活服务页面上的驱动器API访问。我尝试了所有这些,最后发现此代码可用于google日历API。我过去每次使用谷歌认证并将其传递给构建时都会得到401
HttpTransport transport = AndroidHttp.newCompatibleTransport();;
JsonFactory jsonFactory = new GsonFactory();
HttpRequestInitializer httpRequestInitializer;
Log.i("Reached calendar builder", "Reached calendar builder"+accessToken);
//GoogleCredential credential = new GoogleCredential();
httpRequestInitializer = new HttpRequestInitializer(){
public void initialize(HttpRequest request) throws IOException
{
request.getHeaders().setAuthorization(GoogleHeaders.getGoogleLoginValue(accessToken));
}
};
Calendar service = new Calendar.Builder(transport, jsonFactory, httpRequestInitializer)
.setApplicationName("Meetrbus/1.0")
.setJsonHttpRequestInitializer(new GoogleKeyInitializer("API_KEY"))
.build();
}
您包含的代码段有两个问题
authToken
之前,必须使旧的authToken无效
AccountManager.get(activity).invalidateAuthToken("com.google", authToken);
accountManager.getAuthToken(...);
setJsonHttpRequestInitializer
必须使用在项目的API控制台中声明的简单API键
- 可通过访问以下网站获取
- 单击左侧菜单上的API访问
- 查找简单API访问,并复制API密钥
- 在构建驱动器对象时设置API键 .setJsonHttpRequestInitializer(新的Google键初始值设定项(键))
这里有一个小样本演示了令牌失效:我在这里给出了关于在Android上使用Google Drive的详细答案: 使用我在答案中列出的方法,我可以确认您能够做到以下几点:
- 设置和访问元数据
- 上传文件
- 下载文件
- 在Google驱动器目录之间移动文件
- 完全从驱动器中删除文件
credential.setAccessToken(authToken)
在构建任务
实例之后。也许交换这两行就行了?运气不好。好像有东西坏了。无论如何,谢谢。@HaraldWilhelm我想告诉你我非常广泛的答案,包括如何在没有401错误的情况下下载文件(我已经更新了它,在答案的Android代码部分末尾包含了下载代码),在这里:谢谢你的回答。它不起作用。我用简单的API键->401尝试了您的精确代码。我的应用程序是一个“已安装的应用程序”,其客户端Id取自API控制台。我怀疑一个简单的API密钥与一个“已安装的应用程序”结合使用是否有效。你是否成功地制作了一个可以从Google Drive下载文件的Android应用程序?如果是这样的话,你介意分享代码吗?据我所知,我有一个最完整的驱动应用程序,不是谷歌的,它可以在Android上运行,而且我无法下载文件(我总是会遇到401错误……不知何故,我有权完全删除文件,或者完全更改文件内容,但不下载当前内容。)我的代码如下:
HttpTransport transport = AndroidHttp.newCompatibleTransport();;
JsonFactory jsonFactory = new GsonFactory();
HttpRequestInitializer httpRequestInitializer;
Log.i("Reached calendar builder", "Reached calendar builder"+accessToken);
//GoogleCredential credential = new GoogleCredential();
httpRequestInitializer = new HttpRequestInitializer(){
public void initialize(HttpRequest request) throws IOException
{
request.getHeaders().setAuthorization(GoogleHeaders.getGoogleLoginValue(accessToken));
}
};
Calendar service = new Calendar.Builder(transport, jsonFactory, httpRequestInitializer)
.setApplicationName("Meetrbus/1.0")
.setJsonHttpRequestInitializer(new GoogleKeyInitializer("API_KEY"))
.build();
}
AccountManager.get(activity).invalidateAuthToken("com.google", authToken);
accountManager.getAuthToken(...);