1
0
mirror of https://codeberg.org/Freeyourgadget/Gadgetbridge synced 2024-09-27 16:56:57 +02:00

Basic database import and export (to external storage)

(In the Debug Activity)
This commit is contained in:
cpfeiffer 2015-07-08 23:03:34 +02:00
parent b9d5fc6572
commit cc549a6c49
5 changed files with 205 additions and 20 deletions

View File

@ -13,20 +13,34 @@ import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import nodomain.freeyourgadget.gadgetbridge.database.ActivityDatabaseHandler;
import nodomain.freeyourgadget.gadgetbridge.database.DBHelper;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class DebugActivity extends Activity {
Button sendSMSButton;
Button sendEmailButton;
Button incomingCallButton;
Button outgoingCallButton;
Button startCallButton;
Button endCallButton;
Button testNotificationButton;
Button setMusicInfoButton;
Button setTimeButton;
Button rebootButton;
EditText editContent;
private static final Logger LOG = LoggerFactory.getLogger(DebugActivity.class);
private Button sendSMSButton;
private Button sendEmailButton;
private Button incomingCallButton;
private Button outgoingCallButton;
private Button startCallButton;
private Button endCallButton;
private Button testNotificationButton;
private Button setMusicInfoButton;
private Button setTimeButton;
private Button rebootButton;
private Button exportDBButton;
private Button importDBButton;
private EditText editContent;
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@ -114,6 +128,21 @@ public class DebugActivity extends Activity {
}
});
exportDBButton = (Button) findViewById(R.id.exportDBButton);
exportDBButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
exportDB();
}
});
importDBButton = (Button) findViewById(R.id.importDBButton);
importDBButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
importDB();
}
});
rebootButton = (Button) findViewById(R.id.rebootButton);
rebootButton.setOnClickListener(new View.OnClickListener() {
@Override
@ -156,6 +185,34 @@ public class DebugActivity extends Activity {
});
}
private void exportDB() {
try {
ActivityDatabaseHandler dbHandler = GBApplication.getActivityDatabaseHandler();
DBHelper helper = new DBHelper(this);
File dir = FileUtils.getExternalFilesDir();
File destFile = helper.exportDB(dbHandler, dir);
Toast.makeText(this, "Exported to: " + destFile.getAbsolutePath(), Toast.LENGTH_LONG).show();
} catch (Exception ex) {
LOG.error("Unable to export db", ex);
Toast.makeText(this, "Error exporting DB: " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void importDB() {
try {
ActivityDatabaseHandler dbHandler = GBApplication.getActivityDatabaseHandler();
DBHelper helper = new DBHelper(this);
File dir = FileUtils.getExternalFilesDir();
File sourceFile = new File(dir, dbHandler.getDatabaseName());
helper.importDB(dbHandler, sourceFile);
helper.validateDB(dbHandler);
Toast.makeText(this, "Import successful.", Toast.LENGTH_LONG).show();
} catch (Exception ex) {
LOG.error("Unable to import db", ex);
Toast.makeText(this, "Error importing DB: " + ex.getMessage(), Toast.LENGTH_LONG).show();
}
}
private void testNotification() {
NotificationManager nManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
NotificationCompat.Builder ncomp = new NotificationCompat.Builder(this);

View File

@ -12,8 +12,10 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.File;
import java.io.IOException;
import nodomain.freeyourgadget.gadgetbridge.database.ActivityDatabaseHandler;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class GBApplication extends Application {
private static GBApplication context;
@ -47,20 +49,15 @@ public class GBApplication extends Application {
private void setupLogging() {
if (isFileLoggingEnabled()) {
File dir = getExternalFilesDir(null);
if (dir != null) {
if (!dir.exists()) {
dir.mkdirs();
}
try {
File dir = FileUtils.getExternalFilesDir();
// used by assets/logback.xml since the location cannot be statically determined
System.setProperty("GB_LOGFILES_DIR", dir.getAbsolutePath());
} else {
Log.e("GBApplication", "External files dir is null, cannot log to file");
} catch (IOException ex) {
Log.e("GBApplication", "External files dir not available, cannot log to file, ex");
System.setProperty("GB_LOGFILES_DIR", "/dev/null");
}
} else {
System.setProperty("GB_LOGFILES_DIR", "/dev/null"); // just to please logback configuration, not used at all
try {
ch.qos.logback.classic.Logger root = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.detachAppender("FILE");

View File

@ -0,0 +1,67 @@
package nodomain.freeyourgadget.gadgetbridge.database;
import android.content.Context;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import java.io.File;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import nodomain.freeyourgadget.gadgetbridge.util.FileUtils;
public class DBHelper {
private final Context context;
public DBHelper(Context context) {
this.context = context;
}
private String getClosedDBPath(SQLiteOpenHelper dbHandler) throws IllegalStateException {
SQLiteDatabase db = dbHandler.getReadableDatabase();
String path = db.getPath();
db.close(); // reference counted, so may still be open
if (db.isOpen()) {
throw new IllegalStateException("Database must be closed");
}
return path;
}
public File exportDB(SQLiteOpenHelper dbHandler, File toDir) throws IllegalStateException, IOException {
String dbPath = getClosedDBPath(dbHandler);
File sourceFile = new File(dbPath);
File destFile = new File(toDir, sourceFile.getName());
if (destFile.exists()) {
File backup = new File(toDir, destFile.getName() + "_" + getDate());
destFile.renameTo(backup);
} else if (!toDir.exists()) {
if (!toDir.mkdirs()) {
throw new IOException("Unable to create directory: " + toDir.getAbsolutePath());
}
}
FileUtils.copyFile(sourceFile, destFile);
return destFile;
}
private String getDate() {
return new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.US).format(new Date());
}
public void importDB(SQLiteOpenHelper dbHandler, File fromFile) throws IllegalStateException, IOException {
String dbPath = getClosedDBPath(dbHandler);
File toFile = new File(dbPath);
FileUtils.copyFile(fromFile, toFile);
}
public void validateDB(SQLiteOpenHelper dbHandler) throws IOException {
try (SQLiteDatabase db = dbHandler.getReadableDatabase()) {
if (!db.isDatabaseIntegrityOk()) {
throw new IOException("Database integrity is not OK");
}
}
}
}

View File

@ -0,0 +1,45 @@
package nodomain.freeyourgadget.gadgetbridge.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.channels.FileChannel;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
public class FileUtils {
/**
* Copies the the given sourceFile to destFile, overwriting it, in case it exists.
* @param sourceFile
* @param destFile
* @throws IOException
*/
public static void copyFile(File sourceFile, File destFile) throws IOException {
if (!sourceFile.exists()) {
throw new IOException("Does not exist: " + sourceFile.getAbsolutePath());
}
copyFile(new FileInputStream(sourceFile), new FileOutputStream(destFile));
}
private static void copyFile(FileInputStream sourceStream, FileOutputStream destStream) throws IOException {
try (FileChannel fromChannel = sourceStream.getChannel(); FileChannel toChannel = destStream.getChannel()) {
fromChannel.transferTo(0, fromChannel.size(), toChannel);
}
}
/**
* Returns the existing external storage dir.
* @throws IOException when the directory is not available
*/
public static File getExternalFilesDir() throws IOException {
File dir = GBApplication.getContext().getExternalFilesDir(null);
if (dir == null) {
throw new IOException("Unable to access external files dir: null");
}
if (!dir.exists() && !dir.mkdirs()) {
throw new IOException("Unable to access external files dir: does not exist");
}
return dir;
}
}

View File

@ -109,4 +109,23 @@
android:layout_alignParentStart="true"
android:layout_alignEnd="@+id/endCallButton" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Export DB"
android:id="@+id/exportDBButton"
android:layout_above="@+id/rebootButton"
android:layout_alignEnd="@+id/textView"
android:layout_alignParentStart="true"
android:singleLine="false" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Import DB"
android:id="@+id/importDBButton"
android:layout_alignTop="@+id/exportDBButton"
android:layout_alignParentEnd="true"
android:layout_toEndOf="@+id/exportDBButton" />
</RelativeLayout>