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

时间:2018-04-07 16:11:50

标签: java android google-api kotlin google-drive-api

我有一个Android应用,在某些时候,需要在Google云端硬盘上创建和删除一些文本文件,以及下载/获取这些文件的内容以在活动中显示它。 所以我一直试图找到一种方法来只使用文件的名称,但我似乎有很多问题,找到一些如何做到这一点的信息。而且,不是Java开发人员也不会让事情变得更容易。

我设法在根文件夹中创建一个文件:

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

然而,令我惊讶的是,它每次都会创建一个具有相同名称的新文件,而不是覆盖它。

此外,我似乎无法删除文件或仅使用文件名下载/ gra内容。 我发现了很多关于如何使用文件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]
}

有关如何执行此操作或从何处开始查找的任何想法? 或者直接从应用程序中删除文件是不可能的?

2 个答案:

答案 0 :(得分:3)

这就是Google云端硬盘API的工作原理。一切都使用文件ID。您应该做的是file.list发送q参数以搜索具有正确名称和文件类型的文件。然后,您将拥有文件ID以便能够更新文件。

Google广告网络API不会阻止您创建多个具有相同名称的文件。

答案 1 :(得分:1)

按照@ DalmTo的建议,这是我在Google云端硬盘上删除文件的解决方案。下面的示例将跳过垃圾并永久删除文件。

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!");
                }
            });
}

由于帖子标题是下载和删除,这里是从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!");
                }
            });
}

我很确定这可以改进,但我想这对任何寻求解决方案的人来说都是一个开始。