diff --git a/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibrary.java b/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibrary.java index 97f0830b..02042047 100644 --- a/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibrary.java +++ b/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016-2017 Adrian Ulrich + * Copyright (C) 2016-2018 Adrian Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -33,6 +33,10 @@ import java.io.ObjectInputStream; import java.io.Serializable; import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStream; +import java.io.OutputStream; public class MediaLibrary { @@ -264,6 +268,28 @@ public class MediaLibrary { return sScanner.describeScanProgress(); } + /** + * Dumps a copy of the media database to a specified path. + * + * @param context the context to use. + * @param dst the destination path of the db dump. + */ + public static void createDebugDump(Context context, String dst) { + final String src = context.getDatabasePath(MediaLibraryBackend.DATABASE_NAME).getPath(); + try { + try (InputStream in = new FileInputStream(src)) { + try (OutputStream out = new FileOutputStream(dst)) { + byte[] buffer = new byte[4096]; + int len = 0; + while ((len = in.read(buffer)) > 0) { + out.write(buffer, 0, len); + } + } + } + } catch (Exception e) { + Log.v("VanillaMusic", "Debug dump failed: "+e); + } + } /** * Registers a new content observer for the media library diff --git a/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibraryBackend.java b/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibraryBackend.java index 9b54ef8f..8aa6980a 100644 --- a/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibraryBackend.java +++ b/app/src/main/java/ch/blinkenlights/android/medialibrary/MediaLibraryBackend.java @@ -39,7 +39,7 @@ public class MediaLibraryBackend extends SQLiteOpenHelper { /** * on-disk file to store the database */ - private static final String DATABASE_NAME = "media-library.db"; + static final String DATABASE_NAME = "media-library.db"; /** * The magic mtime to use for songs which are in PENDING_DELETION state. * This is NOT 0 as the mtime is always expected to be > 0 for existing rows diff --git a/app/src/main/java/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java b/app/src/main/java/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java index ee7e132b..cadfc5d4 100644 --- a/app/src/main/java/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java +++ b/app/src/main/java/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2017 Adrian Ulrich + * Copyright (C) 2017-2018 Adrian Ulrich * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -26,12 +26,17 @@ import android.content.DialogInterface; import android.content.Intent; import android.database.Cursor; import android.os.Bundle; +import android.os.Environment; import android.view.LayoutInflater; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; import android.view.View; import android.view.ViewGroup; import android.widget.CheckBox; import android.widget.ProgressBar; import android.widget.TextView; +import android.widget.Toast; import java.util.Timer; import java.util.TimerTask; @@ -136,6 +141,8 @@ public class PreferencesMediaLibrary extends Fragment implements View.OnClickLis mEditButton.setOnClickListener(this); mGroupAlbumsCheck.setOnClickListener(this); mForceBastpCheck.setOnClickListener(this); + // Enable options menu. + setHasOptionsMenu(true); } @Override @@ -206,6 +213,29 @@ public class PreferencesMediaLibrary extends Fragment implements View.OnClickLis } } + private static final int MENU_DUMP_DB = 1; + @Override + public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) { + super.onCreateOptionsMenu(menu, inflater); + menu.add(0, MENU_DUMP_DB, 30, R.string.dump_database); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + case MENU_DUMP_DB: + final Context context = getActivity(); + final String path = Environment.getExternalStorageDirectory().getPath() + "/dbdump-" + context.getPackageName() + ".sqlite"; + final String msg = getString(R.string.dump_database_result, path); + + MediaLibrary.createDebugDump(context, path); + Toast.makeText(context, msg, Toast.LENGTH_SHORT).show(); + break; + default: + return super.onOptionsItemSelected(item); + } + return true; + } /** * Wrapper for updatePreferences() which warns the user about * possible consequences. diff --git a/app/src/main/res/values/translatable.xml b/app/src/main/res/values/translatable.xml index 24d76a2f..028facb1 100644 --- a/app/src/main/res/values/translatable.xml +++ b/app/src/main/res/values/translatable.xml @@ -337,6 +337,8 @@ THE SOFTWARE. Send to… No receiving apps found for this media type! Duration + Dump database + Database dumped to \'%s\' Media library Indexed directories