简体   繁体   English

下载适用于Google Drive API Android的数据库文件

[英]Download database File For Google Drive API Android

I am using the drive api to create a database file in the hidden app folder on google drive. 我正在使用驱动器api在谷歌驱动器上隐藏的应用程序文件夹中创建一个数据库文件。 The database file is called notes.db I have been able to successfully upload the database file to google drive but I have no idea how to download it back to the user's device. 数据库文件名为notes.db我已经能够成功将数据库文件上传到谷歌驱动器,但我不知道如何将其下载回用户的设备。 This is what i'm trying to do. 这就是我想要做的。 My app makes a folder on the user's device called School Binder. 我的应用程序在用户设备上创建了一个名为School Binder的文件夹。 in that folder is another folder called Note backups. 在该文件夹中是另一个名为Note backups的文件夹。 Here is where I backup the database. 这是我备份数据库的地方。 The directory is 目录是

 Environment.getExternalStorageDirectory() + "/School Binder/Note Backups/Notes.db"

Google drive takes this file and uploads it to the hidden app folder. Google云端硬盘会将此文件上传到隐藏的应用文件夹。 Now I want to get this notes.db file stored in that app folder on google drive and download it back to this directory on the phone. 现在我想把这个notes.db文件存储在google驱动器上的那个app文件夹中,并将其下载回手机上的这个目录。

 Environment.getExternalStorageDirectory() + "/School Binder/Note Backups/Notes.db"

How do I do this. 我该怎么做呢。 Thanks. 谢谢。 Here is my code for uploading the database to drive this works correctly 这是我上传数据库以使其正常工作的代码

        // Define And Instantiate Variable DriveContents driveContents//
        DriveContents driveContents = result.getStatus().isSuccess() ? result.getDriveContents() : null;

        // Gets The Data for The File//
        if (driveContents != null) try {

            // Define And Instantiate Variable OutputStream outputStream//
            OutputStream outputStream = driveContents.getOutputStream();

            // Start Writing Data To File//
            if (outputStream != null) try {

                // Define And Instantiate Variable InputStream inputStream//
                InputStream inputStream = new FileInputStream(dbFile);

                // Define And Instantiate Variable Byte buffer//
                byte[] buffer = new byte[5000];

                // Define Variable Int data//
                int data;

                // Run Code While data Is Bigger Then Zero//
                while ((data = inputStream.read(buffer, 0, buffer.length)) > 0) {

                    // Write To outputStream//
                    outputStream.write(buffer, 0, data);

                    // Flush outputStream//
                    outputStream.flush();
                }

            } finally {

                // Close outputStream//
                outputStream.close();
            }

        } catch (Exception e) {e.printStackTrace(); Toast.makeText(getApplicationContext(), "Failed To Upload: No Backup File Found", Toast.LENGTH_LONG).show(); return;}

How do I change this to make it work for downloading data to a file from google drive 如何更改此设置以使其适用于从谷歌驱动器下载数据到文件

In Lifecycle of a Drive file , Drive Android API lets your app access files even if the device is offline. 云端硬盘驱动器文件的生命周期中 ,即使设备处于离线状态,云端硬盘驱动器API也可让您的应用访问文 To support offline cases, the API implements a sync engine, which runs in the background to upstream and downstream changes as network access is available and to resolve conflicts. 为了支持脱机情况,API实现了一个同步引擎,该引擎在网络访问可用时在后台运行以进行上游和下游更改并解决冲突。 Perform an initial download request if the file is not yet synced to the local context but the user wants to open the file. 如果文件尚未同步到本地上下文但用户想要打开文件,则执行初始下载请求。 The API handles this automatically when a file is requested. API在请求文件时自动处理。

In downloading a file , you make an authorized HTTP GET request to the file's resource URL and include the query parameter alt=media . 下载文件时 ,您对文件的资源URL发出授权的HTTP GET请求,并包含查询参数alt=media However, please note that downloading the file requests the user to have at least read access. 但请注意,下载文件会要求用户至少具有读取权限。

Sample HTTP Request: HTTP请求示例:

