无需用户选择即可附加到Google驱动器文件

时间:2018-08-13 20:19:45

标签: java android google-drive-api

我正在尝试向我的Android应用中添加代码,以便从用户界面中获取信息并将其追加到Google驱动器中的文件中。我已经登录并获得了授权,并按名称查询了文件。我阅读的大多数SO线程都是用于旧的API或REST API。

但是,我想以“读/写”或“仅写”模式打开它。我尝试查看快速入门演示和驱动器API,但它们都无济于事。

如何以编程方式获取driveId?我尝试从驱动器本身获取ID。有没有一种方法可以构建从查询中获取ID的元数据?

如果我使用openFile(DriveId.decodeFromString(actual_id).asDriveFile() 我收到以下错误:

j ava.lang.IllegalArgumentException: Invalid DriveId: **actual_id**

从共享链接获取文件ID错误: drive.google.com/open?id=some_id

如果是这样,我该如何实现?

private String id = "1fuTq1Q6MHrchgW7sZImjvSfpAShHhsbx";
private DriveFile file = DriveId.decodeFromString(id).asDriveFile();



private void getFile() {
        Query q = new Query.Builder().addFilter(Filters.and(Filters.eq(SearchableField.TITLE, "HelloWorld.txt"))).build();
}

private void appendFile() {

    Task<DriveContents> openTask = getResourceClient().openFile(file, DriveFile.MODE_READ_WRITE);

    openTask.continueWithTask(task -> {
       DriveContents driveContents = task.getResult();
        ParcelFileDescriptor pfd = driveContents.getParcelFileDescriptor();
        long bytesToSkip = pfd.getStatSize();
        try (InputStream in = new FileInputStream(pfd.getFileDescriptor())) {
            // Skip to end of file
            while (bytesToSkip > 0) {
                long skipped = in.skip(bytesToSkip);
                bytesToSkip -= skipped;
            }
        }
        try (OutputStream out = new FileOutputStream(pfd.getFileDescriptor())) {
            out.write("Hello world".getBytes());
        }
        // [START drive_android_commit_contents_with_metadata]
        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                .setStarred(true)
                .setLastViewedByMeDate(new Date())
                .build();
        Task<Void> commitTask =
                getResourceClient().commitContents(driveContents, changeSet);
        // [END drive_android_commit_contents_with_metadata]
        return commitTask;
    })
            .addOnSuccessListener(this,
                    aVoid -> {
                        //showMessage(getString(R.string.content_updated));
                        Log.i("DRIVE", "Sucess");
                        finish();
                    })
            .addOnFailureListener(this, e -> {
                Log.e(TAG, "Unable to update contents", e);
               // showMessage(getString(R.string.content_update_failed));
                finish();
    });
}

该文件也存在,并且ID有效。 enter image description here

1 个答案:

答案 0 :(得分:1)

根据GDAA(Google云端硬盘Android API)的文档,应该可以单独使用asDriveFile()根据文件ID下载文件。

为此,您需要查询,然后将信息存储在Task<MetadataBuffer>中,然后应该能够以files.get(0).asDriveFile()尝试下载的方法使用FileId。但是,即使在提取元数据并使用查询方法时,也会遇到IllegalArgumentException invalid DriveId(这是相同的ID,因此它永远不是无效的),但是它仍然显示为无效。我已经厌倦了使用它,而去了REST API。

注意事项:您要下载的文件必须为:文档/电子表格/幻灯片,照片或应用脚本。 您可以选择要将其导出为的文件类型。这是兼容性的“ truth table”。

在此示例中,编写数据并重新上传数据非常容易。 但是,这些文件具有特殊的编码,因此您无法直接写入数据。

根据需要完成的操作,可以使用sheets apiapache poi

// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

// [START drive_quickstart]
import java.io.BufferedWriter;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.security.GeneralSecurityException;
import java.util.Collections;
import java.util.List;
import com.google.api.client.auth.oauth2.Credential;
import com.google.api.client.extensions.java6.auth.oauth2.AuthorizationCodeInstalledApp;
import com.google.api.client.extensions.jetty.auth.oauth2.LocalServerReceiver;
import com.google.api.client.googleapis.auth.oauth2.GoogleAuthorizationCodeFlow;
import com.google.api.client.googleapis.auth.oauth2.GoogleClientSecrets;
import com.google.api.client.googleapis.javanet.GoogleNetHttpTransport;
import com.google.api.client.http.javanet.NetHttpTransport;
import com.google.api.client.json.JsonFactory;
import com.google.api.client.json.jackson2.JacksonFactory;
import com.google.api.client.util.store.FileDataStoreFactory;
import com.google.api.services.drive.Drive;
import com.google.api.services.drive.DriveScopes;
import com.google.api.services.drive.model.File;
import com.google.api.services.drive.model.FileList;

public class DriveQuickstart {
    private static final String APPLICATION_NAME = "Google Drive API Java Quickstart";
    private static final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();
    private static final String TOKENS_DIRECTORY_PATH = "tokens";
    private static String fileId = "super_secret_string";
    private static final String OUTPUT = "super_secret_path";

    /**
     * Global instance of the scopes required by this quickstart.
     * If modifying these scopes, delete your previously saved credentials/ folder.
     */
    private static final List<String> SCOPES = Collections.singletonList(DriveScopes.DRIVE); //DONT USE THIS SCOPE IN PRODUCTION!
    private static final String CREDENTIALS_FILE_PATH = "/credentials.json";

    /**
     * Creates an authorized Credential object.
     * @param HTTP_TRANSPORT The network HTTP Transport.
     * @return An authorized Credential object.
     * @throws IOException If the credentials.json file cannot be found.
     */
    private static Credential getCredentials(final NetHttpTransport HTTP_TRANSPORT) throws IOException {
        // Load client secrets.
        InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        // Build flow and trigger user authorization request.
        GoogleAuthorizationCodeFlow flow = new GoogleAuthorizationCodeFlow.Builder(
                HTTP_TRANSPORT, JSON_FACTORY, clientSecrets, SCOPES)
                .setDataStoreFactory(new FileDataStoreFactory(new java.io.File(TOKENS_DIRECTORY_PATH)))
                .setAccessType("offline")
                .build();
        return new AuthorizationCodeInstalledApp(flow, new LocalServerReceiver()).authorize("user");
    }

    public static void main(String... args) throws IOException, GeneralSecurityException {
        // Build a new authorized API client service.
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        Drive service = new Drive.Builder(HTTP_TRANSPORT, JSON_FACTORY, getCredentials(HTTP_TRANSPORT))
                .setApplicationName(APPLICATION_NAME)
                .build();

        // Print the names and IDs for up to 10 files.
        FileList result = service.files().list()
                .setPageSize(10)
                .setFields("nextPageToken, files(id, name)")
                .execute();
        List<File> files = result.getFiles();
        if (files == null || files.isEmpty()) {
            System.out.println("No files found.");
        } else {
            System.out.println("Files:");
            for (File file : files) {
                System.out.printf("%s (%s)\n", file.getName(), file.getId());
            }
        }
        //Download the file from it's known ID
        FileOutputStream fos = new FileOutputStream(OUTPUT);
        service.files().export(fileId, "text/plain").executeMediaAndDownloadTo(fos);
        //Append some data to the file
        FileWriter fw = new FileWriter(OUTPUT, true);
        BufferedWriter bw = new BufferedWriter(fw);
        bw.newLine();
        bw.write("Goodbye, World!");
        bw.newLine();
        bw.close();

    }
}
// [END drive_quickstart]