简体   繁体   English

Java-在Google云端硬盘上下载和删除文件

[英]Java - Download and delete file on Google Drive

I have an Android app that at some point, needs to create and delete some text files on Google Drive as well as download / grab the content of those files to display it in an activity. 我有一个Android应用程序,有时需要在Google云端硬盘上创建和删除一些文本文件,以及下载/获取这些文件的内容以在活动中显示它。 So I've been trying for some time to find a way to do this using only the file's name but I seem to be having a lot of problem finding some info on how to do it. 因此,我一直在尝试寻找一种仅使用文件名来执行此操作的方法,但我似乎在查找有关如何执行操作的信息时遇到了很多问题。 Moreover, not being a Java dev does not make things easier. 而且,不是Java开发人员也不会使事情变得简单。

I managed to create a file inside the root folder: 我设法在根文件夹中创建一个文件:

private void createFile()
{
    println("CreateFileActivity > createFile");

    final Task<DriveFolder> rootFolderTask = getDriveResourceClient().getRootFolder();
    final Task<DriveContents> createContentsTask = getDriveResourceClient().createContents();
    Tasks.whenAll(rootFolderTask, createContentsTask)
            .continueWithTask(task -> {
                DriveFolder parent = rootFolderTask.getResult();
                DriveContents contents = createContentsTask.getResult();
                OutputStream outputStream = contents.getOutputStream();

                try (Writer writer = new OutputStreamWriter(outputStream))
                {
                    writer.write("SOME_TEXT_HERE");
                }

                MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                                                      .setTitle("MyFile.txt")
                                                      .setMimeType("text/plain")
                                                      .setStarred(true)
                                                      .build();

                return getDriveResourceClient().createFile(parent, changeSet, contents);
            })
            .addOnSuccessListener(this,
                    driveFile -> {
                        System.out.println("File created");

                        Intent resultActvityIntent = new Intent(getApplicationContext(), ResultActivity.class);
                        startActivity(resultActvityIntent);
                    })
            .addOnFailureListener(this, e -> {
                Toast.makeText(this, "Unable to create file", Toast.LENGTH_SHORT).show();
                System.out.println("Unable to create file");
                Log.e(TAG, "Unable to create file", e);

                Intent resultActvityIntent = new Intent(getApplicationContext(), ResultActivity.class);
                startActivity(resultActvityIntent);
            });
}

To my surprise however, it creates a new file with the same name every time instead of overwriting it. 但是令我惊讶的是,它每次都创建一个具有相同名称的新文件,而不是覆盖它。

Also, I cannot seem to be able to delete the file or download it / grad the content using only the file name. 另外,我似乎无法仅使用文件名来删除文件或下载文件/对其内容进行分级。 I found a lot of info on how to delete the file using the file ID and I also found an example provided by Google but it's not really what I need. 我找到了很多有关如何使用文件ID删除文件的信息,我还找到了Google提供的示例,但这并不是我真正需要的。

@Override
protected void onDriveClientReady() 
{
    pickTextFile()
            .addOnSuccessListener(this,
                    driveId -> deleteFile(driveId.asDriveFile()))
            .addOnFailureListener(this, e -> {
                Log.e(TAG, "No file selected", e);
                showMessage(getString(R.string.file_not_selected));
                finish();
            });
}
private void deleteFile(DriveFile file) 
{
    // [START delete_file]
    getDriveResourceClient()
            .delete(file)
            .addOnSuccessListener(this,
                    aVoid -> {
                        showMessage(getString(R.string.file_deleted));
                        finish();
                    })
            .addOnFailureListener(this, e -> {
                Log.e(TAG, "Unable to delete file", e);
                showMessage(getString(R.string.delete_failed));
                finish();
            });
    // [END delete_file]
}

Any ideas on how to do this or where to start looking? 关于如何执行此操作或从哪里开始寻找任何想法? Or it's not possible to delete the file directly from within an app? 还是无法直接从应用程序内删除文件?