GET https://www.googleapis.com/drive/v3/files/0B9jNhSvVjoIVM3dKcGRKRmVIOVU?alt=media Authorization: Bearer ya29.AHESVbXTUv5mHMo3RYfmS1YJonjzzdTOFZwvyOAUVhrs 获取https://www.googleapis.com/drive/v3/files/0B9jNhSvVjoIVM3dKcGRKRmVIOVU?alt=media授权:Bearer ya29.AHESVbXTUv5mHMo3RYfmS1YJonjzzdTOFZwvyOAUVhrs

For the coding part, this SO post might be of help too. 对于编码部分,这个SO帖子也可能有所帮助。

I figured it out this is my code to redownload a database back to the phone 我想通了这是我将数据库重新下载回手机的代码

        //<editor-fold desc="Create Drive Db File On Device">

        // Log That The File Was Opened//
        Log.d("TAG", "File contents opened");

        // Define And Instantiate Variable DriveContents driveContents//
        DriveContents driveContents = result.getStatus().isSuccess() ? result.getDriveContents() : null;

        // Gets The Data for The File//
        if (driveContents != null) try {

            // Define And Instantiate Variable OutputStream outputStream//
            OutputStream outputStream = new FileOutputStream(dbFile);

            // Define And Instantiate Variable InputStream inputStream//
            InputStream inputStream = driveContents.getInputStream();

            // Define And Instantiate Variable Byte buffer//
            byte[] buffer = new byte[5000];

            // Define Variable Int data//
            int data;

            // Run Code While data Is Bigger Then Zero//
            while ((data = inputStream.read(buffer, 0, buffer.length)) > 0) {

                // Write To outputStream//
                outputStream.write(buffer, 0, data);

                // Flush outputStream//
                outputStream.flush();
            }

            // Close outputStream//
            outputStream.close();

            // Discard Drive Contents//
            driveContents.discard(googleApiClient);

        } catch (Exception e) {e.printStackTrace(); Toast.makeText(getApplicationContext(), "File Failed To Download", Toast.LENGTH_LONG).show(); }

        //</editor-fold>

here is a complete class to upload an internal database, download it and delete it from Google Drive. 这是一个完整的类,用于上传内部数据库,下载并从Google云端硬盘中删除。

Only need to call functions asynchronously and show user a progressbar. 只需要异步调用函数并向用户显示进度条。 DownloadFromGoogleDrive function saves the database in the internal database folder to the app with the name "database2" DownloadFromGoogleDrive函数将内部数据库文件夹中的数据库保存到名为“database2”的应用程序

Hope it's helpful. 希望它有用。

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.drive.Drive;
import com.google.android.gms.drive.DriveApi;
import com.google.android.gms.drive.DriveApi.MetadataBufferResult;
import com.google.android.gms.drive.DriveFile.DownloadProgressListener;
import com.google.android.gms.drive.DriveId;
import com.google.android.gms.drive.DriveResource;
import com.google.android.gms.drive.Metadata;
import com.google.android.gms.drive.DriveApi.DriveContentsResult;
import com.google.android.gms.drive.DriveContents;
import com.google.android.gms.drive.DriveFile;
import com.google.android.gms.drive.DriveFolder.DriveFileResult;
import com.google.android.gms.drive.MetadataChangeSet;
import com.google.android.gms.drive.query.Filters;
import com.google.android.gms.drive.query.Query;
import com.google.android.gms.drive.query.SearchableField;

import android.app.Activity;
import android.content.Intent;
import android.content.IntentSender.SendIntentException;
import android.os.Bundle;
import android.util.Log;
import android.webkit.MimeTypeMap;
import android.widget.Toast;

public class BackupDatabaseActivity extends Activity implements ConnectionCallbacks, OnConnectionFailedListener {

private static final String TAG = "BackupDatabaseActivity";
private GoogleApiClient api;
private boolean mResolvingError = false;
private static final int DIALOG_ERROR_CODE =100;
private static final String DATABASE_NAME = "database";
private static final String GOOGLE_DRIVE_FILE_NAME = "database_backup";

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    // Create the Drive API instance
    api = new GoogleApiClient.Builder(this).addApi(Drive.API).addScope(Drive.SCOPE_FILE).
            addConnectionCallbacks(this).addOnConnectionFailedListener(this).build();
}



