无需用户选择即可附加到Google驱动器文件 [英] Append to google drive file wihout user selection

查看:73
本文介绍了无需用户选择即可附加到Google驱动器文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to add code to my android app that gets information from the UI and appends to a file in google drive. I have gotten as far sign in and authorization, as well as querying the file by name. Most of the SO threads I have read are for the old API or REST API.

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

However, I want to open it in Read/Write, or Write Only mode. I have tried looking at the quickstart demos and the drive API, but none of them are helpful.

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

How can I get the driveId programatically? I have tried getting the ID from drive itself. Is there a way to build Metadata that gets the ID from the query?

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

If I use openFile(DriveId.decodeFromString(actual_id).asDriveFile() I get the following error:

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

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

Is getting the file ID from the sharing link wrong: drive.google.com/open?id=some_id

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

If so, how can I achieve this?

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有效.

Also the file exists and the ID is valid.. Apparently

推荐答案

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

According to the documentation for the GDAA (Google Drive Android API), it should be possible to download a file based on its ID alone by using asDriveFile().

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

To do that you need a query and then store the information in a Task<MetadataBuffer>, and then should be able to files.get(0).asDriveFile() in the method where you are attempting to download by FileId. But even when pulling the metadata and use the query method, you are greeted with IllegalArgumentException invalid DriveId (which IS THE SAME ID, so it was never invalid), But it STILL shows it as invalid. I got tired of wrestling with it and went to the REST API.

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

Things to note: The file you are downloading MUST BE: Doc/Spreadsheet/Slides, photo or apps script. You can choose the type of file you want to export it as. Here is the "truth table" for compatibility.

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

From this example it is easy enough to write your data and re-upload it. However, these files have a special encoding so you can't write the data directly.

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

Depending on what you need to accomplish, you can use the sheets api or apache 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]

这篇关于无需用户选择即可附加到Google驱动器文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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