有人可以为 Google Drive REST API v3 提供最新的 Android 指南吗? [英] Can someone provide an up-to-date Android guide for Google Drive REST API v3?

查看:22
本文介绍了有人可以为 Google Drive REST API v3 提供最新的 Android 指南吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我自己和许多其他人一直在努力设置 Google Drive REST API v3 以与 Android 应用一起使用.这主要是因为官方 Google 文档缺少适用于 Android 的正确快速入门指南,我们只能找到散布在周围的(过时和/或令人困惑的)信息碎片 - 但需要的是完整的 针对初学者的最新指南,帮助他们启动和运行我们,以便他们可以打开和编辑云端硬盘上的文件,包括如何设置凭据、依赖项和清单.

Myself and many others have been struggling with setting up the Google Drive REST API v3 to work with Android apps. This mainly stems from the fact that the official Google documentation is missing a proper quick start guide for Android and we are left with finding scraps of (outdated and/or confusing) information dotted around - but what is needed is a complete up to date guide aimed at beginners to get us up and running so that they can open and edit files on their Drive, including how to set up credentials, dependencies, and manifests.

所以我问是否有人愿意创建这样的指南,或者可以指出已经制作的这样的指南 a) 与最新版本的 Google Drive API REST v3 相关,详细 此处 和 b) 涵盖了初学者需要开始的所有上述方面?

So I am asking if anyone would be willing to create such a guide, or can point to such a guide that has already been made that is a) relevant to the latest version of Google Drive API REST v3 detailed here and b) covers ALL above aspects that a beginner would need to be get started?

ArtOfWarfare 发布的指南这里绝对完美,正是我所期待的for - 但不幸的是已经过时了几年.谁能提供本指南的最新版本?谢谢你.

The guidelines posted by ArtOfWarfare here are absolutely perfect and exactly what I'm looking for - but are unfortunately out of date by several years. Can anyone provide an up-to-date version of this guide? Thank you kindly.

推荐答案

