【问题标题】:Append to google drive file wihout user selection在没有用户选择的情况下附加到谷歌驱动器文件
【发布时间】:2018-08-15 03:43:30
【问题描述】:

我正在尝试将代码添加到我的 android 应用程序中,该应用程序从 UI 获取信息并附加到谷歌驱动器中的文件。我已经登录和授权,以及按名称查询文件。我读过的大部分 SO 线程都是针对旧 API 或 REST API 的。

但是,我想以读/写或只写模式打开它。我试过查看快速入门演示和驱动 API,但都没有帮助。

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

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

java.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 有效.. 显然

【问题讨论】:

  • 如果你碰巧查看了这个SO post,有人指出这是适用于 Android 的 Drive API 的限制,他们正在改用 Drive REST API。
  • 所以这个“功能”并没有被 Google 记录,即使 API 说它是可能的?
  • 在修修补补的 30 分钟内,我能够制作一个 java REST 应用程序,它可以抓取文件并列出它们的名称/ID。代码不那么密集,而且令人惊讶地更有意义..

标签: java android google-drive-api


【解决方案1】:

根据 GDAA (Google Drive Android API) 的文档,应该可以使用 asDriveFile() 仅根据其 ID 下载文件。

为此,您需要一个查询,然后将信息存储在Task&lt;MetadataBuffer&gt; 中,然后应该能够在您尝试通过FileId 下载的方法中使用files.get(0).asDriveFile()。但是即使在提取元数据并使用查询方法时,您也会收到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]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-15
    • 1970-01-01
    相关资源
    最近更新 更多