列出Google Drive中的文件,并获取Android中选定文件的下载URL
我试图从我的Android应用程序中显示用户在Google Drive上的文件列表,一旦用户选择了一个文件,我想获得该帐户的列出Google Drive中的文件,并获取Android中选定文件的下载URL,android,google-drive-api,google-drive-android-api,Android,Google Drive Api,Google Drive Android Api,我试图从我的Android应用程序中显示用户在Google Drive上的文件列表,一旦用户选择了一个文件,我想获得该帐户的下载URL和承载令牌,将其交给我的应用程序服务器下载 我一直在四处张望,似乎很困惑。谷歌硬盘有两个SDK和(RESTbased) 我成功地获得了文件列表,并使用Android SDK显示它(我不必构建任何UI),当用户选择一个文件时,我得到了关于该文件的所有信息,除了下载URL。我确实得到了一些链接,比如webContentLink和alternateLink,但事实证明,
下载URL
和承载令牌
,将其交给我的应用程序服务器下载
我一直在四处张望,似乎很困惑。谷歌硬盘有两个SDK和(REST
based)
我成功地获得了文件列表,并使用Android SDK显示它(我不必构建任何UI),当用户选择一个文件时,我得到了关于该文件的所有信息,除了下载URL
。我确实得到了一些链接,比如webContentLink
和alternateLink
,但事实证明,由于文件未共享,我无法将这些链接传递到我的服务器进行下载
经过进一步研究,我发现可以使用Java SDK访问下载URL
。我的问题是,我是否必须构建自己的UI来显示我获取的文件列表?如果必须构建UI来显示这些文件,如何处理文件夹层次结构
下面是打印有关文件的数据的代码。我已经基于实现了这段代码
公共类GoogleDriveActivity扩展活动{
私人GoogleapClient MGoogleapClient;
public com.google.api.services.drive.drive mService;
公共GoogleAccountCredential凭证;
公共静态最终int请求_授权=3;
公共静态最终整数请求\帐户\选择器=4;
私有静态最终字符串PREF\u ACCOUNT\u NAME=“accountName”;
私有静态最终字符串[]SCOPES={DriveScopes.DRIVE\u METADATA\u READONLY};
final HttpTransport transport=AndroidHttp.newCompatibleTransport();
final JsonFactory JsonFactory=GsonFactory.getDefaultInstance();
@凌驾
创建时受保护的void(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.activity\u google\u drive);
SharedReferences设置=getPreferences(Context.MODE\u PRIVATE);
凭证=GoogleAccountCredential.UsingAuth2(
getApplicationContext(),Arrays.asList(作用域))
.setBackOff(新的指数backoff())
.setSelectedAccountName(设置.getString(首选帐户名称),“abc。test@gmail.com"));
mService=new com.google.api.services.drive.drive.Builder(
运输、jsonFactory、凭证)
.setApplicationName(“我的应用程序”)
.build();
}
@凌驾
恢复时公开作废(){
super.onResume();
刷新结果();
}
@凌驾
受保护的void onActivityResult(int请求代码、int结果代码、意图数据){
开关(请求代码){
案例请求和授权:
if(resultCode!=结果\u确定){
选择帐户();
}
打破
案例请求\账户\选取者:
Log.w(“gd”,“账户内选择器”);
如果(resultCode==RESULT\u OK&&data!=null&&
data.getExtras()!=null){
字符串帐户名=
data.getStringExtra(AccountManager.KEY\u ACCOUNT\u NAME);
if(accountName!=null){
凭证.setSelectedAccountName(accountName);
共享引用设置=
getPreferences(Context.MODE_PRIVATE);
SharedReferences.Editor=settings.edit();
编辑器.putString(PREF_ACCOUNT_NAME,accountName);
commit();
}
}else if(resultCode==RESULT\u取消){
Log.W(“gd”,“取消中”);
}
打破
违约:
super.onActivityResult(请求代码、结果代码、数据);
打破
}
}
私有void chooseAccount(){
startActivityForResult(
credential.newchooseCountContent(),请求\帐户\选择器);
}
私有无效刷新结果(){
新的GoogleDriveAsync(this.execute();
}
公共类GoogleDriveAsync扩展了AsyncTask{
私人谷歌活动;
@凌驾
受保护的空位背景(空位…空位){
试一试{
getDataFromApi();
}捕获(最终GooglePlayServicesAvailabilityIOException可用性异常){
Log.w(“gd”、“GPS不可用”);
}捕获(UserRecoverableAuthIOException userRecoverableException){
Log.w(“gd”,“用户可恢复”);
activity.startActivityForResult(
userRecoverableException.getIntent(),
GoogleDriveActivity.请求授权);
}捕获(例外e){
Log.w(“gd”,“一般异常”+e.getMessage());
}
返回null;
}
GoogleDriveAsync(GoogleDriveActivity活动){
这个。活动=活动;
}
/**
*获取最多10个文件名和ID的列表。
*
*@返回描述文件的字符串列表,如果没有文件,则返回空列表
*找到了。
*@抛出异常
*/
私有列表getDataFromApi()引发IOException{
//获取最多10个文件的列表。
List fileInfo=new ArrayList();
FileList结果=activity.mService.files().list()
.setMaxResults(10)
.execute();
List files=result.getItems();
如果(文件!=null){
用于(文件:文件){
fileInfo.add(String.format(“%s(%s)(%s)\n”,
file.getTitle()、file.getId()、file.getDownloadUrl());
}
}
Log.w(“gd”,“文件信息为”+fileInfo.toString());
返回文件信息;
}
}
}
编辑:请查看我的答案(不是被接受的答案)以获取工作样本。用例是:列出用户的所有Google驱动器文件,选择其中一个后,获取downloadUrl
和access\u令牌
public class GoogleDriveActivity extends Activity {
private GoogleApiClient mGoogleApiClient;
public com.google.api.services.drive.Drive mService;
public GoogleAccountCredential credential;
public static final int REQUEST_AUTHORIZATION = 3;
public static final int REQUEST_ACCOUNT_PICKER = 4;
private static final String PREF_ACCOUNT_NAME = "accountName";
private static final String[] SCOPES = {DriveScopes.DRIVE_METADATA_READONLY};
final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_google_drive);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential = GoogleAccountCredential.usingOAuth2(
getApplicationContext(), Arrays.asList(SCOPES))
.setBackOff(new ExponentialBackOff())
.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, "abc.test@gmail.com"));
mService = new com.google.api.services.drive.Drive.Builder(
transport, jsonFactory, credential)
.setApplicationName("My Application")
.build();
}
@Override
public void onResume() {
super.onResume();
refreshResults();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_AUTHORIZATION:
if (resultCode != RESULT_OK) {
chooseAccount();
}
break;
case REQUEST_ACCOUNT_PICKER:
Log.w("gd", "in account picker");
if (resultCode == RESULT_OK && data != null &&
data.getExtras() != null) {
String accountName =
data.getStringExtra(AccountManager.KEY_ACCOUNT_NAME);
if (accountName != null) {
credential.setSelectedAccountName(accountName);
SharedPreferences settings =
getPreferences(Context.MODE_PRIVATE);
SharedPreferences.Editor editor = settings.edit();
editor.putString(PREF_ACCOUNT_NAME, accountName);
editor.commit();
}
} else if (resultCode == RESULT_CANCELED) {
Log.W("gd", "in cancelled");
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
private void chooseAccount() {
startActivityForResult(
credential.newChooseAccountIntent(), REQUEST_ACCOUNT_PICKER);
}
private void refreshResults() {
new GoogleDriveAsync(this).execute();
}
public class GoogleDriveAsync extends AsyncTask<Void, Void, Void> {
private GoogleDriveActivity activity;
@Override
protected Void doInBackground(Void... voids) {
try {
getDataFromApi();
} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
Log.w("gd", "GPS unavailable");
} catch (UserRecoverableAuthIOException userRecoverableException) {
Log.w("gd", "user recoverable");
activity.startActivityForResult(
userRecoverableException.getIntent(),
GoogleDriveActivity.REQUEST_AUTHORIZATION);
} catch (Exception e) {
Log.w("gd", "general exception " + e.getMessage());
}
return null;
}
GoogleDriveAsync(GoogleDriveActivity activity) {
this.activity = activity;
}
/**
* Fetch a list of up to 10 file names and IDs.
*
* @return List of Strings describing files, or an empty list if no files
* found.
* @throws IOException
*/
private List<String> getDataFromApi() throws IOException {
// Get a list of up to 10 files.
List<String> fileInfo = new ArrayList<String>();
FileList result = activity.mService.files().list()
.setMaxResults(10)
.execute();
List<File> files = result.getItems();
if (files != null) {
for (File file : files) {
fileInfo.add(String.format("%s (%s) (%s)\n",
file.getTitle(), file.getId(), file.getDownloadUrl()));
}
}
Log.w("gd", "file info is " + fileInfo.toString());
return fileInfo;
}
}
}
DriveId driveId = metadata.getDriveId();
String resourceId = driveId.getResourceId();
public class GoogleDriveActivity extends Activity implements
GoogleApiClient.OnConnectionFailedListener, GoogleApiClient.ConnectionCallbacks {
private GoogleApiClient mGoogleApiClient;
final HttpTransport transport = AndroidHttp.newCompatibleTransport();
final JsonFactory jsonFactory = GsonFactory.getDefaultInstance();
public static final int REQUEST_CODE_RESOLUTION = 1;
public static final int REQUEST_CODE_SELECT = 2;
private static final String[] SCOPES = { DriveScopes.DRIVE_FILE};
private static final String TAG = "GoogleDrive";
private String accountName;
@Override
protected void onResume() {
super.onResume();
setupGoogleClient();
}
@Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient != null) {
mGoogleApiClient.disconnect();
}
}
@Override
public void onConnected(Bundle bundle) {
IntentSender intentSender = Drive.DriveApi
.newOpenFileActivityBuilder()
.build(mGoogleApiClient);
AccountManager manager = (AccountManager) getSystemService(ACCOUNT_SERVICE);
Account[] list = manager.getAccountsByType("com.google");
//Getting the first account because that is the primary account for that user
accountName = list[0].name;
try {
startIntentSenderForResult(intentSender, REQUEST_CODE_SELECT, null, 0, 0, 0);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, "Unable to send intent to connect to Google API client " + e.getMessage());
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
if (!connectionResult.hasResolution()) {
return;
}
try {
connectionResult.startResolutionForResult(this, REQUEST_CODE_RESOLUTION);
} catch (IntentSender.SendIntentException e) {
Log.w(TAG, "Unable to send intent to connect to Google API client " + e.getMessage());
}
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
switch (requestCode) {
case REQUEST_CODE_SELECT:
if (resultCode == RESULT_OK) {
DriveId driveId = data.getParcelableExtra(OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
String resourceId = driveId.getResourceId();
new GoogleDriveAsync(this).execute(resourceId);
}
finish();
break;
case REQUEST_CODE_RESOLUTION:
if (resultCode == RESULT_OK) {
mGoogleApiClient.connect();
}
break;
default:
super.onActivityResult(requestCode, resultCode, data);
break;
}
}
@Override
public void onConnectionSuspended(int i) {
Log.w(TAG, "Connection to Google API client suspended");
}
private void setupGoogleClient() {
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addApi(Drive.API)
.addScope(Drive.SCOPE_FILE)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
}
mGoogleApiClient.connect();
}
class GoogleDriveAsync extends AsyncTask<String, Void, Void> {
private GoogleDriveActivity activity;
GoogleDriveAsync(GoogleDriveActivity activity) {
this.activity = activity;
}
@Override
protected Void doInBackground(String... args) {
try {
String id = args[0];
GoogleAccountCredential credential = GoogleAccountCredential.usingOAuth2(getApplicationContext(), Arrays.asList(SCOPES));
credential.setBackOff(new ExponentialBackOff());
credential.setSelectedAccountName(accountName);
com.google.api.services.drive.Drive service = new com.google.api.services.drive.Drive.Builder(transport, jsonFactory, credential).build();
File file = service.files().get(id).setFields("downloadUrl").execute();
if (file != null) {
String strUrl = file.getDownloadUrl();
String token = GoogleAuthUtil.getToken(activity, accountName, "oauth2: " + Drive.SCOPE_FILE);
//This is your downloadUrl and token
Log.w(TAG, "download link is " + strUrl + " and token is " + token);
}
} catch (final GooglePlayServicesAvailabilityIOException availabilityException) {
Log.w(TAG, "Google Play Services not available to get downloadUrl of selected file");
} catch (UserRecoverableAuthIOException userRecoverableException) {
Log.w(TAG, "User authorization error in getting downloadUrl " + userRecoverableException.getMessage());
} catch (Exception e) {
Log.w(TAG, "Exception in getting downloadUrl " + e.getMessage());
}
return null;
}
}
}
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<activity
android:name="com.myapp.GoogleDriveActivity"
android:label="@string/app_name"
<meta-data android:name="com.google.android.apps.drive.APP_ID" android:value="id=<your-gogole-project-id>"/>
</activity>
compile 'com.google.android.gms:play-services-drive:7.8.0'
compile 'com.google.api-client:google-api-client:1.20.0'
compile 'com.google.api-client:google-api-client-android:1.20.0'
compile 'com.google.api-client:google-api-client-gson:1.20.0'
compile 'com.google.apis:google-api-services-drive:v2-rev170-1.20.0'