1

我试图将 sqlite 数据库备份到谷歌驱动器并在需要时恢复它。我收到以下错误。

这是我的 GdriveActivity 代码:

import static adapter.DBAdapter.DATABASE_NAME;

public class GdriveActivity extends AppCompatActivity  {

private static final String TAG = "Google Drive Activity";

public static final int REQUEST_CODE_SIGN_IN = 0;
public static final int REQUEST_CODE_OPENING = 1;

private static final int REQUEST_CODE_OPEN_DOCUMENT = 2;

//variable for decide if i need to do a backup or a restore.
//True stands for backup, False for restore
private boolean isBackup = true;

private GdriveActivity activity;


private DriveServiceHelper mDriveServiceHelper;
private final Context context;
private String mOpenFileId;
public GdriveActivity() {

    context = null;
}

public GdriveActivity(Context ctx) {
    this.context = ctx;
}

@Override
protected void onCreate(Bundle savedInstanceState) {
    activity = this;

    super.onCreate(savedInstanceState);
    setContentView(R.layout.layout_backup_restore);


    findViewById(R.id.backupdrive).setOnClickListener(View->createFile());
    findViewById(R.id.restoredrive).setOnClickListener(View->query());


   // setupUI(db);
   // db.closeDB();
}



@Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
    switch (requestCode) {
        case REQUEST_CODE_SIGN_IN:
            if (resultCode == Activity.RESULT_OK && resultData != null) {
                handleSignInResult(resultData);
            }
            break;


    }

    super.onActivityResult(requestCode, resultCode, resultData);
}


private void createFile() {

    GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(activity);
    Log.e("account details: ", account.toString());
    if (account == null) {
    requestSignIn();
        mOpenFileId= mQuery("pregnancy.db");
    } else {
    mOpenFileId= mQuery("pregnancy.db");
    }
    if(!TextUtils.isEmpty(mOpenFileId)){
        mDriveServiceHelper.deleteFolderFile(mOpenFileId).addOnSuccessListener(v-> Log.d(TAG, "removed file ")).
                addOnFailureListener(v-> Log.d(TAG, "File was not removed: "));
        mDriveServiceHelper.saveFile();

    }
    else {

        Drive mDriveService = null;
        final String inFileName = activity.getDatabasePath(DATABASE_NAME).toString();
        java.io.File dbFile = null;

        try {
            dbFile = new java.io.File(inFileName);
            ByteArrayOutputStream bos = new ByteArrayOutputStream();

            // Transfer bytes from the inputfile to the outputfile
            byte[] bitmapdata = bos.toByteArray();

            //write the bytes in file
            FileOutputStream fos = new FileOutputStream(dbFile);
            fos.write(bitmapdata);
            fos.flush();
            fos.close();
        } catch (FileNotFoundException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

        java.io.File finalDbFile = dbFile;
            File metadata = new File()
                    .setParents(Collections.singletonList("root"))
                    .setMimeType("application/db")
                    .setName("pregnancy.db");
            FileContent fileContent = new FileContent("application/db", finalDbFile);

        File googleFile = null;
        try {
            googleFile = mDriveService.files().create(metadata,fileContent).execute();
        } catch (IOException e) {
            e.printStackTrace();
        }
        if (googleFile == null) {
                try {
                    throw new IOException("Null result when requesting file creation.");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }


    }

}
private void query() {
    final String inFileName = activity.getDatabasePath(DATABASE_NAME).toString();
    GoogleSignInAccount account = GoogleSignIn.getLastSignedInAccount(activity);
    if (account == null) {
        requestSignIn();
        mOpenFileId= mQuery("pregnancy.db");
    } else {
        mOpenFileId= mQuery("pregnancy.db");
    }
    if(!TextUtils.isEmpty(mOpenFileId)){
        context.deleteDatabase(inFileName);
        downloadFile(mOpenFileId);
        Toast.makeText(this, "File restored", Toast.LENGTH_LONG).show();
                }
    else{
        Toast.makeText(this, "No database file to restore", Toast.LENGTH_LONG).show();
    }

}
private void requestSignIn() {
    Log.d(TAG, "Requesting sign-in");

    GoogleSignInOptions signInOptions =
            new GoogleSignInOptions.Builder(GoogleSignInOptions.DEFAULT_SIGN_IN)
                    .requestEmail()
                    .requestScopes(new Scope(DriveScopes.DRIVE_FILE))
                    .build();
    GoogleSignInClient client = GoogleSignIn.getClient(this, signInOptions);

    // The result of the sign-in Intent is handled in onActivityResult.
    startActivityForResult(client.getSignInIntent(), REQUEST_CODE_SIGN_IN);
}



private void handleSignInResult(Intent result) {
    GoogleSignIn.getSignedInAccountFromIntent(result)
            .addOnSuccessListener(googleAccount -> {
                Log.d(TAG, "Signed in as " + googleAccount.getEmail());

                // Use the authenticated account to sign in to the Drive service.
                GoogleAccountCredential credential =
                        GoogleAccountCredential.usingOAuth2(
                                this, Collections.singleton(DriveScopes.DRIVE_FILE));
                credential.setSelectedAccount(googleAccount.getAccount());
                Drive googleDriveService =
                        new Drive.Builder(
                                AndroidHttp.newCompatibleTransport(),
                                new GsonFactory(),
                                credential)
                                .setApplicationName("Drive API Migration")
                                .build();

                // The DriveServiceHelper encapsulates all REST API and SAF functionality.
                // Its instantiation is required before handling any onClick actions.
                mDriveServiceHelper = new DriveServiceHelper(googleDriveService, activity);
            })
            .addOnFailureListener(exception -> Log.e(TAG, "Unable to sign in.", exception));
}

public String mQuery(String name) {
    if (mDriveServiceHelper != null) {
        Log.d(TAG, "Querying for files.");

        mDriveServiceHelper.queryFiles()
                .addOnSuccessListener(fileList -> {
                    for (File file : fileList.getFiles()) {
                        if (file.getName().equals(name))
                            mOpenFileId = file.getId();
                        break;
                    }
                    });

    }
    return mOpenFileId;
}

public void downloadFile(String fileid) {
    final String inFileName = activity.getDatabasePath(DATABASE_NAME).toString();
    java.io.File file = new java.io.File(inFileName, "pregnancy");
    mDriveServiceHelper.downloadFile(file, fileid)
            .addOnSuccessListener(new OnSuccessListener<Void>() {
                @Override
                public void onSuccess(Void aVoid) {

                    Log.i(TAG, "Downloaded the file");
                    long file_size = file.length() / 1024;
                    Log.i(TAG, "file Size :" + file_size);
                    Log.i(TAG, "file Path :" + file.getAbsolutePath());
                }
            })
            .addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {

                    Log.i(TAG, "Failed to Download the file, Exception :" + e.getMessage());
                }
            });
  }
}

