diff --git a/res/layout/medialibrary_preferences.xml b/res/layout/medialibrary_preferences.xml new file mode 100644 index 00000000..d1e198d3 --- /dev/null +++ b/res/layout/medialibrary_preferences.xml @@ -0,0 +1,89 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/res/layout/sdscanner_fragment.xml b/res/layout/sdscanner_fragment.xml deleted file mode 100644 index ffeedb32..00000000 --- a/res/layout/sdscanner_fragment.xml +++ /dev/null @@ -1,47 +0,0 @@ - - - - - - - - diff --git a/res/values/translatable.xml b/res/values/translatable.xml index 9cca7ee9..402d0433 100644 --- a/res/values/translatable.xml +++ b/res/values/translatable.xml @@ -303,21 +303,14 @@ THE SOFTWARE. Send to… No receiving apps found for this media type! - - Starting a rescan causes Vanilla Music to trigger a full rebuild of the media database. - Start Rescan - Examined - Removed reference to - Will also check existing media database for updated or deleted files. - Encountered error reading media database, and might miss updated or deleted files or rescan up-to-date files. - Encountered error reading media database, but recovered. - Encountered error reading media database. Retrying in 1 second... - Processed - Completed, ready to start another scan. - Scan failed: bad path specified for new file search. - Preparing initial list of files... - Querying database... - Not yet started. - Encountered an error and skipping - SD Scanner + Media library + Media scanner + Scan full filesystem (Slow) + Flush media database (Dangerzone!) + Start scan + Statistics + + Number of songs + Play time (Hours) + Scan progress diff --git a/res/xml/preference_headers.xml b/res/xml/preference_headers.xml index 341ee025..a8119062 100644 --- a/res/xml/preference_headers.xml +++ b/res/xml/preference_headers.xml @@ -24,6 +24,9 @@ THE SOFTWARE.
+
diff --git a/res/xml/preference_misc.xml b/res/xml/preference_misc.xml index 436fb0c3..e2f09765 100644 --- a/res/xml/preference_misc.xml +++ b/res/xml/preference_misc.xml @@ -24,9 +24,6 @@ THE SOFTWARE. xmlns:android="http://schemas.android.com/apk/res/android" xmlns:vanilla="http://schemas.android.com/apk/res/ch.blinkenlights.android.vanilla" android:persistent="true"> - keep playlists + getSetScanMark(0); + } + /** * Returns some scan statistics * @@ -373,7 +383,7 @@ public class MediaScanner implements Handler.Callback { if (needsCleanup) - mBackend.cleanOrphanedEntries(); + mBackend.cleanOrphanedEntries(true); Log.v("VanillaMusic", "MediaScanner: inserted "+path); return (needsInsert || needsCleanup); diff --git a/src/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java b/src/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java new file mode 100644 index 00000000..c68d0318 --- /dev/null +++ b/src/ch/blinkenlights/android/vanilla/PreferencesMediaLibrary.java @@ -0,0 +1,159 @@ +/* + * Copyright (C) 2016 Xiao Bao Clark + * Copyright (C) 2016 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +package ch.blinkenlights.android.vanilla; + +import ch.blinkenlights.android.medialibrary.MediaLibrary; + +import android.app.Fragment; +import android.content.Context; +import android.database.Cursor; +import android.os.Bundle; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.CheckBox; +import android.widget.TextView; + +import java.util.Timer; +import java.util.TimerTask; +import android.util.Log; + +public class PreferencesMediaLibrary extends Fragment +{ + /** + * The ugly timer which fires every 200ms + */ + private Timer mTimer; + /** + * Our start button + */ + private View mStartButton; + /** + * The debug / progress text describing the scan status + */ + private TextView mProgress; + /** + * The number of songs on this device + */; + private TextView mStatsSongs; + /** + * The number of hours of music we have + */ + private TextView mStatsPlaytime; + /** + * Checkbox for full scan + */ + private CheckBox mFullScanCheck; + /** + * Checkbox for drop + */ + private CheckBox mDropDbCheck; + + @Override + public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { + return inflater.inflate(R.layout.medialibrary_preferences, container, false); + } + + @Override + public void onViewCreated(View view, Bundle savedInstanceState) { + super.onViewCreated(view, savedInstanceState); + + mStartButton = (View)view.findViewById(R.id.start_button); + mProgress = (TextView)view.findViewById(R.id.media_stats_progress); + mStatsSongs = (TextView)view.findViewById(R.id.media_stats_songs); + mStatsPlaytime = (TextView)view.findViewById(R.id.media_stats_playtime); + mFullScanCheck = (CheckBox)view.findViewById(R.id.media_scan_full); + mDropDbCheck = (CheckBox)view.findViewById(R.id.media_scan_drop_db); + + mStartButton.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + startButtonPressed(v); + } + }); + } + + @Override + public void onResume() { + super.onResume(); + mTimer = new Timer(); + // Yep: its as ugly as it seems: we are POLLING + // the database. + mTimer.scheduleAtFixedRate((new TimerTask() { + @Override + public void run() { + getActivity().runOnUiThread(new Runnable(){ + public void run() { + updateProgress(); + } + }); + }}), 0, 200); + } + + @Override + public void onPause() { + super.onPause(); + if (mTimer != null) { + mTimer.cancel(); + mTimer = null; + } + } + + /** + * Updates the view of this fragment with current information + */ + private void updateProgress() { + Context context = getActivity(); + String scanText = MediaLibrary.describeScanProgress(getActivity()); + mProgress.setText(scanText); + mStartButton.setEnabled(scanText == null); + + Integer songCount = MediaLibrary.getLibrarySize(context); + mStatsSongs.setText(songCount.toString()); + + Float playtime = calculateDuration(context) / 3600000F; + mStatsPlaytime.setText(playtime.toString()); + } + + /** + * Queries the media library and calculates the total amount of playtime in ms + * + * @param context the context to use + * @return the play time of the library in ms + */ + public int calculateDuration(Context context) { + int duration = 0; + Cursor cursor = MediaLibrary.queryLibrary(context, MediaLibrary.TABLE_SONGS, new String[]{"SUM("+MediaLibrary.SongColumns.DURATION+")"}, null, null, null); + if (cursor != null) { + if (cursor.moveToFirst()) { + duration = cursor.getInt(0); + } + cursor.close(); + } + return duration; + } + + /** + * Called when the user hits the start button + * + * @param view the view which was pressed + */ + public void startButtonPressed(View view) { + MediaLibrary.scanLibrary(getActivity(), mFullScanCheck.isChecked(), mDropDbCheck.isChecked()); + updateProgress(); + } + +} diff --git a/src/ch/blinkenlights/android/vanilla/SDScannerFragment.java b/src/ch/blinkenlights/android/vanilla/SDScannerFragment.java deleted file mode 100644 index 0f0e2d1e..00000000 --- a/src/ch/blinkenlights/android/vanilla/SDScannerFragment.java +++ /dev/null @@ -1,92 +0,0 @@ -/* - * Copyright (C) 2016 Xiao Bao Clark - * Copyright (C) 2016 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 - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ - -package ch.blinkenlights.android.vanilla; - -import ch.blinkenlights.android.medialibrary.MediaLibrary; - -import android.app.Fragment; -import android.os.Bundle; -import android.view.LayoutInflater; -import android.view.View; -import android.view.ViewGroup; -import android.widget.TextView; - -import java.util.Timer; -import java.util.TimerTask; -import android.util.Log; - -public class SDScannerFragment extends Fragment -{ - private Timer mTimer; - - @Override - public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { - return inflater.inflate(R.layout.sdscanner_fragment, container, false); - } - - @Override - public void onViewCreated(View view, Bundle savedInstanceState) { - super.onViewCreated(view, savedInstanceState); - - view.findViewById(R.id.start_button).setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - startButtonPressed(v); - } - }); - } - - @Override - public void onResume() { - super.onResume(); - Log.v("VanillaMusic", "onResume! "+mTimer); - - mTimer = new Timer(); - mTimer.scheduleAtFixedRate((new TimerTask() { - @Override - public void run() { - getActivity().runOnUiThread(new Runnable(){ - public void run() { - updateProgress(); - } - }); - }}), 0, 120); - } - - @Override - public void onPause() { - super.onPause(); - Log.v("VanillaMusic", "onPause "+mTimer); - if (mTimer != null) { - mTimer.cancel(); - mTimer = null; - } - } - - private void updateProgress() { - View button = getActivity().findViewById(R.id.start_button); - TextView progress = (TextView)getActivity().findViewById(R.id.progress_label); - String scanText = MediaLibrary.describeScanProgress(getActivity()); - progress.setText(scanText); - button.setEnabled(scanText == null); - } - - public void startButtonPressed(View view) { - MediaLibrary.scanLibrary(getActivity(), true, false); - updateProgress(); - } - -}