我想为Google云端硬盘设计Android文件查看器。
首先,我使用Google Android API实现了该应用,如下所示,
private void retrieveNextPage(){
if(mHasMore == false)
return;
Query query = new Query.Builder().setPageToken(mNextPageToken).build();
com.google.android.gms.drive.Drive.DriveApi.query(getGoogleApiClient(), query).setResultCallback(metadataBufferResultResultCallback);
}
但是,Android Drive API仅允许应用查看和获取自己创建的文件。我无法通过应用程序访问驱动器上的其他文件。
因此,我转向另一个选项,直接操作Java Drive API。
根据Java开发者指南中的示例,
https://developers.google.com/drive/web/quickstart/quickstart-java
用户必须手动复制并粘贴"授权码"在浏览器和应用程序之间,这不是在Android中获取访问令牌的实用方法。
为了采用新方法,我使用Android API中的GoogleAuthUtil
获取访问令牌,与Java API中的GoogleCredential
和Drive
一致,以获取文件列表,如下,
private static List<File> retrieveFiles(Drive service) throws IOException{
List<File> result = new ArrayList<File>();
Files.List request = service.files().list();
do {
try{
FileList fileList = request.execute();
result.addAll(fileList.getItems());
request.setPageToken(fileList.getNextPageToken());
}catch (IOException e){
Log.d(dbgT + "JavaRetrieveFiles", "Retrieved Failed");
request.setPageToken(null);
}
}while (request.getPageToken() != null && request.getPageToken().length() > 0);
return result;
}
private class RetrieveTokenTask extends AsyncTask<String, Void, String>{
@Override
protected String doInBackground(String... params){
String accountName = params[0];
String scopes = "oauth2:" + "https://www.googleapis.com/auth/drive";
String token = null;
try{
token = GoogleAuthUtil.getToken(getApplicationContext(), accountName, scopes);
}
catch (IOException e){
Log.e(excpTAG, "IO Exception: " + e.getMessage());
}
catch (UserRecoverableAuthException e){
startActivityForResult(e.getIntent(), REQ_SIGN_IN_REQUIRED);
}
catch (GoogleAuthException e)
{
Log.e(excpTAG, "GoogleAuthException: " + e.getMessage());
}
return token;
}
@Override
protected void onPostExecute(String s){
super.onPostExecute(s);
//Get Access Token
Log.d( dbgT + "Token", s);
EditText tokenText = (EditText) findViewById(R.id.tokenText);
tokenText.setText(s);
EditText fileNameText = (EditText) findViewById(R.id.editTextMeta);
GoogleCredential credential = new GoogleCredential().setAccessToken(s);
HttpTransport httpTransport = new NetHttpTransport();
JsonFactory jsonFactory = new JacksonFactory();
Drive service = new Drive.Builder(httpTransport, jsonFactory, null).setHttpRequestInitializer(credential).build();
List<File> fileList;
try{
fileList = retrieveFiles(service);
for(int i=0; i< fileList.size(); i++)
fileNameText.append(fileList.get(i).getTitle());
}catch(IOException e){
Log.d(dbgT + "RetrieveFileList", "IO Exception" );
}
}
}
不幸的是,当调用request.execute()
中的retrieveFiles
时,应用程序始终因 NetworkOnMainThreadException 的原因而崩溃。
我检查了访问令牌s
,它通常采用ya29.xxx...etc.
的形式,也可以传递给我的其他.NET程序,以便从Google云端硬盘中检索文件。因此,我可以确定访问令牌是正确的。
所以我的问题是,如何使用访问令牌创建正确的GoogleCredential,而不是在setFromTokenResponse
中应用授权代码?
提前致谢。
答案 0 :(得分:1)
Google Drive SDK for Java中的Drive
,使用没有任何后台/线程工作者的网络库,现在它在我将retrieveFiles()
置于后台后正常运行。
在Google Play Android SDK中应用GoogleAuthUtil
获取访问令牌,然后在Java SDK中使用GoogleCredential
+ Drive
使用令牌在Google云端硬盘中执行文件操作
这是避免Android SDK for Google Drive中范围限制的正确方法,允许开发人员获得访问Google云端硬盘的完全许可。