将sqlite数据库存储到Google驱动器中 [英] Store the sqlite Database into google drive

查看:82
本文介绍了将sqlite数据库存储到Google驱动器中的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have tried many example and did not find any good solution.

我要存储我的应用程序的数据以存储在sqlite数据库中,然后将其与安装该应用程序的用户的google驱动器帐户进行同步.

I want to store the data of my app to store in sqlite database then sync it with the google drive account of the user who installed the app.

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

There is also a button which will show the data from google drive and user can edit and update the data so the updated data is then store in the google drive. I'm new in Android development please help me.

我也应用了以下示例,但没有成功. https://github.com/seanpjanson/GDAADemo 使用以下方法创建/编辑/检索DB文件:GDAA(适用于Android的Google Drive Api) DriveId.getResourceId()的不可预测的结果在Google Drive Android API中 https://github.com/googledrive/android-quickstart

I also have applied the following example but did not succeed. 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

谢谢

推荐答案

我的答案假定您具有用于签名应用程序的密钥库文件.如果不这样做,请

My answer assumes that you have a keystore file to sign your app with. If you don't, this link shows you how.

下一步,您需要下载Android和Google Play Services SDK,并获得Android证书,如

The next thing you need to do is to download the Android and Google play Services SDKs and get an Android certificate, as described here

现在,您的应用应该可以访问Google云端硬盘API.

Now your app should be able to access the Google Drive APIs.

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

In your activity, create these variables

 /**
 * 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()

When the user starts the backup process call the function 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登录客户端来处理用户登录.您将需要处理此客户端的结果.使用以下代码.

The singIn() function will handle a user sign - in by starting Google Sign in Client. You will need to handle the result of this client. Use the following code.

/**
 * 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)函数在上方初始化驱动器客户端.

After sign-in has been successfully completed, the drive client is initialised above by calling the initializeDriveClient(GoogleSignInAccount signInAccount) function.

/**
 * 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().此功能将继续创建/还原您的备份.这里的功能非常简单a.获取用户的Google云端硬盘帐户的基本文件夹.b.检查是否存在备份文件.C.如果是,则将该备份复制到本地数据库文件(覆盖完整文件).d.如果不是,请将本地数据库文件复制到用户的Google Drive基本文件夹.如果愿意,您可以为此逻辑添加一些技巧.我的代码是为了帮助您了解该过程.

After the drive client is set up, onDriveClientReady() is called. This function proceeds to create / restore your back-up. The functionality here is very simple a. Get the base folder of the user's Google Drive account. b. Check if a back-up file exists. c. If yes, copy that backup to the local database file (over write complete file). d. If no, copy the local database file to the user's Google Drive base folder. You can add some finesse to this logic if you wish. My code is to help you understand the process.

/**
 * 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()的函数,用于删除(永久删除而不只是删除垃圾)您创建的所有文件.它已被注释掉.如果要删除创建的文件,请谨慎使用.据我所知,它仅适用于由您的应用程序创建的文件.

There is also a function in here called listFilesInBaseFolder() to delete (permanently delete not simply trash) all files you created. It has been commented out in. Use it in case you want to delete files you created, use with caution. As far as I can tell it works only on files that were created by your application.

检查备份.

    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上找到的文件覆盖本地数据库文件.

restoreBackUp(DriveFile driveFile) will over write the local database file with the file found on 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()创建本地数据库的备份.

And lastly, backUpDatabase() creates a backup of your local database.

    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开发人员指南.

And that is it! This should get you started with basic operations. I recommend going through Google's Developer Guide for a deeper dive.

这篇关于将sqlite数据库存储到Google驱动器中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