这是我的 DriveServiceHelper.java 代码

public class DriveServiceHelper {
private final Executor mExecutor = Executors.newSingleThreadExecutor();
private final Drive mDriveService;

private GdriveActivity activity;
public DriveServiceHelper(Drive driveService, GdriveActivity activity) {
    mDriveService = driveService;
    this.activity=activity;
}

/**
 * Creates a text file in the user's My Drive folder and returns its file ID.
 */
public Task<String> saveFile() {
    final String inFileName = activity.getDatabasePath(DATABASE_NAME).toString();
    java.io.File dbFile = null;

    try {
        dbFile = new java.io.File(inFileName);
        ByteArrayOutputStream bos = new ByteArrayOutputStream();

        // Transfer bytes from the inputfile to the outputfile
        byte[] bitmapdata = bos.toByteArray();

        //write the bytes in file
        FileOutputStream fos = new FileOutputStream(dbFile);
        fos.write(bitmapdata);
        fos.flush();
        fos.close();
        } catch (FileNotFoundException ex) {
        ex.printStackTrace();
    } catch (IOException ex) {
        ex.printStackTrace();
    }

    java.io.File finalDbFile = dbFile;
    return Tasks.call(mExecutor, () -> {
        File metadata = new File()
                .setParents(Collections.singletonList("root"))
                .setMimeType("application/db")
                .setName("pregnancy.db");
        FileContent fileContent = new FileContent("application/db", finalDbFile);

        File googleFile = mDriveService.files().create(metadata,fileContent).execute();
        if (googleFile == null) {
            throw new IOException("Null result when requesting file creation.");
        }




        return googleFile.getId();
    });
}
public Task<Void> downloadFile(java.io.File targetFile, String fileId) {
    return Tasks.call(mExecutor, () -> {

        // Retrieve the metadata as a File object.
        OutputStream outputStream = new FileOutputStream(targetFile);
        mDriveService.files().get(fileId).executeMediaAndDownloadTo(outputStream);
        return null;
    });
}
/**
 * Opens the file identified by {@code fileId} and returns a {@link Pair} of its name and
 * contents.
 */
public Task<Pair<String, String>> readFile(String fileId) {
    return Tasks.call(mExecutor, () -> {
        // Retrieve the metadata as a File object.
        File metadata = mDriveService.files().get(fileId).execute();
        String name = metadata.getName();

        // Stream the file contents to a String.
        try (InputStream is = mDriveService.files().get(fileId).executeMediaAsInputStream();
             BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
            StringBuilder stringBuilder = new StringBuilder();
            String line;

            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            String contents = stringBuilder.toString();

            return Pair.create(name, contents);
        }
    });
}

/**
 * Updates the file identified by {@code fileId} with the given {@code name} and {@code
 * content}.
 */
public Task<Void> saveFile1(String fileId, String name, String content) {
    return Tasks.call(mExecutor, () -> {
        // Create a File containing any metadata changes.
        File metadata = new File().setName(name);

        // Convert content to an AbstractInputStreamContent instance.
        ByteArrayContent contentStream = ByteArrayContent.fromString("text/plain", content);

        // Update the metadata and contents.
        mDriveService.files().update(fileId, metadata, contentStream).execute();
        return null;
    });
}

/**
 * Returns a {@link FileList} containing all the visible files in the user's My Drive.
 *
 * <p>The returned list will only contain files visible to this app, i.e. those which were
 * created by this app. To perform operations on files not created by the app, the project must
 * request Drive Full Scope in the <a href="https://play.google.com/apps/publish">Google
 * Developer's Console</a> and be submitted to Google for verification.</p>
 */
public Task<FileList> queryFiles() {
    return Tasks.call(mExecutor, () ->
            mDriveService.files().list().setSpaces("drive").execute());
}

/**
 * Returns an {@link Intent} for opening the Storage Access Framework file picker.
 */
public Intent createFilePickerIntent() {
    Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
    intent.addCategory(Intent.CATEGORY_OPENABLE);
    intent.setType("text/plain");

    return intent;
}

/**
 * Opens the file at the {@code uri} returned by a Storage Access Framework {@link Intent}
 * created by {@link #createFilePickerIntent()} using the given {@code contentResolver}.
 */
public Task<Pair<String, String>> openFileUsingStorageAccessFramework(
        ContentResolver contentResolver, Uri uri) {
    return Tasks.call(mExecutor, () -> {
        // Retrieve the document's display name from its metadata.
        String name;
        try (Cursor cursor = contentResolver.query(uri, null, null, null, null)) {
            if (cursor != null && cursor.moveToFirst()) {
                int nameIndex = cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME);
                name = cursor.getString(nameIndex);
            } else {
                throw new IOException("Empty cursor returned for file.");
            }
        }

        // Read the document's contents as a String.
        String content;
        try (InputStream is = contentResolver.openInputStream(uri);
             BufferedReader reader = new BufferedReader(new InputStreamReader(is))) {
            StringBuilder stringBuilder = new StringBuilder();
            String line;
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line);
            }
            content = stringBuilder.toString();
        }

