问题描述
我正在尝试将 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)) {
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:尝试在空对象引用上调用虚拟方法“com.google.api.services.drive.Drive$Files com.google.api.services.drive.Drive.files()” 在 drivebackuprestore.GdriveActivity.createFile(GdriveActivity.java:150) 在 drivebackuprestore.GdriveActivity.lambda$onCreate$0$GdriveActivity(GdriveActivity.java:75) 在 drivebackuprestore。-$$Lambda$GdriveActivity$pvZu_qquzakaJJsWZrA8BS6rMRs.onClick(未知来源:2) 在 android.view.View.performClick(View.java:7862) 在 android.widget.TextView.performClick(TextView.java:15004) 在 android.view.View.performClickInternal(View.java:7831) 在 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.loop(Looper.java:237) 在 android.app.ActivityThread.main(ActivityThread.java:8167) 在 java.lang.reflect.Method.invoke(Native Method) 在 com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:496) 在 com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1100)
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)