diff --git a/README.md b/README.md index 226a99b..c59e165 100644 --- a/README.md +++ b/README.md @@ -34,15 +34,31 @@ by [Michael Patricios (mpatric)](https://github.com/mpatric). ### Contributing +#### What can you contribute? + +Implement features you want to see, or take a look at the issue tracker and fix broken things. Before making bigger changes, see that a contributor is supporting the inclusion, so that you can be sure it will be merged. (See Discuss Ideas below) + +#### How to contribute: + If you want to contribute to this project, fork off of develop, implement what you want to implement, and submit a pull request back into develop. After testing it, if enough of the collaborators like it, we will merge it. You might want to discuss your ideas with us first though: -### Discuss Ideas +#### Discuss Ideas If you have any questions, the easiest way to get help is asking in the #playmusicexporter IRC channel on freenode. You can join that on webchat.freenode.net, or preferably, if you are not really an IRC guy anyway, try the corresponding matrix room [#playmusicexporter:jcg.re](https://matrix.to/#/#playmusicexporter:jcg.re). They are bridged together, so everything that happens in one of the rooms gets automatically transfered to the other one too. +### Supporting this project + +If you want to support this project, the best way to do so is contributing source code to the project (see above), or help with illustrations, if that is something you're good at! (I am most certainly not good at creating icons and such things) + +If you are unable to do that, but you still want to support this project, you could send me some bitcoins instead: 1NdzpDWPQ53xWT5fraGPZX5F9XrKiPBXjp + +I will distribute bitcoins send to me to others helping on the project too, so that other people contributing also have a piece of the cake. + +I might later set up [BitHub](https://github.com/WhisperSystems/BitHub) for this purpose later (if there are a lot of donations to distribute), but this project is a little small for that, and BitHub works based on the commit count only, which I would like to modify before setting that up. + ### Copyright Copyright (c) 2016 Jan Christian Grünhage. See LICENSE.txt for details. diff --git a/framework/build.gradle b/framework/build.gradle index 4b42392..b025ec0 100644 --- a/framework/build.gradle +++ b/framework/build.gradle @@ -42,5 +42,5 @@ android { dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) - compile 'com.android.support:appcompat-v7:25.2.0' + compile 'com.android.support:appcompat-v7:25.3.1' } diff --git a/framework/src/main/java/de/arcus/framework/utils/FileTools.java b/framework/src/main/java/de/arcus/framework/utils/FileTools.java index 7e4173c..b6a0c45 100644 --- a/framework/src/main/java/de/arcus/framework/utils/FileTools.java +++ b/framework/src/main/java/de/arcus/framework/utils/FileTools.java @@ -29,6 +29,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collections; import java.util.List; @@ -309,9 +310,7 @@ public class FileTools { } // Remove all blacklisted paths - for (String blacklistPath : mountPointBlacklist) { - storages.remove(blacklistPath); - } + storages.removeAll(Arrays.asList(mountPointBlacklist)); // Sort the list Collections.sort(storages); diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 18481fd..31198d4 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Sun Jan 22 21:19:51 CET 2017 +#Tue Mar 28 12:22:37 CEST 2017 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-3.4.1-all.zip diff --git a/playmusicexporter/build.gradle b/playmusicexporter/build.gradle index dcac987..954e749 100644 --- a/playmusicexporter/build.gradle +++ b/playmusicexporter/build.gradle @@ -20,8 +20,6 @@ * THE SOFTWARE. */ - - apply plugin: 'com.android.application' android { @@ -33,8 +31,8 @@ android { minSdkVersion 21 targetSdkVersion 25 // TODO Change Version with releases - versionCode 109 - versionName '0.9.5.2' + versionCode 110 + versionName '0.9.6.0' vectorDrawables.useSupportLibrary = true jackOptions { @@ -58,9 +56,10 @@ dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile project(':framework') compile project(':playmusiclib') - compile 'com.android.support:appcompat-v7:25.2.0' - compile 'com.android.support:support-v4:25.2.0' - compile 'com.android.support:design:25.2.0' - compile 'com.android.support:support-vector-drawable:25.2.0' + compile 'com.android.support:appcompat-v7:25.3.1' + compile 'com.android.support:support-v4:25.3.1' + compile 'com.android.support:design:25.3.1' + compile 'com.android.support:support-vector-drawable:25.3.1' compile 'com.github.paolorotolo:appintro:4.1.0' + compile 'ly.count.android:sdk:16.12.2' } diff --git a/playmusicexporter/src/main/AndroidManifest.xml b/playmusicexporter/src/main/AndroidManifest.xml index 8075054..09c1b32 100644 --- a/playmusicexporter/src/main/AndroidManifest.xml +++ b/playmusicexporter/src/main/AndroidManifest.xml @@ -24,8 +24,9 @@ + - + + android:label="Play Music Exporter Intro" /> diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/Intro.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/Intro.java index 3676a14..fa1d05a 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/Intro.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/Intro.java @@ -4,7 +4,6 @@ import android.Manifest; import android.content.Intent; import android.content.pm.PackageManager; import android.graphics.Color; -import android.os.AsyncTask; import android.os.Build; import android.os.Bundle; import android.support.annotation.Nullable; diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/MusicContainerListActivity.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/MusicContainerListActivity.java index 2d433f1..bf49109 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/MusicContainerListActivity.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/MusicContainerListActivity.java @@ -43,9 +43,10 @@ import android.widget.EditText; import android.widget.Toast; import de.arcus.framework.logger.Logger; -import de.arcus.framework.crashhandler.CrashHandler; import de.arcus.playmusiclib.exceptions.CouldNotOpenDatabaseException; import de.arcus.playmusiclib.exceptions.NoSuperUserException; +import ly.count.android.sdk.Countly; +import ly.count.android.sdk.DeviceId; import re.jcg.playmusicexporter.R; import re.jcg.playmusicexporter.fragments.MusicTrackListFragment; import re.jcg.playmusicexporter.fragments.MusicContainerListFragment; @@ -108,8 +109,9 @@ public class MusicContainerListActivity extends AppCompatActivity protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); - //Adds the crash handler to this class - CrashHandler.addCrashHandler(this); + Countly.sharedInstance().init(this, getString(R.string.countly_url), getString(R.string.countly_token), null, DeviceId.Type.OPEN_UDID); + Countly.sharedInstance().enableCrashReporting(); + PlayMusicExporterPreferences.init(this); if (!PlayMusicExporterPreferences.getSetupDone()) { @@ -195,11 +197,11 @@ public class MusicContainerListActivity extends AppCompatActivity } } } + /** * Loads the PlayMusicExporter lib and shows the list */ - private void loadPlayMusicExporter() - { + private void loadPlayMusicExporter() { // Gets the running instance mPlayMusicManager = PlayMusicManager.getInstance(); @@ -261,7 +263,7 @@ public class MusicContainerListActivity extends AppCompatActivity MusicContainerListFragment musicTrackListFragment = (MusicContainerListFragment) getSupportFragmentManager() .findFragmentById(R.id.fragment_main); - switch(mViewType) { + switch (mViewType) { case Album: // Load all albums to the list AlbumDataSource dataSourceAlbum = new AlbumDataSource(mPlayMusicManager); @@ -331,24 +333,21 @@ public class MusicContainerListActivity extends AppCompatActivity MenuItem itemRefreshLibrary = menu.findItem(R.id.action_refresh); itemRefreshLibrary.setOnMenuItemClickListener(item -> { - try - { + try { mPlayMusicManager.reloadDatabase(); mPlayMusicManager = null; loadPlayMusicExporter(); - Toast.makeText( this, R.string.database_reloaded, Toast.LENGTH_SHORT).show(); - } - catch (NoSuperUserException | CouldNotOpenDatabaseException e) - { - Toast.makeText( this, R.string.dialog_superuser_access_denied_title, Toast.LENGTH_SHORT).show(); + Toast.makeText(this, R.string.database_reloaded, Toast.LENGTH_SHORT).show(); + } catch (NoSuperUserException | CouldNotOpenDatabaseException e) { + Toast.makeText(this, R.string.dialog_superuser_access_denied_title, Toast.LENGTH_SHORT).show(); e.printStackTrace(); } return true; }); // Finds the search item and create the search view - MenuItem itemSearch = menu. findItem(R.id.action_search); - mSearchView = (SearchView)MenuItemCompat.getActionView(itemSearch); + MenuItem itemSearch = menu.findItem(R.id.action_search); + mSearchView = (SearchView) MenuItemCompat.getActionView(itemSearch); if (mSearchView != null) { // Sets the search listener @@ -376,4 +375,16 @@ public class MusicContainerListActivity extends AppCompatActivity return false; } + + @Override + public void onStart() { + super.onStart(); + Countly.sharedInstance().onStart(this); + } + + @Override + public void onStop() { + Countly.sharedInstance().onStop(); + super.onStop(); + } } diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/SettingsActivity.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/SettingsActivity.java index 26b8b9a..22ee299 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/SettingsActivity.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/activities/SettingsActivity.java @@ -46,31 +46,28 @@ public class SettingsActivity extends AppCompatPreferenceActivity { * A preference value change listener that updates the preference's summary * to reflect its new value. */ - private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = new Preference.OnPreferenceChangeListener() { - @Override - public boolean onPreferenceChange(Preference preference, Object value) { - String stringValue = value.toString(); + private static Preference.OnPreferenceChangeListener sBindPreferenceSummaryToValueListener = (preference, value) -> { + String stringValue = value.toString(); - if (preference instanceof ListPreference) { - // For list preferences, look up the correct display value in - // the preference's 'entries' list. - ListPreference listPreference = (ListPreference) preference; - int index = listPreference.findIndexOfValue(stringValue); + if (preference instanceof ListPreference) { + // For list preferences, look up the correct display value in + // the preference's 'entries' list. + ListPreference listPreference = (ListPreference) preference; + int index = listPreference.findIndexOfValue(stringValue); - // Set the summary to reflect the new value. - preference.setSummary( - index >= 0 - ? listPreference.getEntries()[index] - : null); + // Set the summary to reflect the new value. + preference.setSummary( + index >= 0 + ? listPreference.getEntries()[index] + : null); - } else { - // For all other preferences, set the summary to the value's - // simple string representation. - preference.setSummary(stringValue); - } - - return true; + } else { + // For all other preferences, set the summary to the value's + // simple string representation. + preference.setSummary(stringValue); } + + return true; }; /** @@ -127,15 +124,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity { @TargetApi(Build.VERSION_CODES.HONEYCOMB) public void onBuildHeaders(List
target) { loadHeadersFromResource(R.xml.pref_headers, target); - - // Remove the Debug Fragment - if (!BuildConfig.DEBUG) { - for (int i = 0; i < target.size(); i++) { - if ("Debug".equals(target.get(i).title)) { - target.remove(i); - break; - } - } + if (BuildConfig.DEBUG) { + loadHeadersFromResource(R.xml.pref_debug_header, target); } } @@ -160,19 +150,13 @@ public class SettingsActivity extends AppCompatPreferenceActivity { setHasOptionsMenu(true); - findPreference("preference_alba_export_path").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - startActivityForResult(new Intent("android.intent.action.OPEN_DOCUMENT_TREE"), REQUEST_CODE_OPEN_DOCUMENT_TREE_ALBA_PATH); - return true; - } + findPreference("preference_alba_export_path").setOnPreferenceClickListener(preference -> { + startActivityForResult(new Intent("android.intent.action.OPEN_DOCUMENT_TREE"), REQUEST_CODE_OPEN_DOCUMENT_TREE_ALBA_PATH); + return true; }); - findPreference("preference_groups_export_path").setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - startActivityForResult(new Intent("android.intent.action.OPEN_DOCUMENT_TREE"), REQUEST_CODE_OPEN_DOCUMENT_TREE_GROUPS_PATH); - return true; - } + findPreference("preference_groups_export_path").setOnPreferenceClickListener(preference -> { + startActivityForResult(new Intent("android.intent.action.OPEN_DOCUMENT_TREE"), REQUEST_CODE_OPEN_DOCUMENT_TREE_GROUPS_PATH); + return true; }); } @@ -246,12 +230,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } private void setupOnClickListeners() { - findPreference(PlayMusicExporterPreferences.AUTO_EXPORT_PATH).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - startActivityForResult(new Intent("android.intent.action.OPEN_DOCUMENT_TREE"), REQUEST_CODE_OPEN_DOCUMENT_TREE_AUTO_PATH); - return true; - } + findPreference(PlayMusicExporterPreferences.AUTO_EXPORT_PATH).setOnPreferenceClickListener(preference -> { + startActivityForResult(new Intent("android.intent.action.OPEN_DOCUMENT_TREE"), REQUEST_CODE_OPEN_DOCUMENT_TREE_AUTO_PATH); + return true; }); //For every setting that is used to define the export job, setup a listener that @@ -262,12 +243,9 @@ public class SettingsActivity extends AppCompatPreferenceActivity { } private void setupRescheduler(String preference) { - findPreference(preference).setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { - @Override - public boolean onPreferenceClick(Preference preference) { - ExportAllJob.scheduleExport(getContext()); - return false; - } + findPreference(preference).setOnPreferenceClickListener(preference1 -> { + ExportAllJob.scheduleExport(getContext()); + return false; }); } diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicContainerListFragment.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicContainerListFragment.java index fcc971f..b68d09c 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicContainerListFragment.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicContainerListFragment.java @@ -79,10 +79,7 @@ public class MusicContainerListFragment extends ListFragment { * A dummy implementation of the {@link Callbacks} interface that does * nothing. Used only when this fragment is not attached to an activity. */ - private static Callbacks sDummyCallbacks = new Callbacks() { - @Override - public void onItemSelected(MusicTrackList musicTrackList) { - } + private static Callbacks sDummyCallbacks = musicTrackList -> { }; private MusicContainerListAdapter mMusicTrackListAdapter; @@ -112,9 +109,7 @@ public class MusicContainerListFragment extends ListFragment { // Null check if (list != null) { // Copy the list - for (MusicTrackList musicTrackList : list) { - newList.add(musicTrackList); - } + newList.addAll(list); } // Set the list in the adapter @@ -145,7 +140,8 @@ public class MusicContainerListFragment extends ListFragment { setActivatedPosition(savedInstanceState.getInt(STATE_ACTIVATED_POSITION)); } } -// DEPRECATED + + // DEPRECATED @Override public void onAttach(Context context) { super.onAttach(context); diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicTrackListFragment.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicTrackListFragment.java index defe8fe..b8454f5 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicTrackListFragment.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/MusicTrackListFragment.java @@ -32,7 +32,6 @@ import android.text.TextUtils; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; -import android.widget.AdapterView; import android.widget.ImageView; import android.widget.ListView; import android.widget.TextView; @@ -197,43 +196,36 @@ public class MusicTrackListFragment extends Fragment { mListView.setAdapter(mMusicTrackAdapter); // Click on one list item - mListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { - @Override - public void onItemClick(AdapterView parent, View view, int position, long id) { - // The header is not clicked - if (position > 0) { - // We need to subtract the header view - position -= 1; + mListView.setOnItemClickListener((parent, view, position, id) -> { + // The header is not clicked + if (position > 0) { + // We need to subtract the header view + position -= 1; - // Gets the selected track - MusicTrack musicTrack = mMusicTrackAdapter.getItem(position); + // Gets the selected track + MusicTrack musicTrack = mMusicTrackAdapter.getItem(position); - // Toggle the track - selectTrack(musicTrack, view, TrackSelectionState.Toggle); - } + // Toggle the track + selectTrack(musicTrack, view, TrackSelectionState.Toggle); } }); // The floating action button mFloatingButtonExport = (FloatingActionButton) rootView.findViewById(R.id.floating_button_export); - mFloatingButtonExport.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) - { - m_CPULock.acquire(); - // Export all selected tracks - for (SelectedTrack selectedTrack : SelectedTrackList.getInstance().getSelectedItems()) { - selectedTrack.export(getActivity()); - } - - if ( m_CPULock.isHeld()) - { - m_CPULock.release(); - } - - // Clear the selection - SelectedTrackList.getInstance().clear(true); + mFloatingButtonExport.setOnClickListener(v -> { + m_CPULock.acquire(); + // Export all selected tracks + for (SelectedTrack selectedTrack : SelectedTrackList.getInstance().getSelectedItems()) { + selectedTrack.export(getActivity()); } + + if ( m_CPULock.isHeld()) + { + m_CPULock.release(); + } + + // Clear the selection + SelectedTrackList.getInstance().clear(true); }); updateFloatingButton(); } diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/NavigationDrawerFragment.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/NavigationDrawerFragment.java index 321dd89..2adde17 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/NavigationDrawerFragment.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/fragments/NavigationDrawerFragment.java @@ -22,7 +22,6 @@ package re.jcg.playmusicexporter.fragments; -import android.app.Activity; import android.content.Context; import android.content.Intent; import android.content.res.Configuration; @@ -160,47 +159,24 @@ public class NavigationDrawerFragment extends Fragment { setViewType(mViewType); // Click on album - mButtonTypeAlbum.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - setViewType(ViewType.Album); - } - }); + mButtonTypeAlbum.setOnClickListener(v -> setViewType(ViewType.Album)); // Click on artist - mButtonTypeArtist.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - setViewType(ViewType.Artist); - } - }); + mButtonTypeArtist.setOnClickListener(v -> setViewType(ViewType.Artist)); // Click on playlist - mButtonTypePlaylist.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - setViewType(ViewType.Playlist); - } - }); + mButtonTypePlaylist.setOnClickListener(v -> setViewType(ViewType.Playlist)); // Click on rated - mButtonTypeRated.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - setViewType(ViewType.Rated); - } - }); + mButtonTypeRated.setOnClickListener(v -> setViewType(ViewType.Rated)); // Click on settings - mButtonSettings.setOnClickListener(new View.OnClickListener() { - @Override - public void onClick(View v) { - Intent intentSettings = new Intent(getActivity(), SettingsActivity.class); - startActivity(intentSettings); + mButtonSettings.setOnClickListener(v -> { + Intent intentSettings = new Intent(getActivity(), SettingsActivity.class); + startActivity(intentSettings); - // Close the drawer - mDrawerLayout.closeDrawers(); - } + // Close the drawer + mDrawerLayout.closeDrawers(); }); // Color the settings button @@ -307,12 +283,7 @@ public class NavigationDrawerFragment extends Fragment { } // Defer code dependent on restoration of previous instance state. - mDrawerLayout.post(new Runnable() { - @Override - public void run() { - mDrawerToggle.syncState(); - } - }); + mDrawerLayout.post(mDrawerToggle::syncState); mDrawerLayout.setDrawerListener(mDrawerToggle); } diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportAllService.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportAllService.java index 37b1371..f136677 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportAllService.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportAllService.java @@ -9,6 +9,7 @@ import android.util.Log; import java.util.List; +import ly.count.android.sdk.Countly; import re.jcg.playmusicexporter.settings.PlayMusicExporterPreferences; import re.jcg.playmusicexporter.utils.MusicPathBuilder; import de.arcus.playmusiclib.PlayMusicManager; @@ -34,8 +35,7 @@ public class ExportAllService extends IntentService { Log.i(TAG, "Intent sent!"); } - public ExportAllService() - { + public ExportAllService() { super("AutoGPME-ExportService"); } @@ -75,10 +75,11 @@ public class ExportAllService extends IntentService { try { if (lPlayMusicManager.exportMusicTrack(lTrack, lUri, lPath, PlayMusicExporterPreferences.getFileOverwritePreference())) { Log.i(TAG, "Exported Music Track: " + getStringForTrack(lTrack)); + Countly.sharedInstance().recordEvent("Exported Song", 1); } else { Log.i(TAG, "Failed to export Music Track: " + getStringForTrack(lTrack)); } - + } catch (IllegalArgumentException e) { if (e.getMessage().contains("Invalid URI:")) { /* @@ -88,19 +89,14 @@ public class ExportAllService extends IntentService { */ Log.i(TAG, "Automatic export failed, because the URI is invalid."); } else throw e; - } - finally - { - if ( CPULock.isHeld()) - { - CPULock.release(); - } + } catch (Exception e) { + Countly.sharedInstance().logException(e); + e.printStackTrace(); } } } } - if ( CPULock.isHeld()) - { + if (CPULock.isHeld()) { CPULock.release(); } } diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportService.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportService.java index e68545f..b151357 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportService.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/services/ExportService.java @@ -31,6 +31,7 @@ import android.os.Bundle; import android.support.v4.app.NotificationCompat; import de.arcus.framework.logger.Logger; +import ly.count.android.sdk.Countly; import re.jcg.playmusicexporter.R; import de.arcus.playmusiclib.PlayMusicManager; import de.arcus.playmusiclib.datasources.MusicTrackDataSource; @@ -200,9 +201,16 @@ public class ExportService extends IntentService { updateNotification(); // Exports the song - if(!playMusicManager.exportMusicTrack(mTrackCurrent, uri, path, PlayMusicExporterPreferences.getFileOverwritePreference())) { - // Export failed - mTracksFailed ++; + try { + if (playMusicManager.exportMusicTrack(mTrackCurrent, uri, path, PlayMusicExporterPreferences.getFileOverwritePreference())) { + Countly.sharedInstance().recordEvent("Exported Song", 1); + } else { + // Export failed + mTracksFailed ++; + } + } catch (Exception e) { + Countly.sharedInstance().logException(e); + e.printStackTrace(); } } else { // Export failed diff --git a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/utils/ArtworkViewLoader.java b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/utils/ArtworkViewLoader.java index c4822bc..c359e62 100644 --- a/playmusicexporter/src/main/java/re/jcg/playmusicexporter/utils/ArtworkViewLoader.java +++ b/playmusicexporter/src/main/java/re/jcg/playmusicexporter/utils/ArtworkViewLoader.java @@ -22,14 +22,12 @@ package re.jcg.playmusicexporter.utils; -import android.graphics.Bitmap; import android.widget.ImageView; import java.lang.ref.WeakReference; import re.jcg.playmusicexporter.R; import de.arcus.playmusiclib.ArtworkLoader; -import de.arcus.playmusiclib.ArtworkLoaderCallback; import de.arcus.playmusiclib.items.ArtworkEntry; /** @@ -121,13 +119,10 @@ public class ArtworkViewLoader { maximalArtworkSize = imageViewDefault.getContext().getResources().getDimensionPixelSize(R.dimen.music_track_artwork_loading_size); // Sets the bitmap in the UI thread - Runnable runnable = new Runnable() { - @Override - public void run() { - // Default icon - imageViewDefault.setImageResource(mDefaultImage); + Runnable runnable = () -> { + // Default icon + imageViewDefault.setImageResource(mDefaultImage); - } }; imageViewDefault.post(runnable); } @@ -138,36 +133,30 @@ public class ArtworkViewLoader { mIsLoading = true; // Load the artwork - ArtworkLoader.loadArtworkAsync(mArtworkEntry, maximalArtworkSize, new ArtworkLoaderCallback() { - @Override - public void onFinished(final Bitmap bitmap) { - final ImageView imageView = mImageView.get(); + ArtworkLoader.loadArtworkAsync(mArtworkEntry, maximalArtworkSize, bitmap -> { + final ImageView imageView = mImageView.get(); - if (imageViewDefault != null) { - // Sets the bitmap in the UI thread - Runnable runnable = new Runnable() { - @Override - public void run() { - // Bitmap is valid - if (bitmap != null) - imageView.setImageBitmap(bitmap); - else - imageView.setImageResource(mDefaultImage); - } - }; - imageView.post(runnable); - } + if (imageViewDefault != null) { + // Sets the bitmap in the UI thread + Runnable runnable = () -> { + // Bitmap is valid + if (bitmap != null) + imageView.setImageBitmap(bitmap); + else + imageView.setImageResource(mDefaultImage); + }; + imageView.post(runnable); + } - // Loading is done - mIsLoading = false; + // Loading is done + mIsLoading = false; - // Loads the next image - if (mNewArtworkEntry != null) { - mArtworkEntry = mNewArtworkEntry; - mNewArtworkEntry = null; + // Loads the next image + if (mNewArtworkEntry != null) { + mArtworkEntry = mNewArtworkEntry; + mNewArtworkEntry = null; - loadImage(); - } + loadImage(); } }); } diff --git a/playmusicexporter/src/main/res/drawable-v21/button_navigation_drawer_normal.xml b/playmusicexporter/src/main/res/drawable-v21/button_navigation_drawer_normal.xml deleted file mode 100644 index 62a8436..0000000 --- a/playmusicexporter/src/main/res/drawable-v21/button_navigation_drawer_normal.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/playmusicexporter/src/main/res/drawable-v21/button_navigation_drawer_selected.xml b/playmusicexporter/src/main/res/drawable-v21/button_navigation_drawer_selected.xml deleted file mode 100644 index 7110152..0000000 --- a/playmusicexporter/src/main/res/drawable-v21/button_navigation_drawer_selected.xml +++ /dev/null @@ -1,31 +0,0 @@ - - - - - - - - - - \ No newline at end of file diff --git a/playmusicexporter/src/main/res/drawable/button_navigation_drawer_normal.xml b/playmusicexporter/src/main/res/drawable/button_navigation_drawer_normal.xml index 32cc3ba..62a8436 100644 --- a/playmusicexporter/src/main/res/drawable/button_navigation_drawer_normal.xml +++ b/playmusicexporter/src/main/res/drawable/button_navigation_drawer_normal.xml @@ -21,7 +21,11 @@ ~ THE SOFTWARE. --> - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/playmusicexporter/src/main/res/drawable/button_navigation_drawer_selected.xml b/playmusicexporter/src/main/res/drawable/button_navigation_drawer_selected.xml index 755155d..7110152 100644 --- a/playmusicexporter/src/main/res/drawable/button_navigation_drawer_selected.xml +++ b/playmusicexporter/src/main/res/drawable/button_navigation_drawer_selected.xml @@ -21,7 +21,11 @@ ~ THE SOFTWARE. --> - - - \ No newline at end of file + + + + + + + \ No newline at end of file diff --git a/playmusicexporter/src/main/res/values/constants.xml b/playmusicexporter/src/main/res/values/constants.xml new file mode 100644 index 0000000..b0f79cc --- /dev/null +++ b/playmusicexporter/src/main/res/values/constants.xml @@ -0,0 +1,5 @@ + + + https://countly.jcg.re/ + 82a1d9405388c4dd73dc9835f84c59cf4274086d + \ No newline at end of file diff --git a/playmusicexporter/src/main/res/xml/pref_debug_header.xml b/playmusicexporter/src/main/res/xml/pref_debug_header.xml new file mode 100644 index 0000000..01bfb2d --- /dev/null +++ b/playmusicexporter/src/main/res/xml/pref_debug_header.xml @@ -0,0 +1,7 @@ + +
+ + diff --git a/playmusicexporter/src/main/res/xml/pref_headers.xml b/playmusicexporter/src/main/res/xml/pref_headers.xml index 9866a60..475de8a 100644 --- a/playmusicexporter/src/main/res/xml/pref_headers.xml +++ b/playmusicexporter/src/main/res/xml/pref_headers.xml @@ -16,9 +16,5 @@ android:fragment="re.jcg.playmusicexporter.activities.SettingsActivity$AboutPreferenceFragment" android:icon="@drawable/ic_info_black_24dp" android:title="@string/pref_header_about" /> -
diff --git a/playmusiclib/src/main/java/de/arcus/playmusiclib/PlayMusicManager.java b/playmusiclib/src/main/java/de/arcus/playmusiclib/PlayMusicManager.java index 7b570ce..48bca36 100644 --- a/playmusiclib/src/main/java/de/arcus/playmusiclib/PlayMusicManager.java +++ b/playmusiclib/src/main/java/de/arcus/playmusiclib/PlayMusicManager.java @@ -25,7 +25,6 @@ package de.arcus.playmusiclib; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; -import android.database.Cursor; import android.database.SQLException; import android.database.sqlite.SQLiteDatabase; import android.graphics.Bitmap; @@ -33,10 +32,8 @@ import android.net.Uri; import android.os.Build; import android.os.Environment; import android.os.ParcelFileDescriptor; -import android.support.v4.content.FileProvider; import android.support.v4.provider.DocumentFile; import android.text.TextUtils; -import android.util.Log; import com.mpatric.mp3agic.ID3v1Genres; import com.mpatric.mp3agic.ID3v1Tag; @@ -44,7 +41,10 @@ import com.mpatric.mp3agic.ID3v2; import com.mpatric.mp3agic.ID3v22Tag; import com.mpatric.mp3agic.ID3v23Tag; import com.mpatric.mp3agic.ID3v24Tag; +import com.mpatric.mp3agic.InvalidDataException; import com.mpatric.mp3agic.Mp3File; +import com.mpatric.mp3agic.NotSupportedException; +import com.mpatric.mp3agic.UnsupportedTagException; import java.io.ByteArrayOutputStream; import java.io.File; @@ -138,6 +138,7 @@ public class PlayMusicManager { /** * The database will be copied to a temp folder to access from the app + * * @return Gets the temp path to the database */ private String getTempDatabasePath() { @@ -297,6 +298,7 @@ public class PlayMusicManager { /** * Creates a new PlayMusic manager + * * @param context App context */ public PlayMusicManager(Context context) { @@ -307,8 +309,9 @@ public class PlayMusicManager { /** * Loads all needed information and opens the database - * @throws PlayMusicNotFoundException PlayMusic is not installed - * @throws NoSuperUserException No super user permissions + * + * @throws PlayMusicNotFoundException PlayMusic is not installed + * @throws NoSuperUserException No super user permissions * @throws CouldNotOpenDatabaseException Could not open the database */ public void startUp() throws PlayMusicNotFoundException, NoSuperUserException, CouldNotOpenDatabaseException { @@ -345,7 +348,8 @@ public class PlayMusicManager { /** * Copies the database to a temp directory and opens it - * @throws NoSuperUserException No super user permissions + * + * @throws NoSuperUserException No super user permissions * @throws de.arcus.playmusiclib.exceptions.CouldNotOpenDatabaseException Could not open the database */ private void loadDatabase() throws NoSuperUserException, CouldNotOpenDatabaseException { @@ -370,7 +374,8 @@ public class PlayMusicManager { /** * Reloads the database from PlayMusic - * @throws NoSuperUserException No super user permissions + * + * @throws NoSuperUserException No super user permissions * @throws CouldNotOpenDatabaseException Could not open the database */ public void reloadDatabase() throws NoSuperUserException, CouldNotOpenDatabaseException { @@ -403,6 +408,7 @@ public class PlayMusicManager { /** * Gets the path to the music track + * * @param localCopyPath The local copy path * @return The path to the music file */ @@ -437,6 +443,7 @@ public class PlayMusicManager { /** * Gets the full path to the artwork + * * @param artworkPath The artwork path * @return The full path to the artwork */ @@ -469,12 +476,13 @@ public class PlayMusicManager { /** * Exports a track to the sd card - * @param musicTrack The music track you want to export - * @param dest The destination path - * @param forceOverwrite Forces overwrite of the destination file + * + * @param musicTrack The music track you want to export + * @param dest The destination path + * @param forceOverwrite Forces overwrite of the destination file * @return Returns whether the export was successful */ - public boolean exportMusicTrack(MusicTrack musicTrack, String dest, boolean forceOverwrite ) { + public boolean exportMusicTrack(MusicTrack musicTrack, String dest, boolean forceOverwrite) throws InvalidDataException, IOException, UnsupportedTagException, NotSupportedException { // Creates the destination directory File directory = new File(dest).getParentFile(); @@ -487,12 +495,13 @@ public class PlayMusicManager { /** * Exports a track to the sd card - * @param musicTrack The music track you want to export - * @param uri The document tree - * @param forceOverwrite Forces overwrite of the destination file + * + * @param musicTrack The music track you want to export + * @param uri The document tree + * @param forceOverwrite Forces overwrite of the destination file * @return Returns whether the export was successful */ - public boolean exportMusicTrack(MusicTrack musicTrack, Uri uri, String path, boolean forceOverwrite) { + public boolean exportMusicTrack(MusicTrack musicTrack, Uri uri, String path, boolean forceOverwrite) throws InvalidDataException, IOException, UnsupportedTagException, NotSupportedException { // Check for null if (musicTrack == null) return false; @@ -504,10 +513,9 @@ public class PlayMusicManager { String uniqueID = UUID.randomUUID().toString(); - if ( forceOverwrite || !isAlreadyThere(uri, path) ) - { + if (forceOverwrite || !isAlreadyThere(uri, path)) { - String fileTmp = getTempPath() + uniqueID +"_tmp.mp3"; + String fileTmp = getTempPath() + uniqueID + "_tmp.mp3"; // Copy to temp path failed if (!SuperUserTools.fileCopy(srcFile, fileTmp)) @@ -515,7 +523,7 @@ public class PlayMusicManager { // Encrypt the file if (musicTrack.isEncoded()) { - String fileTmpCrypt = getTempPath() + uniqueID +"_crypt.mp3"; + String fileTmpCrypt = getTempPath() + uniqueID + "_crypt.mp3"; // Encrypts the file if (trackEncrypt(musicTrack, fileTmp, fileTmpCrypt)) { @@ -530,7 +538,6 @@ public class PlayMusicManager { } - String dest; Uri copyUri = null; if (uri.toString().startsWith("file://")) { @@ -541,19 +548,19 @@ public class PlayMusicManager { FileTools.directoryCreate(parentDirectory); } else { // Complex uri (Lollipop) - dest = getTempPath() + uniqueID +"_final.mp3"; + dest = getTempPath() + uniqueID + "_final.mp3"; // The root DocumentFile document = DocumentFile.fromTreeUri(mContext, uri); // Creates the subdirectories - String[] directories = path.split("\\/"); - for(int i=0; i