        return Pair.create(name, content);
    });
}

public Task<Void> deleteFolderFile(String fileId) {
    return Tasks.call(mExecutor, () -> {
        // Retrieve the metadata as a File object.
        if (fileId != null) {
            mDriveService.files().delete(fileId).execute();
        }
        return null;
    });
}

}

当我执行我得到这个错误:

java.lang.NullPointerException:尝试在 drivebackuprestore.GdriveActivity 的空对象引用上调用虚拟方法 'com.google.api.services.drive.Drive$Files com.google.api.services.drive.Drive.files()' .createFile(GdriveActivity.java:150) at drivebackuprestore.GdriveActivity.lambda$onCreate$0$GdriveActivity(GdriveActivity.java:75) at drivebackuprestore.-$$Lambda$GdriveActivity$pvZu_qquzakaJJsWZrA8BS6rMRs.onClick(Unknown Source:2) at android.view .View.performClick(View.java:7862) at android.widget.TextView.performClick(TextView.java:15004) at android.view.View.performClickInternal(View.java:7831) at android.view.View.access$3600 (View.java:879) 在 android.view.View$PerformClick.run(View.java:29359) 在 android.os.Handler.handleCallback(Handler.java:883) 在 android.os.Handler.dispatchMessage(Handler. java:100) 在 android.os.Looper。在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller 的 java.lang.reflect.Method.invoke(Native Method) 的 android.app.ActivityThread.main(ActivityThread.java:8167) 的循环(Looper.java:237)。在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100) 运行(RuntimeInit.java:496)

4

0 回答 0