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

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

问题描述

我和其他许多人一直在努力设置Google Drive REST API v3以与Android应用程序一起使用.这主要是由于以下事实:Google官方文档缺少适用于Android的正确的快速入门指南,我们只剩下一些零碎的(过时和/或令人困惑的)信息,但是我们需要的是 complete 针对初学者的最新指南,以帮助我们入门和运行,以便他们可以在自己的云端硬盘上打开和编辑文件,包括如何设置凭据,依赖项和清单.

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在此处发布的指南绝对是完美,而且正是我所寻找的对于-但不幸的是已经过时了几年.任何人都可以提供本指南的最新版本吗?谢谢.

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.

推荐答案

在回答此问题之前,我想让您知道我从这里获得了代码(

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链接,然后单击Enable 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"/>

在这里,我将下载的文件存储在外部存储中.这就是为什么我添加了对外部存储设备READ和WRITE的权限

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云端硬盘的权限.其代码如下.

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对象.云端硬盘对象是我们在Google云端硬盘之间进行通信所需的对象.

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类在下面给出.我从这里得到的.(

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());
    }
}
}

上传文件

要将文件上传到云端硬盘文件夹,请指定文件夹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云端硬盘REST API v3提供最新的Android指南吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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