如何从 GDrive 恢复文件?

How to restore file from GDrive?

我正在制作一个将 SQLite 数据库备份存储在 GDrive 上的应用程序。我成功登录并上传了驱动器中的文件,但未能恢复它。以下是代码。 我使用 SQLiteDatabase 来存储 fileID,以便在更新和恢复时需要它时,可以使用它。我正在寻找一种使用 FileID 进行恢复的方法。 在 file.getDownloadUrl() 和 file.getContent() 处发生错误。

 class DriveClassHelper 
{
    private final Executor mExecutor = Executors.newSingleThreadExecutor();
    private static Drive mDriveService;

    private String FileID = null;

    private static String filePath = "/data/data/com.example.gdrivebackup/databases/Data.db";


    DriveClassHelper(Drive mDriveService) 
    {
        DriveClassHelper.mDriveService = mDriveService;
    }

    // ---------------------------------- TO BackUp on Drive  -------------------------------------------

    public Task<String> createFile() 
    {
        return Tasks.call(mExecutor, () ->
                {

                    File fileMetaData = new File();
                    fileMetaData.setName("Backup");
                    java.io.File file = new java.io.File(filePath);
                    String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("application/x-sqlite-3");
                    FileContent mediaContent = new FileContent(mimeType, file);
                    File myFile = null;

                    FileID = getFileIDFromDatabase();

                    try {
                        if (FileID != null) {
                            Log.i("CALLED : ", FileID);
                            //mDriveService.files().delete().execute();
                            myFile = mDriveService.files().update(FileID, fileMetaData, mediaContent).execute();
                        } else {
                            myFile = mDriveService.files().create(fileMetaData, mediaContent).execute();
                            MainActivity.demoSQLite.insertData(myFile.getId());
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

                    if (myFile == null) {
                        throw new IOException("Null Result when requesting file creation");
                    }

                    Log.i("ID:", myFile.getId());
                    return myFile.getId();
                }
        );
    }

    // -------------------------------------------------------------------------------------------------

    // ---------------------------------- TO get File ID  -------------------------------------------

    private static String getFileIDFromDatabase() 
    {
        String FileIDFromMethod = null;
        Cursor result = MainActivity.demoSQLite.getData();

        if (result.getCount() == 0) {
            Log.i("CURSOR :", "NO ENTRY");
            return null;
        } else {
            while (result.moveToNext()) {
                FileIDFromMethod = result.getString(0);
            }
            return FileIDFromMethod;
        }
    }

    // -------------------------------------------------------------------------------------------------

    // ---------------------------------- TO Restore  -------------------------------------------


    public static class Restore extends AsyncTask<Void, Void, String>
    {
        @Override
        protected String doInBackground(Void... params) {
            String fileId = null;
            try
            {
                fileId = getFileIDFromDatabase();

                if (fileId != null)
                {
                    File file = mDriveService.files().get(fileId).execute();
                    downloadFile(file);
                }
                else
                {
                    return null;
                }
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
            return fileId;
        }

        private void downloadFile(File file)
        {
            InputStream mInput = null;
            FileOutputStream mOutput = null;


            if (file.getDownloadUrl() != null && file.getDownloadUrl().length() > 0) //Error occurs at file.getDownloadUrl()
            {
                try
                {
                    HttpResponse resp = mDriveService.getRequestFactory().buildGetRequest(new GenericUrl(file.getDownloadUrl())).execute();

                    mInput = resp.getContent();
                    String outFileName = "file://" + Environment.getDataDirectory().getPath() + filePath;
                    // Log.e("com.example.myapp", "getDatabasePath="+ getDatabasePath(""));
                    //Log.e("com.example.myapp", "outFileName="+outFileName);
//                  String outFileName = "../databases/" + "Quickpay.db";
                    mOutput = new FileOutputStream(outFileName);
                    byte[] mBuffer = new byte[1024];
                    int mLength;
                    while ((mLength = mInput.read(mBuffer)) > 0)
                    {
                        mOutput.write(mBuffer, 0, mLength);
                    }
                    mOutput.flush();
                }
                catch (IOException e)
                {
                    // An error occurred.
                    e.printStackTrace();
                    // return null;
                }
                finally
                {
                    try
                    {
                        //Close the streams
                        if (mOutput != null)
                        {
                            mOutput.close();
                        }
                        if (mInput != null)
                        {
                            mInput.close();
                        }
                    }
                    catch (IOException e)
                    {
                        Log.e("com.example.myapp", "failed to close databases");
                    }
                }
            }
            else
            {
                // The file doesn't have any content stored on Drive.
                // return null;
                Log.e("com.example.myapp", "No content on Drive");
            }
        }
    }
}

Gradle 文件就像

implementation 'com.google.android.gms:play-services-auth:16.0.1'
    implementation('com.google.apis:google-api-services-drive:v3-rev136-1.25.0')
            {
                exclude group: 'org.apache.httpcomponents'
            }
    implementation('com.google.api-client:google-api-client-android:1.26.0')
            {
                exclude group: 'org.apache.httpcomponents'
            }
    implementation 'com.google.http-client:google-http-client-gson:1.26.0'

据我所知,下载 URL 仅在 Google 驱动器 api v2 中有效,在 V3 中无效。

Short lived download URL for the file. This field is only populated for files with content stored in Google Drive; it is not populated for Google Docs or shortcut files.

我认为它不是很稳定,因为并非所有文件类型都会 return 下载 url。

使用 Google Drive v3,您应该使用流下载文件。

String fileId = "0BwwA4oUTeiV1UVNwOHItT0xfa2M";
OutputStream outputStream = new ByteArrayOutputStream();
driveService.files().get(fileId)
    .executeMediaAndDownloadTo(outputStream);

这应该适用于还原。如果没有,请告诉我,我会看看它已经有一段时间没有尝试恢复了。