在回答这个问题之前,我想让你知道我从这里得到了代码 (https://ammar.lanui.online/integrate-google-drive-rest-api-on-android-app-bc4ddbd90820) 和 Google 的文档对我没有多大帮助.所以这个解决方案来自我可用的有限资源.

Before answering this question I want you to know that I got the code from here (https://ammar.lanui.online/integrate-google-drive-rest-api-on-android-app-bc4ddbd90820) and the documentation from Google was not much helpful for me. So this solution is from limited resources available to me.

我需要驱动器来从我的应用上传和下载文件.在驱动器中,我必须创建一个文件夹,我必须将文件从我的应用程序上传到该文件夹​​并将文件从该文件夹下载到我的设备.这段代码对我来说很好用.

I need the drive to upload and download files from my app. In drive I have to create a folder and I have to upload file from my app to that folder and download a file from the folder to my device. This code was working fine for me.

我相信您一定已经完成了 Google 登录.如果没有,请查看此视频 (https://youtu.be/t-yZUqthDMM).

I believe that you must have completed Google login. If you don’t, go checkout this video (https://youtu.be/t-yZUqthDMM) .

要与 Drive API 交互,您需要为您的应用启用 Drive API 服务.您可以在 Google Developer Console 中执行此操作.

To interact with the Drive API, you need to enable the Drive API service for your app. You can do this in Google Developer Console.

要启用 Drive API,请完成以下步骤:

To enable the Drive API, complete these steps:

转到 Google API 控制台.

Go to the Google API Console.

  1. 选择一个项目.

  1. Select a project.

在左侧边栏中,展开 APIs &进行身份验证并选择 API.

In the sidebar on the left, expand APIs & auth and select APIs.

在显示的可用 API 列表中,单击 Drive API 链接,然后单击启用 API.

In the displayed list of available APIs, click the Drive API link and click Enable API.

如果您已完成,请转到控制台中的 OAuth 同意屏幕并添加驱动器的两个范围并保存.

If you completed it, then go to OAuth Consent screen in console and add the two scopes for drive and save it.

在您的项目中添加以下依赖项.

In your project add the dependencies below.

implementation 'com.google.android.gms:play-services-auth:17.0.0'// for google sign in

// for drive integration
implementation 'com.google.android.gms:play-services-auth:16.0.1'
implementation 'com.google.http-client:google-http-client-gson:1.26.0'
implementation('com.google.api-client:google-api-client-android:1.26.0') {
exclude group: 'org.apache.httpcomponents'
}
implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0') 
{
exclude group: 'org.apache.httpcomponents'
} 

在 android 标签内,在同一个 gradle 文件中,添加打包选项.

And inside android tag, in the same gradle file, add the packaging options.

packagingOptions {
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/license.txt'
exclude 'META-INF/NOTICE'
exclude 'META-INF/NOTICE.txt'
exclude 'META-INF/notice.txt'
exclude 'META-INF/ASL2.0'
}

在您的清单文件中,添加所需的权限

In your Manifest file, add the required permissions

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

这里我将下载的文件存储在外部存储中.所以这就是为什么我添加了外部存储读取和写入权限

Here I am storing the downloaded file in external storage. So that’s why I added the permissions for External storage READ and WRITE

在 Google 登录后,请求访问 Google Drive 的权限.下面给出了它的代码.

After Google sign In, ask permission to access Google drive. The code for it is given below.

private void checkForGooglePermissions() {

    if (!GoogleSignIn.hasPermissions(
            GoogleSignIn.getLastSignedInAccount(getApplicationContext()),
            ACCESS_DRIVE_SCOPE,
            SCOPE_EMAIL)) {
        GoogleSignIn.requestPermissions(
                MainActivity.this,
                RC_AUTHORIZE_DRIVE,
                GoogleSignIn.getLastSignedInAccount(getApplicationContext()),
                ACCESS_DRIVE_SCOPE,
                SCOPE_EMAIL);
    } else {
        Toast.makeText(this, "Permission to access Drive and Email has been granted", Toast.LENGTH_SHORT).show();
        driveSetUp();

    }

}

变量 ACCESS_DRIVE_SCOPE 和 SCOPE_EMAIL 是,

The variables ACCESS_DRIVE_SCOPE and SCOPE_EMAIL are,

Scope ACCESS_DRIVE_SCOPE = new Scope(Scopes.DRIVE_FILE);
Scope SCOPE_EMAIL = new Scope(Scopes.EMAIL);

获得许可并登录后,我们就有了 GoogleSignInAccount 对象.有了这个对象,创建一个GoogleAccountCredential的对象,我们可以从中生成一个Drive的对象.Drive 对象是我们在 Google Drive 之间进行通信所需要的.

After having permission and Sign In we have our GoogleSignInAccount object. With this object, create an object of GoogleAccountCredential, from which we can generate an object of Drive. The Drive object is what we needed for the communication between Google Drive.

private void driveSetUp() {

GoogleSignInAccount mAccount = GoogleSignIn.getLastSignedInAccount(MainActivity.this);

GoogleAccountCredential credential =
        GoogleAccountCredential.usingOAuth2(
                getApplicationContext(), Collections.singleton(Scopes.DRIVE_FILE));
credential.setSelectedAccount(mAccount.getAccount());
googleDriveService =
        new com.google.api.services.drive.Drive.Builder(
                AndroidHttp.newCompatibleTransport(),
                new GsonFactory(),
                credential)
                .setApplicationName("GoogleDriveIntegration 3")
                .build();
mDriveServiceHelper = new DriveServiceHelper(googleDriveService);
}

在这里你可以看到我创建了一个 DriveServiceHelper 类的对象并传递了 Drive(googleDriveSrvice) 的对象.DriveServiceHelper 类在下面给出.我从这里得到它.( https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/src/main/java/com/google/android/gms/drive/sample/driveapimigration/DriveServiceHelper.java?source=post_page-----bc4ddbd90820--------------).你可以用那个.我为自己在那门课上做了一些改变.

Here you can see I created an object of DriveServiceHelper class and passed the object of Drive(googleDriveSrvice) along with it. DriveServiceHelper class is given below. I got it from here.( https://github.com/gsuitedevs/android-samples/blob/master/drive/deprecation/app/src/main/java/com/google/android/gms/drive/sample/driveapimigration/DriveServiceHelper.java?source=post_page-----bc4ddbd90820----------------------). You can use that one. I made some changes in that class for myself.

public class DriveServiceHelper {

private final Executor mExecutor = Executors.newSingleThreadExecutor();
private final Drive mDriveService;
private final String TAG = "DRIVE_TAG";


public DriveServiceHelper(Drive driveService) {

    mDriveService = driveService;
}

/**
 * Creates a text file in the user's My Drive folder and returns its file ID.
 */
public Task<GoogleDriveFileHolder> createFile(String folderId, String filename) {
    return Tasks.call(mExecutor, () -> {
        GoogleDriveFileHolder googleDriveFileHolder = new GoogleDriveFileHolder();

        List<String> root;
        if (folderId == null) {

            root = Collections.singletonList("root");

        } else {

            root = Collections.singletonList(folderId);
        }
        File metadata = new File()
                .setParents(root)
                .setMimeType("text/plain")
                .setName(filename);

        File googleFile = mDriveService.files().create(metadata).execute();
        if (googleFile == null) {

            throw new IOException("Null result when requesting file creation.");
        }
        googleDriveFileHolder.setId(googleFile.getId());
        return googleDriveFileHolder;
    });
}


// TO CREATE A FOLDER

public Task<GoogleDriveFileHolder> createFolder(String folderName, @Nullable String folderId) {
    return Tasks.call(mExecutor, () -> {

        GoogleDriveFileHolder googleDriveFileHolder = new GoogleDriveFileHolder();

        List<String> root;
        if (folderId == null) {

            root = Collections.singletonList("root");

        } else {

            root = Collections.singletonList(folderId);
        }
        File metadata = new File()
                .setParents(root)
                .setMimeType("application/vnd.google-apps.folder")
                .setName(folderName);

        File googleFile = mDriveService.files().create(metadata).execute();
        if (googleFile == null) {
            throw new IOException("Null result when requesting file creation.");
        }
        googleDriveFileHolder.setId(googleFile.getId());
        return googleDriveFileHolder;
    });
}


public Task<Void> downloadFile(java.io.File targetFile, String fileId) {
    return Tasks.call(mExecutor, () -> {

        // Retrieve the metadata as a File object.
        OutputStream outputStream = new FileOutputStream(targetFile);
        mDriveService.files().get(fileId).executeMediaAndDownloadTo(outputStream);
        return null;
    });
}

public Task<Void> deleteFolderFile(String fileId) {

    return Tasks.call(mExecutor, () -> {

        // Retrieve the metadata as a File object.
        if (fileId != null) {
            mDriveService.files().delete(fileId).execute();
        }

        return null;

    });
}

// TO LIST FILES

public List<File> listDriveImageFiles() throws IOException{

    FileList result;
    String pageToken = null;
    do {
        result = mDriveService.files().list()
/*.setQ("mimeType='image/png' or mimeType='text/plain'")This si to list both image and text files. Mind the type of image(png or jpeg).setQ("mimeType='image/png' or mimeType='text/plain'") */
                .setSpaces("drive")
                .setFields("nextPageToken, files(id, name)")
                .setPageToken(pageToken)
                .execute();

        pageToken = result.getNextPageToken();
    } while (pageToken != null);

    return result.getFiles();
}

// TO UPLOAD A FILE ONTO DRIVE

public Task<GoogleDriveFileHolder> uploadFile(final java.io.File localFile, 
final String mimeType, @Nullable final String folderId) {
    return Tasks.call(mExecutor, new Callable<GoogleDriveFileHolder>() {
        @Override
        public GoogleDriveFileHolder call() throws Exception {
            // Retrieve the metadata as a File object.

            List<String> root;
            if (folderId == null) {
                root = Collections.singletonList("root");
            } else {

                root = Collections.singletonList(folderId);
            }

            File metadata = new File()
                    .setParents(root)
                    .setMimeType(mimeType)
                    .setName(localFile.getName());

            FileContent fileContent = new FileContent(mimeType, localFile);

            File fileMeta = mDriveService.files().create(metadata, 
fileContent).execute();
            GoogleDriveFileHolder googleDriveFileHolder = new 
GoogleDriveFileHolder();
            googleDriveFileHolder.setId(fileMeta.getId());
            googleDriveFileHolder.setName(fileMeta.getName());
            return googleDriveFileHolder;
        }
    });
}
}

请记住,无论何时创建文件或文件夹或上传文件,驱动器都会为其提供唯一 ID,您可以访问它.所以这里唯一的不是文件名,而是文件的id.因此,如果您多次上传或创建同名文件,它将多次保存在文件夹中.所以如果你想用另一个同名文件替换一个文件.首先删除文件并保存/上传.要创建文件,请指定要创建的文件夹 ID 和文件名.

Remember the fact that whenever you create a file or folder or if you upload a file, the drive will give a unique id for it and you can access it. So it’s not the file name that is unique in here, it’s the id of the file. Hence if you upload or create a file of same name multiple times it will be saved in the folder multiple times. So if you want to replace a file with another file of the same name. First delete the file and save/ upload it. To create a file, specify the folder id and file name to be created.

下面给出了 GoogleDriveHolder 类.

The GoogleDriveHolder class is given below.

public class GoogleDriveFileHolder {

private String id;
private String name;
private DateTime modifiedTime;
private long size;
private DateTime createdTime;
private Boolean starred;


public DateTime getCreatedTime() {
    return createdTime;
}

public void setCreatedTime(DateTime createdTime) {
    this.createdTime = createdTime;
}

public Boolean getStarred() {
    return starred;
}

public void setStarred(Boolean starred) {
    this.starred = starred;
}

public String getId() {
    return id;
}

public void setId(String id) {
    this.id = id;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

public DateTime getModifiedTime() {
    return modifiedTime;
}

public void setModifiedTime(DateTime modifiedTime) {
    this.modifiedTime = modifiedTime;
}

public long getSize() {
    return size;
}

public void setSize(long size) {
    this.size = size;
}
}

从您的活动中,您必须调用这些方法.就像下面给出的代码一样.

From your activity you have to call these methods. Like in the codes given below.

创建文件夹

public void createFolderInDrive(View view) {

Log.i(TAG, "Creating a Folder...");
mDriveServiceHelper.createFolder("My Foder", null)
        .addOnSuccessListener(new OnSuccessListener<GoogleDriveFileHolder>() {
            @Override
            public void onSuccess(GoogleDriveFileHolder googleDriveFileHolder) {

                Gson gson = new Gson();
                Log.i(TAG, "onSuccess of Folder creation: " + gson.toJson(googleDriveFileHolder));
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {

                Log.i(TAG, "onFailure of Folder creation: " + e.getMessage());
            }
        });
}

列出文件

public void listFilesInDrive(View view) {

Log.i(TAG, "Listing Files...");
new MyAsyncTask().execute();

}

要列出文件,您不能从主线程执行此操作,因为这会导致死锁.您必须在 Asynctask 的 doInBackground() 方法中执行此操作.这是我的课.

To list the files, you can’t do it from your main thread because it will cause a deadlock. You have to do it in doInBackground() method of Asynctask. Here is my class.

public class MyAsyncTask extends AsyncTask<Void, Void, List<File>> {

List<File> fileList;

@Override
protected List<File> doInBackground(Void... voids) {

    try {

        fileList = mDriveServiceHelper.listDriveImageFiles();

    } catch (IOException e) {

        Log.i(TAG, "IO Exception while fetching file list");
    }

    return fileList;

}

@Override
protected void onPostExecute(List<File> files) {
    super.onPostExecute(files);

    if (files.size() == 0){

        Log.i(TAG, "No Files");
    }
    for (File file : files) {

        Log.i(TAG, "\nFound file: File Name :" +
                file.getName() + " File Id :" + file.getId());
    }
}
}

上传文件

要将文件上传到 Drive 文件夹,请指定文件夹 id 、要上传的文件的 MIME 类型以及文件本身.在这里,我从图库中选择了一张图片并将其上传到驱动器中.

To upload a file into Drive folder, specify the folder id , mime type of file to be uploaded and the file itself. Here I select an Image from gallery and uploaded it into drive.

public void uploadFile(View view) {

if (ActivityCompat.checkSelfPermission(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
    ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE, Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PICK_IMAGE);

} else {
    Intent i = new Intent(
            Intent.ACTION_PICK, android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

    startActivityForResult(i, RESULT_LOAD_IMAGE);
}
}

在 onActivityResult

In onActivityResult

else if (requestCode == RESULT_LOAD_IMAGE) {

if (resultCode == RESULT_OK) {

    Uri selectedImage = data.getData();
    String[] filePathColumn = {MediaStore.Images.Media.DATA};

    Cursor cursor = getContentResolver().query(selectedImage,
            filePathColumn, null, null, null);
    cursor.moveToFirst();

    int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
    String picturePath = cursor.getString(columnIndex);
    cursor.close();

    uploadImageIntoDrive(BitmapFactory.decodeFile(picturePath));

} else {

    Toast.makeText(this, "Did not select any image", Toast.LENGTH_SHORT).show();
}

uploadImageIntoDrive() 方法,

uploadImageIntoDrive() method,

private void uploadImageIntoDrive(Bitmap bitmap) {

try {

    if (bitmap == null) {

        Log.i(TAG, "Bitmap is null");
        return;
    }
    java.io.File file = new java.io.File(getApplicationContext().getFilesDir(), "FirstFile");
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 0 /*ignored for PNG*/, bos);
    byte[] bitmapdata = bos.toByteArray();

    //write the bytes in file
    FileOutputStream fos = new FileOutputStream(file);
    fos.write(bitmapdata);
    fos.flush();
    fos.close();

    mDriveServiceHelper.uploadFile(file, "image/jpeg", "MY_FOLDER_ID")
            .addOnSuccessListener(new OnSuccessListener<GoogleDriveFileHolder>() {
                @Override
                public void onSuccess(GoogleDriveFileHolder googleDriveFileHolder) {

                    Log.i(TAG, "Successfully Uploaded. File Id :" + googleDriveFileHolder.getId());
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {

                    Log.i(TAG, "Failed to Upload. File Id :" + e.getMessage());
                }
            });
} catch (Exception e) {

    Log.i(TAG, "Exception : " + e.getMessage());
}

}

下载文件

要下载文件,请指定文件的 id 和下载文件必须存储到的目标文件.

To download a file, specify the id of the file and the target file into which the downloading file has to be stored.

public void downloadFile(View view) {

java.io.File file = new java.io.File(getExternalFilesDir(null), "DemoFile2.jpg");
mDriveServiceHelper.downloadFile(file, "MY_FILE_ID")
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {

                Log.i(TAG, "Downloaded the file");
                long file_size = file.length() / 1024;
                Log.i(TAG, "file Size :" + file_size);
                Log.i(TAG, "file Path :" + file.getAbsolutePath());
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {

                Log.i(TAG, "Failed to Download the file, Exception :" + e.getMessage());
            }
        });
}

删除文件.

public void deleteFile(View view) {

mDriveServiceHelper.deleteFolderFile("MY_FILE_OR_FOLDER_ID")
        .addOnSuccessListener(new OnSuccessListener<Void>() {
            @Override
            public void onSuccess(Void aVoid) {

                Log.i(TAG, "onSuccess of Deleting File ");
            }
        })
        .addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {

                Log.i(TAG, "onFailure on Deleting File Exception : " + e.getMessage());
            }
        });
}

我不是一个有经验的人.我发布此代码的原因是有人会发现它很有用,可以提出自己的更改并将其发布在这里.因为目前没有太多关于 Android 的 Drive Rest API 集成的参考资料.

I am not an experienced guy. The reason I posted this code is somebody will find it useful and can bring up their own changes to it and post it here. Because there is not much reference for Drive Rest API integration for Android right now.

谢谢.

这篇关于有人可以为 Google Drive REST API v3 提供最新的 Android 指南吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