final private ResultCallback<DriveApi.DriveContentsResult> contentsCallback = new ResultCallback<DriveApi.DriveContentsResult>() {

    @Override
    public void onResult(DriveApi.DriveContentsResult result) {
        if (!result.getStatus().isSuccess()) {
            Log.v(TAG, "Error while trying to create new file contents");
            return;
        }
        CreateFileOnGoogleDrive(result);
        //OR DownloadFromGoogleDrive(result);
        //OR DeleteFromGoogleDrive(result);
    }

};


final private ResultCallback<DriveFileResult> fileCallback = new ResultCallback<DriveFileResult>() {

    @Override
    public void onResult(DriveFileResult result) {
        if (!result.getStatus().isSuccess()) {
            Log.v(TAG, "Error while trying to create the file");
            return;
        }

        Log.v(TAG, "File created: "+result.getDriveFile().getDriveId());
    }
};

/**
 * Create a file in root folder using MetadataChangeSet object.
 * @param result
 */
public void CreateFileOnGoogleDrive(DriveContentsResult result){
    final DriveContents driveContents = result.getDriveContents();

    // Perform I/O off the UI thread.
    new Thread() {
        @Override
        public void run() {
            try {
                FileInputStream is = new FileInputStream(getDbPath());
                BufferedInputStream in = new BufferedInputStream(is);
                byte[] buffer = new byte[8 * 1024];
                BufferedOutputStream out = new BufferedOutputStream(driveContents.getOutputStream());
                int n = 0;
                while( ( n = in.read(buffer) ) > 0 ) {
                    out.write(buffer, 0, n);
                }
                out.flush();
                out.close();
                in.close();
            } catch (FileNotFoundException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
            String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db");
            MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                    .setTitle(GOOGLE_DRIVE_FILE_NAME) // Google Drive File name
                    .setMimeType(mimeType)
                    .setStarred(true).build();

            // create a file in root folder
            Drive.DriveApi.getRootFolder(api)
                    .createFile(api, changeSet, driveContents)
                    .setResultCallback(fileCallback);
        }
    }.start();
}

/**
 * Download File from Google Drive
 * @param result
 */
public void DownloadFromGoogleDrive(DriveContentsResult result){
    final DriveContents driveContents = result.getStatus().isSuccess() ? result.getDriveContents() : null;
    if(driveContents!=null){
        Query query = new Query.Builder().addFilter(Filters.eq(SearchableField.TITLE, GOOGLE_DRIVE_FILE_NAME)).build();
        Drive.DriveApi.query(api, query).setResultCallback(new ResultCallback<MetadataBufferResult>() {

            @Override
            public void onResult(MetadataBufferResult result) {
                try{
                    DriveId driveId = result.getMetadataBuffer().get(0).getDriveId();
                    DriveFile driveFile =  driveId.asDriveFile();
                    //mProgressBar.setProgress(0);
                    DownloadProgressListener listener = new DownloadProgressListener() {
                        @Override
                        public void onProgress(long bytesDownloaded, long bytesExpected) {
                            // Update progress dialog with the latest progress.
                            int progress = (int)(bytesDownloaded*100/bytesExpected);
                            Log.d(TAG, String.format("Loading progress: %d percent", progress));
                           // mProgressBar.setProgress(progress);
                        }
                    };

                    driveFile.open(api, DriveFile.MODE_READ_ONLY, listener).setResultCallback(driveContentsCallback);

                }catch(Exception e){
                    Toast.makeText(getApplicationContext(), "File Failed To Download", Toast.LENGTH_LONG).show(); 
                }
            }
        });
    }else{
        Toast.makeText(getApplicationContext(), "File Failed To Download", Toast.LENGTH_LONG).show(); 
    }
}

private ResultCallback<DriveContentsResult> driveContentsCallback =
        new ResultCallback<DriveContentsResult>() {
    @Override
    public void onResult(DriveContentsResult result) {
        if (!result.getStatus().isSuccess()) {
            Log.d(TAG, "Error while opening the file contents");
            return;
        }
        Log.d(TAG, "Downloaded");
        DriveContents dc = result.getDriveContents();            
        try {
            InputStream inputStream = dc.getInputStream();

            OutputStream outputStream = new FileOutputStream(getDbPath()+"2");

            byte[] buffer = new byte[8 * 1024];
            //BufferedOutputStream out = new BufferedOutputStream(dc.getOutputStream());
            int n = 0;
            while( ( n = inputStream.read(buffer) ) > 0 ) {
                outputStream.write(buffer, 0, n);
            }
            outputStream.flush();
            outputStream    .close();
            //inputStream.close();
            dc.discard(api);    
        } catch (FileNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
};


/**
 * Delete File from Google Drive
 * @param result
 */
public void DeleteFromGoogleDrive(DriveContentsResult result){
    Query query = new Query.Builder()
        .addFilter(Filters.eq(SearchableField.TITLE, GOOGLE_DRIVE_FILE_NAME))
        .build();
    Drive.DriveApi.query(api, query)
            .setResultCallback(new ResultCallback<MetadataBufferResult>() {

        @Override
        public void onResult(MetadataBufferResult result) {
            try{
                Metadata metadata = result.getMetadataBuffer().get(0);
                /*String a = metadata.getTitle();
                String b = metadata.getDescription();
                long c = metadata.getFileSize();*/
                DriveResource driveResource = metadata.getDriveId().asDriveResource();
                 if (metadata.isTrashable()) {
                     if (metadata.isTrashed()) {
                         driveResource.untrash(api).setResultCallback(trashStatusCallback);
                     } else {
                         driveResource.trash(api).setResultCallback(trashStatusCallback);
                     }
                 } else {
                     Log.d(TAG, "Error trying delete");
                 }
            }catch(Exception e){
                Log.d(TAG, "Error: metadata doesn't exist");
            }

        }
    });
}

/**
 * Callback when call to trash or untrash is complete.
 */
private final ResultCallback<Status> trashStatusCallback =
        new ResultCallback<Status>() {
            @Override
            public void onResult(Status status) {
                if (!status.isSuccess()) {
                    Log.e(TAG, "Error trying delete: " + status.getStatusMessage());
                    return;
                }else{
                    Log.e(TAG, "Deleted: " + status.getStatusMessage());
                }
            }
        };




private File getDbPath() {
    return this.getDatabasePath(DATABASE_NAME);
}


@Override
public void onConnectionSuspended(int cause) {
    // TODO Auto-generated method stub
    Log.v(TAG, "Connection suspended");

}


@Override
public void onStart() {
    super.onStart();
    if(!mResolvingError) {
        api.connect(); // Connect the client to Google Drive
    }
}

@Override
public void onStop() {
    super.onStop();
    api.disconnect(); // Disconnect the client from Google Drive
}

@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.v(TAG, "Connection failed");
    if(mResolvingError) { // If already in resolution state, just return.
        return;
    } else if(result.hasResolution()) { // Error can be resolved by starting an intent with user interaction
        mResolvingError = true;
        try {
            result.startResolutionForResult(this, DIALOG_ERROR_CODE);
        } catch (SendIntentException e) {
            e.printStackTrace();
        }
    } else { // Error cannot be resolved. Display Error Dialog stating the reason if possible.
        Toast.makeText(this, "Error: Connection failed", Toast.LENGTH_SHORT).show();
    }
}



@Override
public void onConnected(Bundle connectionHint) {
    Log.v(TAG, "Connected successfully");

    /* Connection to Google Drive established. Now request for Contents instance, which can be used to provide file contents.
       The callback is registered for the same. */
    Drive.DriveApi.newDriveContents(api).setResultCallback(contentsCallback);
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    if(requestCode == DIALOG_ERROR_CODE) {
        mResolvingError = false;
        if(resultCode == RESULT_OK) { // Error was resolved, now connect to the client if not done so.
            if(!api.isConnecting() && !api.isConnected()) {
                api.connect();
            }
        }
    }
}

} }

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

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