This is how the Google drive API works. 这就是Google Drive API的工作方式。 Everything uses the file id. 一切都使用文件ID。 What you should be doing is a file.list sending the q parameters to search for files with the correct name and file type. 您应该做的是一个file.list发送q参数来搜索具有正确名称和文件类型的文件。 You will then have the file id to be able to update the file. 然后,您将具有文件ID,以便能够更新文件。

Google drive API doesn't prevent you from creating more than one file with the same name. Google驱动器API不会阻止您创建多个具有相同名称的文件。

Following @DalmTo's suggestion, here's my solution for deleting a file on Google Drive. 遵循@DalmTo的建议,这是我删除Google云端硬盘上文件的解决方案。 The example below skips trash and deletes the file permanently. 下面的示例跳过垃圾桶并永久删除文件。

private static final String fileName = "MyAppsTextFile.txt";

private void deleteExistingFile()
{
    println("DeleteFileActivity > deleteExistingFile");

    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, fileName))
            .build();

    Task<MetadataBuffer> queryTask = getDriveResourceClient().query(query);

    queryTask.addOnSuccessListener( this,
            new OnSuccessListener<MetadataBuffer>()
            {
                @Override
                public void onSuccess(MetadataBuffer metadataBuffer)
                {
                    System.out.println("Success. File/s found!");

                    for(Metadata m : metadataBuffer)
                    {
                        DriveResource driveResource = m.getDriveId().asDriveResource();

                        System.out.println("Deleting file " + fileName + " with DriveID m.getDriveId()");
                        getDriveResourceClient().delete(driveResource);
                    }
                }
            })
            .addOnFailureListener(this, new OnFailureListener()
            {
                @Override
                public void onFailure(@NonNull Exception e)
                {
                    System.out.println("ERROR: File not found!");
                }
            });
}

And since the thread title is Download and Delete, here's the code to get the file content from Google drive: 由于线程标题为“下载并删除”,因此以下是从Google驱动器获取文件内容的代码:

private static final String fileName = "MyAppsTextFile.txt";

private void getFiles()
{
    System.out.println("GetGoogleDriveFile > getFiles");

    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, fileName))
            .build();

    Task<MetadataBuffer> queryTask = getDriveResourceClient().query(query);

    queryTask
            .addOnSuccessListener(this,
                    new OnSuccessListener<MetadataBuffer>()
                    {
                        @Override
                        public void onSuccess(MetadataBuffer metadataBuffer)
                        {
                            System.out.println("On SUCCESS");

                            for( Metadata m : metadataBuffer )
                            {
                                DriveFile driveFile = m.getDriveId().asDriveFile();
                                getFileContents(driveFile);
                            }
                        }
                    })
            .addOnFailureListener(this, new OnFailureListener()
            {
                @Override
                public void onFailure(@NonNull Exception e)
                {
                    System.out.println("On FAILURE");
                }
            });
}

private void getFileContents(DriveFile myFile)
{
    System.out.println("GetGoogleDriveFile > getFileContents");

    Task<DriveContents> openFileTask =
            getDriveResourceClient().openFile(myFile, DriveFile.MODE_READ_ONLY);

    openFileTask
            .continueWithTask(new Continuation<DriveContents, Task<Void>>()
            {
                @Override
                public Task<Void> then(@NonNull Task<DriveContents> task) throws Exception
                {
                    DriveContents contents = task.getResult();

                    try (BufferedReader reader = new BufferedReader(
                            new InputStreamReader(contents.getInputStream())))
                    {
                        StringBuilder builder = new StringBuilder();
                        String line;

                        while ((line = reader.readLine()) != null)
                        {
                            builder.append(line).append("\n");
                        }

                        userData = builder.toString();
                    }

                    System.out.println("We have the file content!");

                    Task<Void> discardTask = getDriveResourceClient().discardContents(contents);
                    return discardTask;
                }
            })
            .addOnFailureListener(new OnFailureListener()
            {
                @Override
                public void onFailure(@NonNull Exception e)
                {
                    System.out.println("Unable to read file!");
                }
            });
}

I'm pretty sure this can be improved but I guess it's a start for anyone looking for a solution. 我很确定这可以改善,但是我想这对于任何寻求解决方案的人都是一个开始。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM