【问题标题】:Store the sqlite Database into google drive将 sqlite 数据库存储到谷歌驱动器中
【发布时间】:2016-11-30 12:48:56
【问题描述】:

我尝试了很多示例,但没有找到任何好的解决方案。

我想将我的应用程序的数据存储在 sqlite 数据库中,然后将其与安装该应用程序的用户的 google drive 帐户同步。

还有一个按钮将显示来自谷歌驱动器的数据,用户可以编辑和更新数据,以便更新的数据随后存储在谷歌驱动器中。 我是 Android 开发新手,请帮助我。

我也应用了以下示例,但没有成功。 https://github.com/seanpjanson/GDAADemo Create / Edit / Retrieve DB file with GDAA (Google Drive Api for Android) Unpredictable result of DriveId.getResourceId() in Google Drive Android API https://github.com/googledrive/android-quickstart

谢谢

【问题讨论】:

  • 您可以将数据库文件压缩成 ZIP 并将该 zip 文件发送到服务器。
  • 亲爱的我不想压缩它。我希望当用户输入数据时它会被存储并在谷歌驱动器上更新。谢谢@Divyesh
  • 然后将该 .db 文件发送到驱动器。
  • 就像 WhatsApp 一样,您的数据在谷歌驱动器上。我们想要这样的功能。@Divyesh
  • 我确信 whatsapp 将您的 .DB 文件保存在驱动器中并取回该文件并读取所有消息并根据该数据创建列表视图

标签: android sqlite google-drive-android-api


【解决方案1】:

首先使用以下行在 SD 卡中创建数据库备份

Driver_utils.create_backup(SettingActivity.this);

**在 build.gradle 中添加以下依赖项**

 compile 'com.google.code.gson:gson:2.2.+'
 compile 'com.google.android.gms:play-services-drive:10.0.1'`
in_drive.setOnClickListener(new OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Utils.isInternetWorking()) {
                    File directorys = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Databackup");
                    if (directorys.exists()) {
                        String json = preferences_driverId.getString("drive_id", "");
                        DriveId driveId = gson.fromJson(json, DriveId.class);
                        //Update file already stored in Drive
                        Driver_utils.trash(driveId, google_api_client);
                        // Create the Drive API instance
                        Driver_utils.creatBackupDrive(SettingActivity.this, google_api_client);
                        dialog.dismiss();
                        Toast.makeText(getApplicationContext(), R.string.backupss, Toast.LENGTH_LONG).show();
                    } else {
                        Toast.makeText(getApplicationContext(), R.string.inportfirest, Toast.LENGTH_LONG).show();
                    }
                } else {
                    Toast.makeText(getApplicationContext(), R.string.nointe, Toast.LENGTH_LONG).show();
                }
            }
        });

**对于恢复使用这个**

   restore_from_drive.setOnClickListener(new OnClickListener() {
        @Override
        public void onClick(View v) {
            // Launch user interface and allow user to select file
            IntentSender intentSender = Drive.DriveApi
                    .newOpenFileActivityBuilder()
                    .setMimeType(new String[]{"application/zip"})
                    .build(google_api_client);
            try {

                startIntentSenderForResult(

                        intentSender, REQ_CODE_OPEN, null, 0, 0, 0);

            } catch (IntentSender.SendIntentException e) {

                Log.w(TAG, e.getMessage());
            }
            dialog.dismiss();
        }
    });

 @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 (!google_api_client.isConnecting() && !google_api_client.isConnected()) {
                google_api_client.connect();
            }
        }

    }
    if (requestCode == REQ_CODE_OPEN && resultCode == RESULT_OK) {
        DriveId mSelectedFileDriveId = data.getParcelableExtra(
                OpenFileActivityBuilder.EXTRA_RESPONSE_DRIVE_ID);
        Log.e("DriveID ---", mSelectedFileDriveId + "");
        Gson gson = new Gson();
        String json = gson.toJson(mSelectedFileDriveId); // myObject - instance of MyObject
        editor_drive = preferences_driverId.edit();
        editor_drive.putString("drive_id", json).commit();
        Log.e(TAG, "driveId this 1-- " + mSelectedFileDriveId);
        if (Utils.isInternetWorking()) {
            //restore Drive file to SDCArd
            Driver_utils.restoreDriveBackup(SettingActivity.this, google_api_client, GOOGLE_DRIVE_FILE_NAME, preferences_driverId, mfile);
            Driver_utils.restore(SettingActivity.this);

        } else {
            Toast.makeText(getApplicationContext(), R.string.nointernets, Toast.LENGTH_LONG).show();
        }
    }
}

**制作一个静态的 Driver_utils 类**

public class Driver_utils {
public static DriveFile mfile;
public static GoogleApiClient api;
public static DriveId driveId;
public static Context ctxs;
public static SharedPreferences preferences_driverId;
public static SharedPreferences.Editor editor;
private static final String GOOGLE_DRIVE_FILE_NAME = "Databackup";
public static void restoreDriveBackup(Context ctx, GoogleApiClient apis, String GOOGLE_DRIVE_FILE_NAME, SharedPreferences preferences_driverIds, DriveFile mfiles) {
    mfile = mfiles;
    api = apis;
    preferences_driverId = preferences_driverIds;
    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, GOOGLE_DRIVE_FILE_NAME))
            .build();

    Drive.DriveApi.query(api, query).setResultCallback(new ResultCallback<DriveApi.MetadataBufferResult>() {
        @Override
        public void onResult(DriveApi.MetadataBufferResult metadataBufferResult) {
            Gson gson = new Gson();
            String json = preferences_driverId.getString("drive_id", "");
            DriveId driveId = gson.fromJson(json, DriveId.class);
            Log.e("driveId put", "" + driveId);
            Log.e("filesize in cloud ", +metadataBufferResult.getMetadataBuffer().get(0).getFileSize() + "");
            metadataBufferResult.getMetadataBuffer().release();
            mfile = Drive.DriveApi.getFile(api, driveId);
            mfile.open(api, DriveFile.MODE_READ_ONLY, new DriveFile.DownloadProgressListener() {
                @Override
                public void onProgress(long bytesDown, long bytesExpected) {
                    Log.e("Downloading..", "" + bytesDown + "/" + bytesExpected);
                }
            })
                    .setResultCallback(restoreContentsCallback);
        }
    });
}

static final private ResultCallback<DriveApi.DriveContentsResult> restoreContentsCallback =
        new ResultCallback<DriveApi.DriveContentsResult>() {
            @Override
            public void onResult(DriveApi.DriveContentsResult result) {
                if (!result.getStatus().isSuccess()) {
                    Log.e("Unable to open,try", "data");
                    return;
                }
                File sd = Environment.getExternalStorageDirectory();
                String backupDBPath = "/Databackup.zip";
                File imgFile = new File(sd, backupDBPath);
                Log.e("FILE EXIST", imgFile.exists() + "");

                if (!imgFile.exists())
                    try {
                        imgFile.createNewFile();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                imgFile = new File(imgFile.getAbsolutePath());
                DriveContents contents = result.getDriveContents();
                try {
                    FileOutputStream fos = new FileOutputStream(imgFile.getAbsolutePath());
                    BufferedOutputStream bos = new BufferedOutputStream(fos);
                    BufferedInputStream in = new BufferedInputStream(contents.getInputStream());
                    byte[] buffer = new byte[1024];
                    int n, cnt = 0;
                    while ((n = in.read(buffer)) > 0) {
                        bos.write(buffer, 0, n);
                        cnt += n;
                        Log.e("buffer: ", buffer[0] + "");
                        Log.e("buffer: ", "" + buffer[1]);
                        Log.e("buffer: ", "" + buffer[2]);
                        Log.e("buffer: ", "" + buffer[3]);
                        bos.flush();
                    }

                    bos.close();

                } catch (FileNotFoundException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }

               //Unzip when download from drive

                try {
                    String dest_file_path = Environment.getExternalStorageDirectory()
                            .getAbsolutePath() + "/Databackup";
                    String src_location = Environment.getExternalStorageDirectory()
                            .getAbsolutePath() + "/Databackup.zip";
                    Decompress.unzip(new File(src_location), new File(dest_file_path));
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        };

public static void creatBackupDrive(Context ctx, GoogleApiClient apis) {
    ctxs = ctx;
    api = apis;
    Drive.DriveApi.newDriveContents(api).setResultCallback(contentsCallback);
}

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

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

        String mimeType = MimeTypeMap.getSingleton().getExtensionFromMimeType("db");
        MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                .setTitle(GOOGLE_DRIVE_FILE_NAME) // Google Drive File name
                .setMimeType("application/zip")
                .setStarred(true).build();
        // create a file on root folder
        Drive.DriveApi.getRootFolder(api)
                .createFile(api, changeSet, result.getDriveContents())
                .setResultCallback(fileCallback);
    }

};

final public static ResultCallback<DriveFolder.DriveFileResult> fileCallback = new ResultCallback<DriveFolder.DriveFileResult>() {

    @Override
    public void onResult(DriveFolder.DriveFileResult result) {
        preferences_driverId = ctxs.getSharedPreferences("ID", MODE_PRIVATE);
        editor = preferences_driverId.edit();
        if (!result.getStatus().isSuccess()) {
            Log.v(TAG, "Error while trying to create the file");
            return;
        }
        driveId = result.getDriveFile().getDriveId();
        Log.e(TAG, "Created a file with content: " + driveId);
        Gson gson = new Gson();
        String json = gson.toJson(driveId); // myObject - instance of MyObject
        editor.putString("drive_id", json).commit();
        Log.e(TAG, "driveId " + driveId);
        mfile = result.getDriveFile();
        mfile.open(api, DriveFile.MODE_WRITE_ONLY, new DriveFile.DownloadProgressListener() {
            @Override
            public void onProgress(long bytesDownloaded, long bytesExpected) {
                Log.e(TAG, "Creating backup file" + bytesDownloaded + "/" + bytesExpected);
            }
        }).setResultCallback(contentsOpenedCallback);
    }
};
final public static ResultCallback<DriveApi.DriveContentsResult> contentsOpenedCallback = new ResultCallback<DriveApi.DriveContentsResult>() {

    @Override
    public void onResult(DriveApi.DriveContentsResult result) {
        if (!result.getStatus().isSuccess()) {
            Log.v(TAG, "Error opening file");
            return;
        }
        String sd = Environment.getExternalStorageDirectory().getAbsolutePath() + "/DiaryDatabackup.zip";
        Log.e("DB FILE NAME---", sd + "");
        DriveContents contents = result.getDriveContents();
        BufferedOutputStream out = new BufferedOutputStream(contents.getOutputStream());
        byte[] buffer = new byte[1024];
        int n;

        try {
            FileInputStream is = new FileInputStream(sd);
            BufferedInputStream in = new BufferedInputStream(is);

            while ((n = in.read(buffer)) > 0) {
                out.write(buffer, 0, n);
                Log.e("Backing up...", "Backup");
            }
            out.close();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        contents.commit(api, null).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(Status status) {
                Log.e("Backup completed!", "complete"+status);

            }
        });
    }
};
public static  void trash(DriveId dId, GoogleApiClient apis) {
    api = apis;
    try {
        Log.e(TAG,"Goes in trans" );
        DriveFile sumFile = dId.asDriveFile();
        com.google.android.gms.common.api.Status deleteStatus =
                sumFile.delete(api).await();
        if (!deleteStatus.isSuccess()) {
            Log.e(TAG, "Unable to delete app data.");

        } else {
            // Remove stored DriveId.
            preferences_driverId.edit().remove("drive_id").apply();
        }
        Log.d(TAG, "Past sums deleted.");
    } catch (Exception e) {
        e.printStackTrace();
    }
}


public static void restore(Context ctx) {
    OutputStream myOutput;
    String dbpath = "//data//" + ctx.getPackageName() + "//databases//databaseName.db";
    String sdpath = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Databackup";
    File directorys = new File(sdpath + "/backup_sd");
    if (directorys.exists()) {
        try {
            myOutput = new FileOutputStream(Environment.getDataDirectory()
                    + dbpath);
            // Set the folder on the SDcard
            File directory = new File(sdpath + "/backup_sd");
            // Set the input file stream up:
            InputStream myInputs = new FileInputStream(directory.getPath());
            // Transfer bytes from the input file to the output file
            byte[] buffer = new byte[1024];
            int length;
            while ((length = myInputs.read(buffer)) > 0) {
                myOutput.write(buffer, 0, length);
            }
            // Close and clear the streams
            myOutput.flush();
            myOutput.close();
            myInputs.close();
            Toast.makeText(ctx, R.string.successss, Toast.LENGTH_LONG)
                    .show();

        } catch (FileNotFoundException e) {
            Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
            e.printStackTrace();
        } catch (IOException e) {
            Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();

            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    } else {
        Log.e("NO DB YET ", "Created");
        Toast.makeText(ctx, R.string.savesome, Toast.LENGTH_LONG).show();

    }

}

public static void create_backup(Context ctx) {
    InputStream myInput;
    String dbpath = "//data//" + ctx.getPackageName() + "//databases//databaseName.db";
    String sdpath_createbackup = Environment.getExternalStorageDirectory().getAbsolutePath() + "/Databackup";
    File file = new File(sdpath_createbackup);
    if (!file.exists())
        file.mkdirs();
    try {

        myInput = new FileInputStream(Environment.getDataDirectory()
                + dbpath);
        // Set the output folder on the Scard
        File directory = new File(file + "/backup_sd");
        // Create the folder if it doesn't exist:
        if (!directory.exists()) {
            directory.createNewFile();
        }
        // Set the output file stream up:
        OutputStream myOutput = new FileOutputStream(directory.getPath());
        // Transfer bytes from the input file to the output file
        byte[] buffer = new byte[100024];
        int length;
        while ((length = myInput.read(buffer)) > 0) {
            myOutput.write(buffer, 0, length);
        }
        // Close and clear the streams
        myOutput.flush();
        myOutput.close();
        myInput.close();
        Toast.makeText(ctx, R.string.backups, Toast.LENGTH_LONG)
                .show();

    } catch (FileNotFoundException e) {
        Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
        Log.e("error", e.getMessage());

        // TODO Auto-generated catch block
        e.printStackTrace();
    } catch (IOException e) {
        Toast.makeText(ctx, ctx.getString(R.string.err), Toast.LENGTH_LONG).show();
        Log.e("error 1", e.getMessage());
        // TODO Auto-generated catch block
        e.printStackTrace();

    }
    String src_file_path = Environment.getExternalStorageDirectory()
            .getAbsolutePath() + "/Databackup";
    String destination_location = Environment.getExternalStorageDirectory()
            .getAbsolutePath() + "/Databackup.zip";
    Decompress.backupfolder(new File(src_file_path), new File(destination_location));
  }
}

你需要分解器文件,只需创建并复制这个

public class Decompress {

public static  boolean unzip(File zipfile, File directory) {
    BufferedReader br = null;
    try {
        ZipFile zfile = new ZipFile(zipfile);
        Enumeration<? extends ZipEntry> entries = zfile.entries();
        while (entries.hasMoreElements()) {
            ZipEntry entry = entries.nextElement();
            File file = new File(directory, entry.getName());
            if (entry.isDirectory()) {
                file.mkdirs();
            } else {
                file.getParentFile().mkdirs();
                InputStream in = zfile.getInputStream(entry);
                copy(in, file);
                in.close();
            }
        }
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    } finally {
        try {
            if (br != null) br.close();
        } catch (IOException ex) {
            ex.printStackTrace();

        }
    }
    return true;
}


public static boolean backupfolder(File directory, File zipfile) {
    try {
        URI base = directory.toURI();
        Deque<File> queue = new LinkedList<>();
        queue.push(directory);
        OutputStream out = new FileOutputStream(zipfile);
        Closeable res = out;
        ZipOutputStream zout = new ZipOutputStream(out);
        res = zout;
        while (!queue.isEmpty()) {
            directory = queue.pop();
            for (File kid : directory.listFiles()) {
                String name = base.relativize(kid.toURI()).getPath();
                if (kid.isDirectory()) {
                    queue.push(kid);
                    name = name.endsWith("/") ? name : name + "/";
                    zout.putNextEntry(new ZipEntry(name));
                } else {
                    zout.putNextEntry(new ZipEntry(name));
                    copy(kid, zout);
                    zout.closeEntry();
                }
            }
        }
        res.close();
    } catch (Exception e) {
        e.printStackTrace();
        return false;
    }
    return true;
}

private static void copy(InputStream in, OutputStream out) throws IOException {
    byte[] buffer = new byte[1024];
    while (true) {
        int readCount = in.read(buffer);
        if (readCount < 0) {
            break;
        }
        out.write(buffer, 0, readCount);
    }
}

private static void copy(File file, OutputStream out) throws IOException {
    InputStream in = new FileInputStream(file);
    try {
        copy(in, out);
    } finally {
        in.close();
    }
}

private static void copy(InputStream in, File file) throws IOException {
    OutputStream out = new FileOutputStream(file);
    try {
        copy(in, out);
    } finally {
        out.close();
    }
  }
}

【讨论】:

  • 我没看懂,请你解释一下。
  • 现在你只需要复制和粘贴就可以了,只需从你的数据库名称更改数据库名称就可以了
  • 你能把完整的项目发给我吗,我可以测试并做出很容易的改变。
  • 它是完整的代码你只需要使用google api来连接和连接时使用上面的代码这样google_api_client = new GoogleApiClient.Builder(this).addApi(Drive.API).addScope(Drive.范围文件)。 addConnectionCallbacks(this).addOnConnectionFailedListener(this).build(); @justchill
  • 我不明白。如果你把项目发给我只运行它。
【解决方案2】:

我的回答假设您有一个密钥库文件来签署您的应用程序。如果您不这样做,this 链接会告诉您如何操作。

接下来您需要下载 Android 和 Google Play 服务 SDK 并获得 Android 证书,如 here 所述

现在您的应用应该能够访问 Google Drive API。

在您的活动中,创建这些变量

 /**
 * Handle access to Drive resources/files.
 */
DriveResourceClient mDriveResourceClient;

/**
 * Base folder. This is where the backup will be created
 */
DriveFolder baseFolder;

/**
 * Request code for google sign-in, to be used for result of Drive sign-in
 * Can be any suitable value
 */
protected static final int REQUEST_CODE_SIGN_IN = 0;

/**
 * String variables to hold file names, file paths etc.
 */
static final String BACK_UP = <NAME OF BACKUP FILE CREATED ON DRIVE> ;
static final String dbPath = <PATH TO YOUR DATABASE>;
static final String DATABASE_NAME = <NAME OF YOUR DATABASE>;

/*
 * This text view is used to show the output from various operations
 */
private TextView tvDriveResult;

当用户启动备份过程时调用函数singIn()

 /**
 * Starts the sign-in process and initializes the Drive client.
 */
private void singIn() {
    Set<Scope> requiredScopes = new HashSet<>(2);

    requiredScopes.add(Drive.SCOPE_FILE);
    GoogleSignInAccount signInAccount = GoogleSignIn.getLastSignedInAccount(this);

    if (signInAccount != null && signInAccount.getGrantedScopes().containsAll(requiredScopes)) {
        initializeDriveClient(signInAccount);
    } else {
        GoogleSignInOptions signInOptions =
                new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                        .requestScopes(Drive.SCOPE_FILE)
                        .build();

        GoogleSignInClient googleSignInClient = GoogleSignIn.getClient(this, signInOptions);
        startActivityForResult(googleSignInClient.getSignInIntent(), REQUEST_CODE_SIGN_IN);
    }
}

singIn() 函数将通过启动 Google 登录客户端来处理用户登录。您将需要处理此客户端的结果。使用以下代码。

/**
 * Handles resolution callbacks.
 */
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case REQUEST_CODE_SIGN_IN:
            if (resultCode != RESULT_OK) {
                /* Sign-in may fail or be cancelled by the user. For this sample, sign-in is
                * required and is fatal. For apps where sign-in is optional,       handle appropriately
                */
                Log.e(TAG, "Sign-in failed.");
                return;
            }

            Task<GoogleSignInAccount> getAccountTask =
                    GoogleSignIn.getSignedInAccountFromIntent(data);
            if (getAccountTask.isSuccessful()) {
                initializeDriveClient(getAccountTask.getResult());
            } else {
                Log.e(TAG, "Sign-in failed.");
                tvDriveResult.append("Sign-in failed\n");
            }
            break;
    }
    super.onActivityResult(requestCode, resultCode, data);
}

登录成功后,上面调用initializeDriveClient(GoogleSignInAccount signInAccount)函数初始化驱动客户端。

/**
 * Continues the sign-in process, initializing the Drive clients with the current
 * user's account.
 */
private void initializeDriveClient(GoogleSignInAccount signInAccount) {
    mDriveClient = Drive.getDriveClient(getApplicationContext(), signInAccount);
    mDriveResourceClient = Drive.getDriveResourceClient(getApplicationContext(), signInAccount);
    onDriveClientReady();
}

驱动客户端设置后,调用onDriveClientReady()。此功能继续创建/恢复您的备份。这里的功能很简单。获取用户的 Google Drive 帐户的基本文件夹。湾。检查是否存在备份文件。 C。如果是,则将该备份复制到本地数据库文件(覆盖完整文件)。 d。如果不是,则将本地数据库文件复制到用户的 Google Drive 基本文件夹。如果您愿意,您可以在此逻辑中添加一些技巧。我的代码是为了帮助你理解这个过程。

/**
 * Called after the user has signed in and the Drive client has been initialized.
 */
 private void onDriveClientReady(){
/*   Initialise the root folder. */
/* Since the tasks are executed in a separate execution threads, the remaining tasks are called from within each other */
     getRootFolder();
}

getRootFolder() 函数进行如下

    private void getRootFolder() {
     /* Get the app folder */
     Task<DriveFolder> appFolderTask = mDriveResourceClient.getRootFolder();

     appFolderTask
             .addOnSuccessListener(this, new OnSuccessListener<DriveFolder>() {
         @Override
         public void onSuccess(DriveFolder driveFolder) {
             tvDriveResult.append("Root folder found\n");
             baseFolder = driveFolder;
     /* Base folder is found, now check if backup file exists */
             checkForBackUp();

            /* Use this to delete files. Remember to comment out the line able it */
            /* listFilesInBaseFolder(); */
         }
     })
             .addOnFailureListener(this, new OnFailureListener() {
         @Override
         public void onFailure(@NonNull Exception e) {
             tvDriveResult.append("Root folder not found, error: " + e.toString() + "\n");
         }
     });

}

这里还有一个名为listFilesInBaseFolder() 的功能可以删除(永久删除而不是简单地删除)您创建的所有文件。它已被注释掉。如果您想删除您创建的文件,请谨慎使用。据我所知,它仅适用于您的应用程序创建的文件。

检查备份。

    private void checkForBackUp() {
       /* Build a query */
    Query query = new Query.Builder()
            .addFilter(Filters.eq(SearchableField.TITLE, BACK_UP))
            .build();

       /* Query contents of app folder */
    Task<MetadataBuffer> queryTask = mDriveResourceClient.queryChildren(baseFolder, query);

       /* Check for result of query */
    queryTask
            .addOnSuccessListener(this, new OnSuccessListener<MetadataBuffer>() {
        @Override
        public void onSuccess(MetadataBuffer metadataBuffer) {
       /* if count is 0, the file doesn't exist */
            if (metadataBuffer.getCount() == 0){
                tvDriveResult.append("File " + BACK_UP + " not found\n");
       /* Make file backup */
                backUpDatabase();
            } else {
                tvDriveResult.append(metadataBuffer.getCount() + " Instances of file " + BACK_UP + " found\n");
                Metadata metadata = metadataBuffer.get(0);
                restoreBackUp(metadata.getDriveId().asDriveFile());
            }
        }
    })
            .addOnFailureListener(this, new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception e) {
            tvDriveResult.append("Could not search for file, error: " + e.toString() + "\n");
        }
    });
}

restoreBackUp(DriveFile driveFile) 将使用在 Goole Drive 上找到的文件覆盖本地数据库文件。

    private void restoreBackUp(DriveFile driveFile) {
    tvDriveResult.append("Restoring from backup\n");
    /*  Get the path of the local backup */
    File dbFileOld = new File(dbPath + DATABASE_NAME);

    /* Check of dbFileExists on device, delete if it does because it needs to be completely over written */
    if (dbFileOld.exists()){
        dbFileOld.delete();
    }

    File dbFileNew = new File(dbPath + DATABASE_NAME);

    /* File input stream from database to read from */
    final FileOutputStream fileOutputStream;
    try {
        fileOutputStream = new FileOutputStream(dbFileNew);
    } catch (FileNotFoundException e) {
        tvDriveResult.append("Could not get input stream from local file\n");
        return;
    }
    /* Task to open file */
    Task<DriveContents> openFileTask =
            mDriveResourceClient.openFile(driveFile, DriveFile.MODE_READ_ONLY);

    /* Continue with task */
    openFileTask.continueWithTask(new Continuation<DriveContents, Task<Void>>(){

        @Override
        public Task<Void> then(@NonNull Task<DriveContents> task) throws Exception {
            DriveContents backupContents = task.getResult();
            InputStream inputStream = backupContents.getInputStream();

            tvDriveResult.append("Attempting to restore from database\n");

            byte[] buffer = new byte[4096];
            int c;

            while ((c = inputStream.read(buffer, 0, buffer.length)) > 0){
                fileOutputStream.write(buffer, 0, c);
            }
            fileOutputStream.flush();
            fileOutputStream.close();
            fileOutputStream.flush();
            fileOutputStream.close();
            tvDriveResult.append("Database restored\n");

      /* Return statement needed to avoid task failure */
            Task<Void> discardTask = mDriveResourceClient.discardContents(backupContents);
            return discardTask;
        }
    })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    tvDriveResult.append("Could not read file contents\n");
                }
            });

}

最后,backUpDatabase() 创建本地数据库的备份。

    private void backUpDatabase() {
     tvDriveResult.append("Creating Drive back-up");
 /* get the path of the local backup */
    File dbFile = new File(dbPath + DATABASE_NAME);

 /* Check of dbFileExists on device */
    if (! dbFile.exists()){
        tvDriveResult.append("Local database not found?!\n");
        return;
    }
 /* File input stream from database to read from */
    final FileInputStream fileInputStream;
    try {
        fileInputStream = new FileInputStream(dbFile);
    } catch (FileNotFoundException e) {
        tvDriveResult.append("Could not get input stream from local file\n");
        return;
    }

  /* Task to make file */
    final Task<DriveContents> createContentsTask = mDriveResourceClient.createContents();

    tvDriveResult.append("Creating a back-up of the Database File\n");

    Tasks.whenAll(createContentsTask).continueWithTask(new Continuation<Void, Task<DriveFile>>() {

        @Override
        public Task<DriveFile> then(@NonNull Task<Void> task) throws Exception {
   /* Retrieved the drive contents returned by the Task */
            DriveContents contents = createContentsTask.getResult();

   /* Output stream where data will be written */
            OutputStream outputStream = contents.getOutputStream();
   /* File output stream */
            tvDriveResult.append("Attempting to write\n");

            byte[] buffer = new byte[4096];
            int c;

            while ((c = fileInputStream.read(buffer, 0, buffer.length)) > 0){
                outputStream.write(buffer, 0, c);
            }
            outputStream.flush();
            outputStream.close();
            fileInputStream.close();
            tvDriveResult.append("Database written\n");

    /* Save the file, using MetadataChangeSet */
            MetadataChangeSet changeSet = new MetadataChangeSet.Builder()
                    .setTitle(BACK_UP)
                    .setMimeType("application/x-sqlite3")
                    .setStarred(false)
                    .build();

            return mDriveResourceClient.createFile(baseFolder, changeSet, contents);
        }
    })
    /* Task successful */
            .addOnSuccessListener(new OnSuccessListener<DriveFile>() {
                @Override
                public void onSuccess(DriveFile driveFile) {
                    tvDriveResult.append("Back up file created\n");
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    tvDriveResult.append("Could not create back up file\n");
                }
            });

}

就是这样!这应该让您开始基本操作。我建议通过Google's Developer Guide 进行更深入的了解。

【讨论】:

  • 你能更新你的答案吗? DriveResourceClient 已被弃用
  • 新的 API 看起来比这个冗长复杂的答案更好用。在此处检查文件上传:developers.google.com/drive/api/v3/manage-uploads 在 File file = driveService.files().create(fileMetadata, mediaContent) 中将 mediaContent 替换为您的数据库文件
猜你喜欢
  • 1970-01-01
  • 2014-11-26
  • 1970-01-01
  • 2023-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多