Add rating in music track
More ui improvments
|
@ -243,17 +243,6 @@ public class SuperUserCommand {
|
|||
mThread.start();
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command asynchronously.
|
||||
* Please notice that the commands will only executed one after another.
|
||||
* The command will wait until the su process is free.
|
||||
* @param callback The callback instance
|
||||
* @param activity Set the activity to execute the callback on the UI thread
|
||||
*/
|
||||
public void executeAsync(SuperUserCommandCallback callback, Activity activity) {
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Execute the command and return whether the command was executed.
|
||||
* It will only return false if the app wasn't granted superuser permissions, like {@link #superuserWasSuccessful()}.
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
android:label="@string/app_name"
|
||||
android:theme="@style/AppTheme" >
|
||||
<activity
|
||||
android:name=".TrackListActivity"
|
||||
android:name=".activitys.MusicTrackListActivity"
|
||||
android:label="@string/app_name" >
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
|
@ -41,12 +41,12 @@
|
|||
</intent-filter>
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".TrackDetailActivity"
|
||||
android:name=".activitys.MusicTrackDetailActivity"
|
||||
android:label="@string/title_track_detail"
|
||||
android:parentActivityName=".TrackListActivity" >
|
||||
android:parentActivityName=".activitys.MusicTrackListActivity" >
|
||||
<meta-data
|
||||
android:name="android.support.PARENT_ACTIVITY"
|
||||
android:value=".TrackListActivity" />
|
||||
android:value=".activitys.MusicTrackListActivity" />
|
||||
</activity>
|
||||
|
||||
<meta-data android:name="crashhandler.email" android:value="mail@david-schulte.de" />
|
||||
|
|
|
@ -1,156 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2015 David Schulte
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
|
||||
import de.arcus.framework.logger.Logger;
|
||||
import de.arcus.framework.crashhandler.CrashHandler;
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.datasources.AlbumDataSource;
|
||||
import de.arcus.playmusiclib.datasources.PlaylistDataSource;
|
||||
import de.arcus.playmusiclib.enums.ID3v2Version;
|
||||
import de.arcus.playmusiclib.items.MusicTrackList;
|
||||
|
||||
/**
|
||||
* An activity representing a list of Tracks. This activity
|
||||
* has different presentations for handset and tablet-size devices. On
|
||||
* handsets, the activity presents a list of items, which when touched,
|
||||
* lead to a {@link TrackDetailActivity} representing
|
||||
* item details. On tablets, the activity presents the list of items and
|
||||
* item details side-by-side using two vertical panes.
|
||||
* <p/>
|
||||
* The activity makes heavy use of fragments. The list of items is a
|
||||
* {@link TrackListFragment} and the item details
|
||||
* (if present) is a {@link TrackDetailFragment}.
|
||||
* <p/>
|
||||
* This activity also implements the required
|
||||
* {@link TrackListFragment.Callbacks} interface
|
||||
* to listen for item selections.
|
||||
*/
|
||||
public class TrackListActivity extends ActionBarActivity
|
||||
implements TrackListFragment.Callbacks {
|
||||
|
||||
/**
|
||||
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
|
||||
* device.
|
||||
*/
|
||||
private boolean mTwoPane;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_track_list);
|
||||
|
||||
// Adds the crash handler to this class
|
||||
CrashHandler.addCrashHandler(this);
|
||||
|
||||
Logger.getInstance().logVerbose("Activity", "onCreate(" + this.getLocalClassName() + ")");
|
||||
|
||||
// Setup ActionBar
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setTitle(R.string.app_name);
|
||||
}
|
||||
|
||||
if (findViewById(R.id.track_detail_container) != null) {
|
||||
// The detail container view will be present only in the
|
||||
// large-screen layouts (res/values-large and
|
||||
// res/values-sw600dp). If this view is present, then the
|
||||
// activity should be in two-pane mode.
|
||||
mTwoPane = true;
|
||||
|
||||
// In two-pane mode, list items should be given the
|
||||
// 'activated' state when touched.
|
||||
((TrackListFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.track_list))
|
||||
.setActivateOnItemClick(true);
|
||||
}
|
||||
|
||||
// Gets the running instance
|
||||
PlayMusicManager playMusicManager = PlayMusicManager.getInstance();
|
||||
|
||||
// Create a new instance
|
||||
if (playMusicManager == null) {
|
||||
playMusicManager = new PlayMusicManager(this);
|
||||
|
||||
try {
|
||||
// Simple play ground
|
||||
playMusicManager.startUp();
|
||||
playMusicManager.setOfflineOnly(true);
|
||||
|
||||
// Setup ID3
|
||||
playMusicManager.setID3Enable(true);
|
||||
playMusicManager.setID3EnableArtwork(true);
|
||||
playMusicManager.setID3EnableFallback(true);
|
||||
playMusicManager.setID3v2Version(ID3v2Version.ID3v23);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.getInstance().logError("Test", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Load all albums to the list
|
||||
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
|
||||
//PlaylistDataSource playlistDataSource = new PlaylistDataSource(playMusicManager);
|
||||
|
||||
albumDataSource.setOfflineOnly(true);
|
||||
|
||||
((TrackListFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.track_list)).setMusicTrackList(albumDataSource.getAll());
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method from {@link TrackListFragment.Callbacks}
|
||||
* indicating that the item with the given ID was selected.
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(MusicTrackList musicTrackList) {
|
||||
if (mTwoPane) {
|
||||
// In two-pane mode, show the detail view in this activity by
|
||||
// adding or replacing the detail fragment using a
|
||||
// fragment transaction.
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putLong(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, musicTrackList.getMusicTrackListID());
|
||||
arguments.putString(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE, musicTrackList.getMusicTrackListType());
|
||||
TrackDetailFragment fragment = new TrackDetailFragment();
|
||||
fragment.setArguments(arguments);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.track_detail_container, fragment)
|
||||
.commit();
|
||||
|
||||
} else {
|
||||
// In single-pane mode, simply start the detail activity
|
||||
// for the selected item ID.
|
||||
Intent detailIntent = new Intent(this, TrackDetailActivity.class);
|
||||
detailIntent.putExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, musicTrackList.getMusicTrackListID());
|
||||
detailIntent.putExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE, musicTrackList.getMusicTrackListType());
|
||||
startActivity(detailIntent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2;
|
||||
package de.arcus.playmusicexporter2.activitys;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
|
@ -28,17 +28,20 @@ import android.support.v7.app.ActionBarActivity;
|
|||
import android.support.v4.app.NavUtils;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import de.arcus.playmusicexporter2.R;
|
||||
import de.arcus.playmusicexporter2.fragments.MusicTrackDetailFragment;
|
||||
|
||||
|
||||
/**
|
||||
* An activity representing a single Track detail screen. This
|
||||
* activity is only used on handset devices. On tablet-size devices,
|
||||
* item details are presented side-by-side with a list of items
|
||||
* in a {@link TrackListActivity}.
|
||||
* in a {@link MusicTrackListActivity}.
|
||||
* <p/>
|
||||
* This activity is mostly just a 'shell' activity containing nothing
|
||||
* more than a {@link TrackDetailFragment}.
|
||||
* more than a {@link de.arcus.playmusicexporter2.fragments.MusicTrackDetailFragment}.
|
||||
*/
|
||||
public class TrackDetailActivity extends ActionBarActivity {
|
||||
public class MusicTrackDetailActivity extends ActionBarActivity {
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
@ -62,13 +65,13 @@ public class TrackDetailActivity extends ActionBarActivity {
|
|||
// using a fragment transaction.
|
||||
Bundle arguments = new Bundle();
|
||||
|
||||
arguments.putLong(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID,
|
||||
getIntent().getLongExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, 0));
|
||||
arguments.putLong(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID,
|
||||
getIntent().getLongExtra(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, 0));
|
||||
|
||||
arguments.putString(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE,
|
||||
getIntent().getStringExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE));
|
||||
arguments.putString(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE,
|
||||
getIntent().getStringExtra(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE));
|
||||
|
||||
TrackDetailFragment fragment = new TrackDetailFragment();
|
||||
MusicTrackDetailFragment fragment = new MusicTrackDetailFragment();
|
||||
fragment.setArguments(arguments);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.add(R.id.track_detail_container, fragment)
|
||||
|
@ -87,7 +90,7 @@ public class TrackDetailActivity extends ActionBarActivity {
|
|||
//
|
||||
// http://developer.android.com/design/patterns/navigation.html#up-vs-back
|
||||
//
|
||||
NavUtils.navigateUpTo(this, new Intent(this, TrackListActivity.class));
|
||||
NavUtils.navigateUpTo(this, new Intent(this, MusicTrackListActivity.class));
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (c) 2015 David Schulte
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2.activitys;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
|
||||
import de.arcus.framework.logger.Logger;
|
||||
import de.arcus.framework.crashhandler.CrashHandler;
|
||||
import de.arcus.playmusicexporter2.R;
|
||||
import de.arcus.playmusicexporter2.fragments.MusicTrackDetailFragment;
|
||||
import de.arcus.playmusicexporter2.fragments.MusicTrackListFragment;
|
||||
import de.arcus.playmusicexporter2.fragments.NavigationDrawerFragment;
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.datasources.AlbumDataSource;
|
||||
import de.arcus.playmusiclib.datasources.ArtistDataSource;
|
||||
import de.arcus.playmusiclib.datasources.PlaylistDataSource;
|
||||
import de.arcus.playmusiclib.enums.ID3v2Version;
|
||||
import de.arcus.playmusiclib.items.MusicTrackList;
|
||||
|
||||
/**
|
||||
* An activity representing a list of Tracks. This activity
|
||||
* has different presentations for handset and tablet-size devices. On
|
||||
* handsets, the activity presents a list of items, which when touched,
|
||||
* lead to a {@link MusicTrackDetailActivity} representing
|
||||
* item details. On tablets, the activity presents the list of items and
|
||||
* item details side-by-side using two vertical panes.
|
||||
* <p/>
|
||||
* The activity makes heavy use of fragments. The list of items is a
|
||||
* {@link de.arcus.playmusicexporter2.fragments.MusicTrackListFragment} and the item details
|
||||
* (if present) is a {@link de.arcus.playmusicexporter2.fragments.MusicTrackDetailFragment}.
|
||||
* <p/>
|
||||
* This activity also implements the required
|
||||
* {@link de.arcus.playmusicexporter2.fragments.MusicTrackListFragment.Callbacks} interface
|
||||
* to listen for item selections.
|
||||
*/
|
||||
public class MusicTrackListActivity extends ActionBarActivity
|
||||
implements MusicTrackListFragment.Callbacks
|
||||
, NavigationDrawerFragment.NavigationDrawerCallbacks {
|
||||
|
||||
@Override
|
||||
public void onViewTypeChanged(NavigationDrawerFragment.ViewType viewType) {
|
||||
loadList(viewType);
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether or not the activity is in two-pane mode, i.e. running on a tablet
|
||||
* device.
|
||||
*/
|
||||
private boolean mTwoPane;
|
||||
|
||||
private PlayMusicManager mPlayMusicManager;
|
||||
|
||||
private NavigationDrawerFragment mNavigationDrawerFragment;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_track_list);
|
||||
|
||||
// Adds the crash handler to this class
|
||||
CrashHandler.addCrashHandler(this);
|
||||
|
||||
Logger.getInstance().logVerbose("Activity", "onCreate(" + this.getLocalClassName() + ")");
|
||||
|
||||
// Setup ActionBar
|
||||
ActionBar actionBar = getSupportActionBar();
|
||||
if (actionBar != null) {
|
||||
actionBar.setTitle(R.string.app_name);
|
||||
}
|
||||
|
||||
|
||||
mNavigationDrawerFragment = (NavigationDrawerFragment)
|
||||
getSupportFragmentManager().findFragmentById(R.id.navigation_drawer);
|
||||
|
||||
mNavigationDrawerFragment.setOnListViewChanged(this);
|
||||
|
||||
// Set up the drawer.
|
||||
mNavigationDrawerFragment.setUp(
|
||||
R.id.navigation_drawer,
|
||||
(DrawerLayout) findViewById(R.id.drawer_layout));
|
||||
|
||||
if (findViewById(R.id.track_detail_container) != null) {
|
||||
// The detail container view will be present only in the
|
||||
// large-screen layouts (res/values-large and
|
||||
// res/values-sw600dp). If this view is present, then the
|
||||
// activity should be in two-pane mode.
|
||||
mTwoPane = true;
|
||||
|
||||
// In two-pane mode, list items should be given the
|
||||
// 'activated' state when touched.
|
||||
((MusicTrackListFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.track_list))
|
||||
.setActivateOnItemClick(true);
|
||||
}
|
||||
|
||||
// Gets the running instance
|
||||
mPlayMusicManager = PlayMusicManager.getInstance();
|
||||
|
||||
// Create a new instance
|
||||
if (mPlayMusicManager == null) {
|
||||
mPlayMusicManager = new PlayMusicManager(this);
|
||||
|
||||
try {
|
||||
// Simple play ground
|
||||
mPlayMusicManager.startUp();
|
||||
mPlayMusicManager.setOfflineOnly(true);
|
||||
|
||||
// Setup ID3
|
||||
mPlayMusicManager.setID3Enable(true);
|
||||
mPlayMusicManager.setID3EnableArtwork(true);
|
||||
mPlayMusicManager.setID3EnableFallback(true);
|
||||
mPlayMusicManager.setID3v2Version(ID3v2Version.ID3v23);
|
||||
|
||||
} catch (Exception e) {
|
||||
Logger.getInstance().logError("Test", e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
loadList(NavigationDrawerFragment.ViewType.Album);
|
||||
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the music list with the current view type
|
||||
*/
|
||||
private void loadList(NavigationDrawerFragment.ViewType viewType) {
|
||||
// Manager is not loaded
|
||||
if (mPlayMusicManager == null) return;
|
||||
|
||||
// Gets the music list fragment
|
||||
MusicTrackListFragment musicTrackListFragment = (MusicTrackListFragment) getSupportFragmentManager()
|
||||
.findFragmentById(R.id.track_list);
|
||||
|
||||
switch(viewType) {
|
||||
case Album:
|
||||
// Load all albums to the list
|
||||
AlbumDataSource dataSourceAlbum = new AlbumDataSource(mPlayMusicManager);
|
||||
dataSourceAlbum.setOfflineOnly(true);
|
||||
musicTrackListFragment.setMusicTrackList(dataSourceAlbum.getAll());
|
||||
break;
|
||||
case Artist:
|
||||
// Load all artists to the list
|
||||
ArtistDataSource dataSourceArtist = new ArtistDataSource(mPlayMusicManager);
|
||||
dataSourceArtist.setOfflineOnly(true);
|
||||
musicTrackListFragment.setMusicTrackList(dataSourceArtist.getAll());
|
||||
break;
|
||||
case Playlist:
|
||||
// Load all playlists to the list
|
||||
PlaylistDataSource dataSourcePlaylist = new PlaylistDataSource(mPlayMusicManager);
|
||||
dataSourcePlaylist.setOfflineOnly(true);
|
||||
musicTrackListFragment.setMusicTrackList(dataSourcePlaylist.getAll());
|
||||
break;
|
||||
case Rated:
|
||||
// Load all reated albums to the list
|
||||
AlbumDataSource dataSourceRatedAlbum = new AlbumDataSource(mPlayMusicManager);
|
||||
dataSourceRatedAlbum.setOfflineOnly(true);
|
||||
dataSourceRatedAlbum.setRatedOnly(true);
|
||||
musicTrackListFragment.setMusicTrackList(dataSourceRatedAlbum.getAll());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback method from {@link de.arcus.playmusicexporter2.fragments.MusicTrackListFragment.Callbacks}
|
||||
* indicating that the item with the given ID was selected.
|
||||
*/
|
||||
@Override
|
||||
public void onItemSelected(MusicTrackList musicTrackList) {
|
||||
if (mTwoPane) {
|
||||
// In two-pane mode, show the detail view in this activity by
|
||||
// adding or replacing the detail fragment using a
|
||||
// fragment transaction.
|
||||
Bundle arguments = new Bundle();
|
||||
arguments.putLong(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, musicTrackList.getMusicTrackListID());
|
||||
arguments.putString(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE, musicTrackList.getMusicTrackListType());
|
||||
MusicTrackDetailFragment fragment = new MusicTrackDetailFragment();
|
||||
fragment.setArguments(arguments);
|
||||
getSupportFragmentManager().beginTransaction()
|
||||
.replace(R.id.track_detail_container, fragment)
|
||||
.commit();
|
||||
|
||||
} else {
|
||||
// In single-pane mode, simply start the detail activity
|
||||
// for the selected item ID.
|
||||
Intent detailIntent = new Intent(this, MusicTrackDetailActivity.class);
|
||||
detailIntent.putExtra(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, musicTrackList.getMusicTrackListID());
|
||||
detailIntent.putExtra(MusicTrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE, musicTrackList.getMusicTrackListType());
|
||||
startActivity(detailIntent);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -23,17 +23,19 @@
|
|||
package de.arcus.playmusicexporter2.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DataSetObserver;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.playmusicexporter2.R;
|
||||
import de.arcus.playmusicexporter2.utils.ImageViewLoader;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
|
||||
/**
|
||||
|
@ -45,6 +47,19 @@ public class MusicTrackAdapter extends ArrayAdapter<MusicTrack> {
|
|||
*/
|
||||
private Context mContext;
|
||||
|
||||
/**
|
||||
* If this is set the music track shows it artwork instead of the track number
|
||||
*/
|
||||
private boolean mShowArtworks = true;
|
||||
|
||||
public boolean getShowArtwok() {
|
||||
return mShowArtworks;
|
||||
}
|
||||
|
||||
public void setShowArtworks(boolean showArtworks) {
|
||||
mShowArtworks = showArtworks;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new track adapter
|
||||
* @param context The app context
|
||||
|
@ -77,9 +92,10 @@ public class MusicTrackAdapter extends ArrayAdapter<MusicTrack> {
|
|||
view = inflater.inflate(R.layout.adapter_music_track, parent, false);
|
||||
}
|
||||
|
||||
|
||||
TextView textView;
|
||||
|
||||
// Set the track number
|
||||
// Sets the track number
|
||||
textView = (TextView)view.findViewById(R.id.text_music_track_number);
|
||||
long trackPosition = musicTrack.getTrackNumber();
|
||||
|
||||
|
@ -92,12 +108,39 @@ public class MusicTrackAdapter extends ArrayAdapter<MusicTrack> {
|
|||
textView.setText("");
|
||||
textView.setTextColor(mContext.getResources().getColor(musicTrack.isOfflineAvailable() ? R.color.text_music_number : R.color.text_music_disable_number));
|
||||
|
||||
// Set the title
|
||||
// Sets the disc number
|
||||
textView = (TextView)view.findViewById(R.id.text_music_track_disc_number);
|
||||
textView.setText("CD " + musicTrack.getDiscNumber());
|
||||
// Don't show the disc number if this is a playlist or artist list
|
||||
if (musicTrack.getDiscNumber() > 0 && TextUtils.isEmpty(musicTrack.getContainerName()))
|
||||
textView.setVisibility(View.VISIBLE);
|
||||
else
|
||||
textView.setVisibility(View.GONE);
|
||||
textView.setTextColor(mContext.getResources().getColor(musicTrack.isOfflineAvailable() ? R.color.text_music_disc_number : R.color.text_music_disable_disc_number));
|
||||
|
||||
|
||||
if (mShowArtworks) {
|
||||
view.findViewById(R.id.relative_layout_number).setVisibility(View.GONE);
|
||||
view.findViewById(R.id.relative_layout_artwork).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
view.findViewById(R.id.relative_layout_number).setVisibility(View.VISIBLE);
|
||||
view.findViewById(R.id.relative_layout_artwork).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
if (mShowArtworks) {
|
||||
ImageView imageView = (ImageView) view.findViewById(R.id.image_music_track_artwork);
|
||||
imageView.setImageResource(R.drawable.cd_case);
|
||||
String artworkPath = musicTrack.getArtworkPath();
|
||||
if (artworkPath != null)
|
||||
ImageViewLoader.loadImage(imageView, artworkPath);
|
||||
}
|
||||
|
||||
// Sets the title
|
||||
textView = (TextView)view.findViewById(R.id.text_music_track_title);
|
||||
textView.setText(musicTrack.getTitle());
|
||||
textView.setTextColor(mContext.getResources().getColor(musicTrack.isOfflineAvailable() ? R.color.text_music_title : R.color.text_music_disable_title));
|
||||
|
||||
// Set the artist
|
||||
// Sets the artist
|
||||
textView = (TextView)view.findViewById(R.id.text_music_track_artist);
|
||||
textView.setText(musicTrack.getArtist());
|
||||
textView.setTextColor(mContext.getResources().getColor(musicTrack.isOfflineAvailable() ? R.color.text_music_description : R.color.text_music_disable_description));
|
||||
|
|
|
@ -23,20 +23,17 @@
|
|||
package de.arcus.playmusicexporter2.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.DataSetObserver;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListAdapter;
|
||||
import android.widget.TextView;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import de.arcus.playmusicexporter2.R;
|
||||
import de.arcus.playmusicexporter2.utils.ImageViewLoader;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
import de.arcus.playmusiclib.items.MusicTrackList;
|
||||
|
||||
/**
|
||||
|
|
|
@ -20,30 +20,35 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2;
|
||||
package de.arcus.playmusicexporter2.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.os.Environment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.Log;
|
||||
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;
|
||||
|
||||
import de.arcus.playmusicexporter2.R;
|
||||
import de.arcus.playmusicexporter2.adapter.MusicTrackAdapter;
|
||||
import de.arcus.playmusicexporter2.utils.ImageViewLoader;
|
||||
import de.arcus.playmusicexporter2.utils.MusicPathBuilder;
|
||||
import de.arcus.playmusiclib.PlayMusicManager;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
import de.arcus.playmusiclib.items.MusicTrackList;
|
||||
|
||||
|
||||
/**
|
||||
* A fragment representing a single Track detail screen.
|
||||
* This fragment is either contained in a {@link TrackListActivity}
|
||||
* in two-pane mode (on tablets) or a {@link TrackDetailActivity}
|
||||
* This fragment is either contained in a {@link de.arcus.playmusicexporter2.activitys.MusicTrackListActivity}
|
||||
* in two-pane mode (on tablets) or a {@link de.arcus.playmusicexporter2.activitys.MusicTrackDetailActivity}
|
||||
* on handsets.
|
||||
*/
|
||||
public class TrackDetailFragment extends Fragment {
|
||||
public class MusicTrackDetailFragment extends Fragment {
|
||||
/**
|
||||
* The fragment argument representing the item ID that this fragment
|
||||
* represents.
|
||||
|
@ -60,7 +65,7 @@ public class TrackDetailFragment extends Fragment {
|
|||
* Mandatory empty constructor for the fragment manager to instantiate the
|
||||
* fragment (e.g. upon screen orientation changes).
|
||||
*/
|
||||
public TrackDetailFragment() {
|
||||
public MusicTrackDetailFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -90,32 +95,67 @@ public class TrackDetailFragment extends Fragment {
|
|||
// Show the dummy content as text in a TextView.
|
||||
if (mMusicTrackList != null) {
|
||||
final ListView listView = (ListView)rootView.findViewById(R.id.list_music_track);
|
||||
final MusicTrackAdapter musicTrackAdapter = new MusicTrackAdapter(getActivity());
|
||||
|
||||
musicTrackAdapter.setShowArtworks(mMusicTrackList.getShowArtworkInTrack());
|
||||
|
||||
MusicTrackAdapter musicTrackAdapter = new MusicTrackAdapter(getActivity());
|
||||
View headerView = inflater.inflate(R.layout.header_music_track_list, listView, false);
|
||||
headerView.setEnabled(false);
|
||||
|
||||
TextView textView;
|
||||
ImageView imageView;
|
||||
|
||||
// Sets the artwork image
|
||||
imageView = (ImageView)headerView.findViewById(R.id.image_music_track_artwork);
|
||||
imageView.setImageResource(R.drawable.cd_case);
|
||||
String artworkPath = mMusicTrackList.getArtworkPath();
|
||||
if (artworkPath != null)
|
||||
ImageViewLoader.loadImage(imageView, artworkPath);
|
||||
|
||||
// Sets the title
|
||||
textView = (TextView)headerView.findViewById(R.id.text_music_track_list_title);
|
||||
textView.setText(mMusicTrackList.getTitle());
|
||||
|
||||
// Sets the description
|
||||
textView = (TextView)headerView.findViewById(R.id.text_music_track_list_description);
|
||||
textView.setText(mMusicTrackList.getDescription());
|
||||
|
||||
listView.addHeaderView(headerView);
|
||||
|
||||
musicTrackAdapter.setList(mMusicTrackList.getMusicTrackList());
|
||||
|
||||
listView.setAdapter(musicTrackAdapter);
|
||||
listView.setDrawSelectorOnTop(false);
|
||||
//listView.setDrawSelectorOnTop(false);
|
||||
listView.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
|
||||
listView.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
listView.setItemsCanFocus(false);
|
||||
|
||||
Log.d("onItemSelected", "pos: " + position);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {
|
||||
|
||||
}
|
||||
});
|
||||
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
Log.d("onItemClick", "pos: " + position);
|
||||
listView.setItemChecked(position, true);
|
||||
// The header is not clicked
|
||||
if (position > 0) {
|
||||
// We need to subtract the header view
|
||||
position -= 1;
|
||||
|
||||
// Gets the selected track
|
||||
MusicTrack musicTrack = musicTrackAdapter.getItem(position);
|
||||
|
||||
// Track is available
|
||||
if (musicTrack.isOfflineAvailable()) {
|
||||
// Build the path
|
||||
String path = MusicPathBuilder.Build(musicTrack, "{album-artist}/{album}/{disc=CD $}/{no=$$.} {title}.mp3");
|
||||
|
||||
// Path to the public music folder
|
||||
path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MUSIC) + "/" + path;
|
||||
|
||||
PlayMusicManager playMusicManager = PlayMusicManager.getInstance();
|
||||
|
||||
if (playMusicManager != null) {
|
||||
playMusicManager.exportMusicTrack(musicTrack, path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
|
@ -20,7 +20,7 @@
|
|||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2;
|
||||
package de.arcus.playmusicexporter2.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.os.Bundle;
|
||||
|
@ -39,12 +39,12 @@ import de.arcus.playmusiclib.items.MusicTrackList;
|
|||
* A list fragment representing a list of Tracks. This fragment
|
||||
* also supports tablet devices by allowing list items to be given an
|
||||
* 'activated' state upon selection. This helps indicate which item is
|
||||
* currently being viewed in a {@link TrackDetailFragment}.
|
||||
* currently being viewed in a {@link MusicTrackDetailFragment}.
|
||||
* <p/>
|
||||
* Activities containing this fragment MUST implement the {@link Callbacks}
|
||||
* interface.
|
||||
*/
|
||||
public class TrackListFragment extends ListFragment {
|
||||
public class MusicTrackListFragment extends ListFragment {
|
||||
|
||||
/**
|
||||
* The serialization (saved instance state) Bundle key representing the
|
||||
|
@ -91,7 +91,7 @@ public class TrackListFragment extends ListFragment {
|
|||
* Mandatory empty constructor for the fragment manager to instantiate the
|
||||
* fragment (e.g. upon screen orientation changes).
|
||||
*/
|
||||
public TrackListFragment() {
|
||||
public MusicTrackListFragment() {
|
||||
}
|
||||
|
||||
/**
|
|
@ -0,0 +1,391 @@
|
|||
/*
|
||||
* Copyright (c) 2015 David Schulte
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2.fragments;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.PorterDuff;
|
||||
import android.os.Bundle;
|
||||
import android.preference.PreferenceManager;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.view.GravityCompat;
|
||||
import android.support.v4.widget.DrawerLayout;
|
||||
import android.support.v7.app.ActionBar;
|
||||
import android.support.v7.app.ActionBarActivity;
|
||||
import android.support.v7.app.ActionBarDrawerToggle;
|
||||
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.Button;
|
||||
|
||||
|
||||
import de.arcus.playmusicexporter2.R;
|
||||
|
||||
/**
|
||||
* Fragment used for managing interactions for and presentation of a navigation drawer.
|
||||
* See the <a href="https://developer.android.com/design/patterns/navigation-drawer.html#Interaction">
|
||||
* design guidelines</a> for a complete explanation of the behaviors implemented here.
|
||||
*/
|
||||
public class NavigationDrawerFragment extends Fragment {
|
||||
|
||||
/**
|
||||
* Remember the position of the selected item.
|
||||
*/
|
||||
private static final String STATE_SELECTED_POSITION = "selected_navigation_drawer_position";
|
||||
|
||||
/**
|
||||
* Per the design guidelines, you should show the drawer on launch until the user manually
|
||||
* expands it. This shared preference tracks this.
|
||||
*/
|
||||
private static final String PREF_USER_LEARNED_DRAWER = "navigation_drawer_learned";
|
||||
|
||||
/**
|
||||
* A pointer to the current callbacks instance (the Activity).
|
||||
*/
|
||||
private NavigationDrawerCallbacks mCallbacks;
|
||||
|
||||
/**
|
||||
* Helper component that ties the action bar to the navigation drawer.
|
||||
*/
|
||||
private ActionBarDrawerToggle mDrawerToggle;
|
||||
|
||||
private DrawerLayout mDrawerLayout;
|
||||
private View mFragmentContainerView;
|
||||
|
||||
private int mCurrentSelectedPosition = 0;
|
||||
private boolean mFromSavedInstanceState;
|
||||
private boolean mUserLearnedDrawer;
|
||||
|
||||
private Button mButtonTypeAlbum;
|
||||
private Button mButtonTypeArtist;
|
||||
private Button mButtonTypePlaylist;
|
||||
private Button mButtonTypeRated;
|
||||
private Button mButtonSettings;
|
||||
|
||||
public enum ViewType {
|
||||
Album, Artist, Playlist, Rated
|
||||
}
|
||||
|
||||
private ViewType mViewType;
|
||||
|
||||
/**
|
||||
* @return Gets the current view type
|
||||
*/
|
||||
public ViewType getViewType() {
|
||||
return mViewType;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param viewType Sets the current view type
|
||||
*/
|
||||
private void setViewType(ViewType viewType) {
|
||||
// Change the ui
|
||||
setButtonActive(mButtonTypeAlbum, viewType == ViewType.Album);
|
||||
setButtonActive(mButtonTypeArtist, viewType == ViewType.Artist);
|
||||
setButtonActive(mButtonTypePlaylist, viewType == ViewType.Playlist);
|
||||
setButtonActive(mButtonTypeRated, viewType == ViewType.Rated);
|
||||
|
||||
if (viewType != mViewType)
|
||||
if (mCallbacks != null) mCallbacks.onViewTypeChanged(viewType);
|
||||
|
||||
mViewType = viewType;
|
||||
|
||||
// Close the drawer
|
||||
if (mDrawerLayout != null)
|
||||
mDrawerLayout.closeDrawers();
|
||||
}
|
||||
|
||||
public NavigationDrawerFragment() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
|
||||
// Read in the flag indicating whether or not the user has demonstrated awareness of the
|
||||
// drawer. See PREF_USER_LEARNED_DRAWER for details.
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getActivity());
|
||||
mUserLearnedDrawer = sp.getBoolean(PREF_USER_LEARNED_DRAWER, false);
|
||||
|
||||
if (savedInstanceState != null) {
|
||||
mCurrentSelectedPosition = savedInstanceState.getInt(STATE_SELECTED_POSITION);
|
||||
mFromSavedInstanceState = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
// Indicate that this fragment would like to influence the set of actions in the action bar.
|
||||
setHasOptionsMenu(true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container,
|
||||
Bundle savedInstanceState) {
|
||||
View view = inflater.inflate(
|
||||
R.layout.fragment_navigation_drawer, container, false);
|
||||
|
||||
// Gets all buttons
|
||||
mButtonTypeAlbum = (Button)view.findViewById(R.id.button_type_album);
|
||||
mButtonTypeArtist = (Button)view.findViewById(R.id.button_type_artist);
|
||||
mButtonTypePlaylist = (Button)view.findViewById(R.id.button_type_playlist);
|
||||
mButtonTypeRated = (Button)view.findViewById(R.id.button_type_rated);
|
||||
|
||||
mButtonSettings = (Button)view.findViewById(R.id.button_setting);
|
||||
|
||||
// Set the default
|
||||
setViewType(ViewType.Album);
|
||||
|
||||
// Click on album
|
||||
mButtonTypeAlbum.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setViewType(ViewType.Album);
|
||||
}
|
||||
});
|
||||
|
||||
// Click on artist
|
||||
mButtonTypeArtist.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setViewType(ViewType.Artist);
|
||||
}
|
||||
});
|
||||
|
||||
// Click on playlist
|
||||
mButtonTypePlaylist.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setViewType(ViewType.Playlist);
|
||||
}
|
||||
});
|
||||
|
||||
// Click on rated
|
||||
mButtonTypeRated.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
setViewType(ViewType.Rated);
|
||||
}
|
||||
});
|
||||
|
||||
// Color the settings button
|
||||
setButtonActive(mButtonSettings, false);
|
||||
|
||||
return view;
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the button
|
||||
* @param button The button
|
||||
* @param active Active
|
||||
*/
|
||||
public void setButtonActive(Button button, boolean active) {
|
||||
// Gets the button
|
||||
//Button button = (Button)parentView.findViewById(resID);
|
||||
|
||||
int colorText;
|
||||
int colorBackground;
|
||||
|
||||
// Button is active
|
||||
if (active) {
|
||||
// Gets the active color
|
||||
colorText = getResources().getColor(R.color.button_navigation_drawer_text_active);
|
||||
colorBackground = getResources().getColor(R.color.button_navigation_drawer_active);
|
||||
} else {
|
||||
// Gets the normal color
|
||||
colorText = getResources().getColor(R.color.button_navigation_drawer_text);
|
||||
colorBackground = getResources().getColor(R.color.button_navigation_drawer_normal);
|
||||
}
|
||||
|
||||
// Sets the color
|
||||
button.setBackgroundColor(colorBackground);
|
||||
button.setTextColor(colorText);
|
||||
button.getCompoundDrawables()[0].setColorFilter(colorText, PorterDuff.Mode.MULTIPLY);
|
||||
}
|
||||
|
||||
public boolean isDrawerOpen() {
|
||||
return mDrawerLayout != null && mDrawerLayout.isDrawerOpen(mFragmentContainerView);
|
||||
}
|
||||
|
||||
public void setOnListViewChanged(NavigationDrawerCallbacks callback) {
|
||||
mCallbacks = callback;
|
||||
}
|
||||
|
||||
/**
|
||||
* Users of this fragment must call this method to set up the navigation drawer interactions.
|
||||
*
|
||||
* @param fragmentId The android:id of this fragment in its activity's layout.
|
||||
* @param drawerLayout The DrawerLayout containing this fragment's UI.
|
||||
*/
|
||||
public void setUp(int fragmentId, DrawerLayout drawerLayout) {
|
||||
mFragmentContainerView = getActivity().findViewById(fragmentId);
|
||||
mDrawerLayout = drawerLayout;
|
||||
|
||||
// set a custom shadow that overlays the main content when the drawer opens
|
||||
mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START);
|
||||
// set up the drawer's list view with items and click listener
|
||||
|
||||
ActionBar actionBar = getActionBar();
|
||||
actionBar.setDisplayHomeAsUpEnabled(true);
|
||||
actionBar.setHomeButtonEnabled(true);
|
||||
|
||||
// ActionBarDrawerToggle ties together the the proper interactions
|
||||
// between the navigation drawer and the action bar app icon.
|
||||
mDrawerToggle = new ActionBarDrawerToggle(
|
||||
getActivity(), /* host Activity */
|
||||
mDrawerLayout, /* DrawerLayout object */
|
||||
R.string.navigation_drawer_open, /* "open drawer" description for accessibility */
|
||||
R.string.navigation_drawer_close /* "close drawer" description for accessibility */
|
||||
) {
|
||||
@Override
|
||||
public void onDrawerClosed(View drawerView) {
|
||||
super.onDrawerClosed(drawerView);
|
||||
if (!isAdded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDrawerOpened(View drawerView) {
|
||||
super.onDrawerOpened(drawerView);
|
||||
if (!isAdded()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!mUserLearnedDrawer) {
|
||||
// The user manually opened the drawer; store this flag to prevent auto-showing
|
||||
// the navigation drawer automatically in the future.
|
||||
mUserLearnedDrawer = true;
|
||||
SharedPreferences sp = PreferenceManager
|
||||
.getDefaultSharedPreferences(getActivity());
|
||||
sp.edit().putBoolean(PREF_USER_LEARNED_DRAWER, true).commit();
|
||||
}
|
||||
|
||||
getActivity().supportInvalidateOptionsMenu(); // calls onPrepareOptionsMenu()
|
||||
}
|
||||
};
|
||||
|
||||
// If the user hasn't 'learned' about the drawer, open it to introduce them to the drawer,
|
||||
// per the navigation drawer design guidelines.
|
||||
if (!mUserLearnedDrawer && !mFromSavedInstanceState) {
|
||||
mDrawerLayout.openDrawer(mFragmentContainerView);
|
||||
}
|
||||
|
||||
// Defer code dependent on restoration of previous instance state.
|
||||
mDrawerLayout.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mDrawerToggle.syncState();
|
||||
}
|
||||
});
|
||||
|
||||
mDrawerLayout.setDrawerListener(mDrawerToggle);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAttach(Activity activity) {
|
||||
super.onAttach(activity);
|
||||
try {
|
||||
mCallbacks = (NavigationDrawerCallbacks) activity;
|
||||
} catch (ClassCastException e) {
|
||||
throw new ClassCastException("Activity must implement NavigationDrawerCallbacks.");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetach() {
|
||||
super.onDetach();
|
||||
mCallbacks = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
outState.putInt(STATE_SELECTED_POSITION, mCurrentSelectedPosition);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigurationChanged(Configuration newConfig) {
|
||||
super.onConfigurationChanged(newConfig);
|
||||
// Forward the new configuration the drawer toggle component.
|
||||
mDrawerToggle.onConfigurationChanged(newConfig);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
|
||||
// If the drawer is open, show the global app actions in the action bar. See also
|
||||
// showGlobalContextActionBar, which controls the top-left area of the action bar.
|
||||
if (mDrawerLayout != null && isDrawerOpen()) {
|
||||
//inflater.inflate(R.menu.global, menu);
|
||||
showGlobalContextActionBar();
|
||||
}
|
||||
super.onCreateOptionsMenu(menu, inflater);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
if (mDrawerToggle.onOptionsItemSelected(item)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
/*if (item.getItemId() == R.id.action_example) {
|
||||
Toast.makeText(getActivity(), "Example action.", Toast.LENGTH_SHORT).show();
|
||||
return true;
|
||||
}*/
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
/**
|
||||
* Per the navigation drawer design guidelines, updates the action bar to show the global app
|
||||
* 'context', rather than just what's in the current screen.
|
||||
*/
|
||||
private void showGlobalContextActionBar() {
|
||||
ActionBar actionBar = getActionBar();
|
||||
actionBar.setDisplayShowTitleEnabled(true);
|
||||
actionBar.setNavigationMode(ActionBar.NAVIGATION_MODE_STANDARD);
|
||||
actionBar.setTitle(R.string.app_name);
|
||||
}
|
||||
|
||||
private ActionBar getActionBar() {
|
||||
return ((ActionBarActivity) getActivity()).getSupportActionBar();
|
||||
}
|
||||
|
||||
/**
|
||||
* Callbacks interface that all activities using this fragment must implement.
|
||||
*/
|
||||
public static interface NavigationDrawerCallbacks {
|
||||
/**
|
||||
* Called when an item in the navigation drawer is selected.
|
||||
*/
|
||||
void onViewTypeChanged(ViewType viewType);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,191 @@
|
|||
/*
|
||||
* Copyright (c) 2015 David Schulte
|
||||
*
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
* of this software and associated documentation files (the "Software"), to deal
|
||||
* in the Software without restriction, including without limitation the rights
|
||||
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
* copies of the Software, and to permit persons to whom the Software is
|
||||
* furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in
|
||||
* all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
* THE SOFTWARE.
|
||||
*/
|
||||
|
||||
package de.arcus.playmusicexporter2.utils;
|
||||
|
||||
import android.text.TextUtils;
|
||||
|
||||
import de.arcus.framework.logger.Logger;
|
||||
import de.arcus.playmusiclib.items.MusicTrack;
|
||||
|
||||
/**
|
||||
* Helper class te create a path by a user defined structure
|
||||
*/
|
||||
public class MusicPathBuilder {
|
||||
/**
|
||||
* Hides the constructor
|
||||
*/
|
||||
private MusicPathBuilder() {}
|
||||
|
||||
/**
|
||||
* Generates a path from a user defined patter
|
||||
* @param musicTrack The music track data
|
||||
* @param patter The patter
|
||||
* @return Returns the file path
|
||||
*/
|
||||
public static String Build(MusicTrack musicTrack, String patter)
|
||||
{
|
||||
String path = "";
|
||||
int pos = 0;
|
||||
|
||||
// While there is an open tag
|
||||
while (patter.indexOf('{', pos) >= 0)
|
||||
{
|
||||
// Gets the start and the end of the tag
|
||||
int posStart = patter.indexOf('{', pos);
|
||||
int posEnd = patter.indexOf('}', posStart);
|
||||
|
||||
// Gets the equal sign
|
||||
int posEqual = patter.indexOf('=', posStart);
|
||||
|
||||
// Adds the part between this tag and the last one to the path
|
||||
path += patter.substring(pos, posStart);
|
||||
|
||||
if (posEnd >= 0) {
|
||||
// Name of the tag
|
||||
String name;
|
||||
String value = "";
|
||||
|
||||
// There is an equal sign
|
||||
if (posEqual >= 0 && posEqual < posEnd) {
|
||||
name = patter.substring(posStart + 1, posEqual);
|
||||
} else {
|
||||
name = patter.substring(posStart + 1, posEnd);
|
||||
}
|
||||
|
||||
// Trim and lower
|
||||
name = name.trim().toLowerCase();
|
||||
|
||||
// Gets the values
|
||||
switch (name) {
|
||||
case "album-artist":
|
||||
if (!TextUtils.isEmpty(musicTrack.getAlbumArtist()))
|
||||
value = musicTrack.getAlbumArtist();
|
||||
break;
|
||||
case "album":
|
||||
if (!TextUtils.isEmpty(musicTrack.getAlbum()))
|
||||
value = musicTrack.getAlbum();
|
||||
break;
|
||||
case "group":
|
||||
if (!TextUtils.isEmpty(musicTrack.getContainerName()))
|
||||
value = musicTrack.getContainerName();
|
||||
break;
|
||||
case "artist":
|
||||
if (!TextUtils.isEmpty(musicTrack.getArtist()))
|
||||
value = musicTrack.getArtist();
|
||||
break;
|
||||
case "title":
|
||||
if (!TextUtils.isEmpty(musicTrack.getTitle()))
|
||||
value = musicTrack.getTitle();
|
||||
break;
|
||||
case "disc":
|
||||
if (musicTrack.getDiscNumber() > 0)
|
||||
value = String.valueOf(musicTrack.getDiscNumber());
|
||||
break;
|
||||
case "no":
|
||||
if (musicTrack.getTrackNumber() > 0)
|
||||
value = String.valueOf(musicTrack.getTrackNumber());
|
||||
break;
|
||||
case "year":
|
||||
if (!TextUtils.isEmpty(musicTrack.getYear()))
|
||||
value = musicTrack.getYear();
|
||||
break;
|
||||
case "genre":
|
||||
if (!TextUtils.isEmpty(musicTrack.getGenre()))
|
||||
value = musicTrack.getGenre();
|
||||
break;
|
||||
default:
|
||||
// Unknown tag
|
||||
Logger.getInstance().logWarning("MusicPathBuilder", "Unknown tag '" + name + "'");
|
||||
break;
|
||||
}
|
||||
|
||||
// Equal sign exists
|
||||
if (posEqual >= 0 && posEqual < posEnd && !TextUtils.isEmpty(value)) {
|
||||
String format = patter.substring(posEqual + 1, posEnd);
|
||||
|
||||
// Gets the insert sign
|
||||
int posInsertStart = format.indexOf('$');
|
||||
if (posInsertStart >= 0) {
|
||||
|
||||
int posInsertEnd = posInsertStart + 1;
|
||||
// Search the end
|
||||
while(posInsertEnd < format.length() && format.charAt(posInsertEnd) == '$') {
|
||||
posInsertEnd ++;
|
||||
}
|
||||
|
||||
// Fill Zeros
|
||||
while(value.length() < posInsertEnd - posInsertStart) {
|
||||
value = "0" + value;
|
||||
}
|
||||
|
||||
// Adds the rest of the format to the value
|
||||
value = format.substring(0, posInsertStart) + value + format.substring(posInsertEnd);
|
||||
|
||||
} else {
|
||||
// Missing insert sign
|
||||
Logger.getInstance().logWarning("MusicPathBuilder", "Cloud not find replace symbol ('$') of format attribute in tag '" + name + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// Adds the value
|
||||
path += cleanFilename(value);
|
||||
|
||||
pos = posEnd + 1;
|
||||
} else {
|
||||
path += "{";
|
||||
pos = posStart + 1;
|
||||
Logger.getInstance().logWarning("MusicPathBuilder", "Cloud not find end symbol ('}') of the tag in patter '" + patter + "'");
|
||||
}
|
||||
}
|
||||
|
||||
// Insert end
|
||||
path += patter.substring(pos, patter.length());
|
||||
|
||||
// Remove double slash
|
||||
while(path.contains("//"))
|
||||
path = path.replace("//", "/");
|
||||
|
||||
// Return path
|
||||
return path;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes forbidden chars in the filename
|
||||
* @param filename The filename
|
||||
* @return Returns the new clean filename
|
||||
*/
|
||||
public static String cleanFilename(String filename)
|
||||
{
|
||||
// Forbidden chars
|
||||
filename = filename.replace('\\', '-');
|
||||
filename = filename.replace(':', '-');
|
||||
filename = filename.replace('*', '-');
|
||||
filename = filename.replace('?', '-');
|
||||
filename = filename.replace('"', '-');
|
||||
filename = filename.replace('<', '-');
|
||||
filename = filename.replace('>', '-');
|
||||
filename = filename.replace('|', '-');
|
||||
|
||||
return filename;
|
||||
}
|
||||
}
|
BIN
playmusicexporter/src/main/res/drawable-hdpi/cd_overlay.png
Normal file
After Width: | Height: | Size: 829 B |
BIN
playmusicexporter/src/main/res/drawable-hdpi/drawer_shadow.9.png
Normal file
After Width: | Height: | Size: 161 B |
After Width: | Height: | Size: 807 B |
BIN
playmusicexporter/src/main/res/drawable-hdpi/ic_type_album.png
Normal file
After Width: | Height: | Size: 668 B |
BIN
playmusicexporter/src/main/res/drawable-hdpi/ic_type_artist.png
Normal file
After Width: | Height: | Size: 530 B |
After Width: | Height: | Size: 308 B |
BIN
playmusicexporter/src/main/res/drawable-hdpi/ic_type_rated.png
Normal file
After Width: | Height: | Size: 488 B |
BIN
playmusicexporter/src/main/res/drawable-mdpi/cd_overlay.png
Normal file
After Width: | Height: | Size: 620 B |
BIN
playmusicexporter/src/main/res/drawable-mdpi/drawer_shadow.9.png
Normal file
After Width: | Height: | Size: 142 B |
After Width: | Height: | Size: 550 B |
BIN
playmusicexporter/src/main/res/drawable-mdpi/ic_type_album.png
Normal file
After Width: | Height: | Size: 449 B |
BIN
playmusicexporter/src/main/res/drawable-mdpi/ic_type_artist.png
Normal file
After Width: | Height: | Size: 375 B |
After Width: | Height: | Size: 246 B |
BIN
playmusicexporter/src/main/res/drawable-mdpi/ic_type_rated.png
Normal file
After Width: | Height: | Size: 390 B |
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/button_navigation_drawer_hover">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/button_navigation_drawer_normal"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
|
@ -0,0 +1,31 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:color="@color/button_navigation_drawer_hover">
|
||||
<item>
|
||||
<shape android:shape="rectangle">
|
||||
<solid android:color="@color/button_navigation_drawer_selected"/>
|
||||
</shape>
|
||||
</item>
|
||||
</ripple>
|
BIN
playmusicexporter/src/main/res/drawable-xhdpi/cd_overlay.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 174 B |
After Width: | Height: | Size: 1.1 KiB |
BIN
playmusicexporter/src/main/res/drawable-xhdpi/ic_type_album.png
Normal file
After Width: | Height: | Size: 804 B |
BIN
playmusicexporter/src/main/res/drawable-xhdpi/ic_type_artist.png
Normal file
After Width: | Height: | Size: 662 B |
After Width: | Height: | Size: 337 B |
BIN
playmusicexporter/src/main/res/drawable-xhdpi/ic_type_rated.png
Normal file
After Width: | Height: | Size: 642 B |
BIN
playmusicexporter/src/main/res/drawable-xxhdpi/cd_overlay.png
Normal file
After Width: | Height: | Size: 1.6 KiB |
After Width: | Height: | Size: 208 B |
After Width: | Height: | Size: 1.6 KiB |
BIN
playmusicexporter/src/main/res/drawable-xxhdpi/ic_type_album.png
Normal file
After Width: | Height: | Size: 1.1 KiB |
After Width: | Height: | Size: 911 B |
After Width: | Height: | Size: 431 B |
BIN
playmusicexporter/src/main/res/drawable-xxhdpi/ic_type_rated.png
Normal file
After Width: | Height: | Size: 877 B |
|
@ -0,0 +1,40 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:drawable="@drawable/button_navigation_drawer_normal"
|
||||
android:state_selected="false"
|
||||
android:state_pressed="false"/>
|
||||
|
||||
<item android:drawable="@drawable/button_navigation_drawer_selected"
|
||||
android:state_selected="false"
|
||||
android:state_pressed="true"/>
|
||||
|
||||
<item android:drawable="@drawable/button_navigation_drawer_selected"
|
||||
android:state_selected="true"
|
||||
android:state_pressed="false"/>
|
||||
|
||||
<item android:drawable="@drawable/button_navigation_drawer_selected"
|
||||
android:state_selected="true"
|
||||
android:state_pressed="true"/>
|
||||
</selector>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/button_navigation_drawer_normal"/>
|
||||
</shape>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<solid android:color="@color/button_navigation_drawer_selected"/>
|
||||
</shape>
|
|
@ -20,8 +20,38 @@
|
|||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/track_list"
|
||||
android:name="de.arcus.playmusicexporter2.TrackListFragment" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" tools:context=".TrackListActivity"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
|
||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent"
|
||||
tools:context=".TrackListActivity">
|
||||
|
||||
|
||||
|
||||
<!-- As the main content view, the view below consumes the entire
|
||||
space available using match_parent in both dimensions. -->
|
||||
<fragment android:id="@+id/track_list"
|
||||
android:name="de.arcus.playmusicexporter2.fragments.MusicTrackListFragment"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
tools:context=".TrackListActivity"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
|
||||
<!-- android:layout_gravity="start" tells DrawerLayout to treat
|
||||
this as a sliding drawer on the left side for left-to-right
|
||||
languages and on the right side for right-to-left languages.
|
||||
If you're not building against API 17 or higher, use
|
||||
android:layout_gravity="left" instead. -->
|
||||
<!-- The drawer is given a fixed width in dp and extends the full height of
|
||||
the container. -->
|
||||
<fragment android:id="@+id/navigation_drawer"
|
||||
android:layout_width="@dimen/navigation_drawer_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:name="de.arcus.playmusicexporter2.fragments.NavigationDrawerFragment"
|
||||
tools:layout="@layout/fragment_navigation_drawer" />
|
||||
|
||||
|
||||
</android.support.v4.widget.DrawerLayout>
|
||||
|
||||
|
||||
|
|
|
@ -20,31 +20,51 @@
|
|||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="false"
|
||||
android:divider="?android:attr/dividerHorizontal" android:orientation="horizontal"
|
||||
android:showDividers="middle" tools:context=".TrackListActivity">
|
||||
|
||||
<!--
|
||||
This layout is a two-pane layout for the Tracks
|
||||
master/detail flow.
|
||||
See res/values-large/refs.xml and
|
||||
res/values-sw600dp/refs.xml for an example of layout aliases
|
||||
that replace the single-pane version of the layout with
|
||||
this two-pane version.
|
||||
<!-- A DrawerLayout is intended to be used as the top-level content view using match_parent for both width and height to consume the full space available. -->
|
||||
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/drawer_layout"
|
||||
android:layout_width="match_parent" android:layout_height="match_parent"
|
||||
tools:context=".TrackListActivity">
|
||||
|
||||
For more on layout aliases, see:
|
||||
http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
|
||||
-->
|
||||
<LinearLayout android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:baselineAligned="false"
|
||||
android:divider="?android:attr/dividerHorizontal" android:orientation="horizontal"
|
||||
android:showDividers="middle" tools:context=".TrackListActivity">
|
||||
|
||||
<fragment android:id="@+id/track_list"
|
||||
android:name="de.arcus.playmusicexporter2.TrackListFragment" android:layout_width="0dp"
|
||||
android:layout_height="match_parent" android:layout_weight="1.5"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
<!--
|
||||
This layout is a two-pane layout for the Tracks
|
||||
master/detail flow.
|
||||
See res/values-large/refs.xml and
|
||||
res/values-sw600dp/refs.xml for an example of layout aliases
|
||||
that replace the single-pane version of the layout with
|
||||
this two-pane version.
|
||||
|
||||
<FrameLayout android:id="@+id/track_detail_container" android:layout_width="0dp"
|
||||
android:layout_height="match_parent" android:layout_weight="3" />
|
||||
For more on layout aliases, see:
|
||||
http://developer.android.com/training/multiscreen/screensizes.html#TaskUseAliasFilters
|
||||
-->
|
||||
<fragment android:id="@+id/track_list"
|
||||
android:name="de.arcus.playmusicexporter2.fragments.MusicTrackListFragment" android:layout_width="0dp"
|
||||
android:layout_height="match_parent" android:layout_weight="1.5"
|
||||
tools:layout="@android:layout/list_content" />
|
||||
|
||||
</LinearLayout>
|
||||
<FrameLayout android:id="@+id/track_detail_container" android:layout_width="0dp"
|
||||
android:layout_height="match_parent" android:layout_weight="3" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<!-- android:layout_gravity="start" tells DrawerLayout to treat
|
||||
this as a sliding drawer on the left side for left-to-right
|
||||
languages and on the right side for right-to-left languages.
|
||||
If you're not building against API 17 or higher, use
|
||||
android:layout_gravity="left" instead. -->
|
||||
<!-- The drawer is given a fixed width in dp and extends the full height of
|
||||
the container. -->
|
||||
<fragment android:id="@+id/navigation_drawer"
|
||||
android:layout_width="@dimen/navigation_drawer_width"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_gravity="start"
|
||||
android:name="de.arcus.playmusicexporter2.fragments.NavigationDrawerFragment"
|
||||
tools:layout="@layout/fragment_navigation_drawer" />
|
||||
</android.support.v4.widget.DrawerLayout>
|
|
@ -24,29 +24,65 @@
|
|||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:gravity="center_vertical"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
android:gravity="center_vertical">
|
||||
|
||||
<TextView
|
||||
android:layout_width="64dp"
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text="1"
|
||||
android:id="@+id/text_music_track_number"
|
||||
android:gravity="center"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="20dp"
|
||||
android:textColor="@color/text_music_number" />
|
||||
android:id="@+id/relative_layout_left"
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="@dimen/music_track_artwork_size"
|
||||
android:layout_height="wrap_content"
|
||||
android:id="@+id/relative_layout_number"
|
||||
android:layout_centerVertical="true">
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text="1"
|
||||
android:id="@+id/text_music_track_number"
|
||||
android:gravity="center"
|
||||
android:textSize="16dp"
|
||||
android:textColor="@color/text_music_number" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="CD 1"
|
||||
android:id="@+id/text_music_track_disc_number"
|
||||
android:layout_below="@+id/text_music_track_number"
|
||||
android:gravity="center" />
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="@dimen/music_track_artwork_size"
|
||||
android:layout_height="@dimen/music_track_artwork_size"
|
||||
android:id="@+id/relative_layout_artwork"
|
||||
android:layout_marginRight="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/music_track_artwork_size"
|
||||
android:layout_height="@dimen/music_track_artwork_size"
|
||||
android:id="@+id/image_music_track_artwork"
|
||||
android:scaleType="centerCrop" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_toRightOf="@+id/text_music_track_number"
|
||||
android:layout_toEndOf="@+id/text_music_track_number"
|
||||
android:paddingLeft="8dp"
|
||||
android:layout_toEndOf="@+id/relative_layout_left"
|
||||
android:paddingRight="8dp"
|
||||
android:id="@+id/relativeLayout">
|
||||
android:id="@+id/relative_layout_title"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_toRightOf="@+id/relative_layout_left"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -30,10 +30,15 @@
|
|||
android:layout_width="@dimen/music_track_list_artwork_size"
|
||||
android:layout_height="@dimen/music_track_list_artwork_size"
|
||||
android:id="@+id/image_music_track_artwork"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:scaleType="centerCrop" />
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/cd_case" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/music_track_list_artwork_size"
|
||||
android:layout_height="@dimen/music_track_list_artwork_size"
|
||||
android:id="@+id/image_music_track_artwork_overlay"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/cd_overlay" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
|
|
|
@ -0,0 +1,78 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:clickable="true"
|
||||
android:background="@color/navigation_drawer_background">
|
||||
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/ic_type_album"
|
||||
android:drawableStart="@drawable/ic_type_album"
|
||||
android:text="@string/title_view_album"
|
||||
android:id="@+id/button_type_album"
|
||||
style="@style/AppTheme.Button" />
|
||||
|
||||
<Button
|
||||
style="@style/AppTheme.Button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/ic_type_artist"
|
||||
android:drawableStart="@drawable/ic_type_artist"
|
||||
android:text="@string/title_view_artist"
|
||||
android:id="@+id/button_type_artist" />
|
||||
|
||||
<Button
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/ic_type_playlist"
|
||||
android:drawableStart="@drawable/ic_type_playlist"
|
||||
android:text="@string/title_view_playlist"
|
||||
android:id="@+id/button_type_playlist"
|
||||
style="@style/AppTheme.Button" />
|
||||
|
||||
<Button
|
||||
style="@style/AppTheme.Button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:drawableLeft="@drawable/ic_type_rated"
|
||||
android:drawableStart="@drawable/ic_type_rated"
|
||||
android:text="@string/title_view_rated"
|
||||
android:id="@+id/button_type_rated" />
|
||||
|
||||
<Button
|
||||
style="@style/AppTheme.Button"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="20dp"
|
||||
android:drawableLeft="@drawable/ic_action_settings"
|
||||
android:drawableStart="@drawable/ic_action_settings"
|
||||
android:text="@string/title_settings"
|
||||
android:id="@+id/button_setting" />
|
||||
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/music_track_list_header_artwork_size"
|
||||
android:id="@+id/relative_layout_header">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/music_track_list_header_artwork_size"
|
||||
android:layout_height="@dimen/music_track_list_header_artwork_size"
|
||||
android:id="@+id/image_music_track_artwork"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/cd_case" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="@dimen/music_track_list_header_artwork_size"
|
||||
android:layout_height="@dimen/music_track_list_header_artwork_size"
|
||||
android:id="@+id/image_music_track_artwork_overlay"
|
||||
android:scaleType="centerCrop"
|
||||
android:src="@drawable/cd_overlay" />
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:layout_toRightOf="@+id/image_music_track_artwork"
|
||||
android:layout_toEndOf="@+id/image_music_track_artwork"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:layout_marginBottom="16dp">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text="Large Text"
|
||||
android:id="@+id/text_music_track_list_title"
|
||||
android:layout_alignParentTop="true"
|
||||
android:layout_alignParentRight="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:maxLines="2" />
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium"
|
||||
android:text="Medium Text"
|
||||
android:id="@+id/text_music_track_list_description"
|
||||
android:layout_below="@+id/text_music_track_list_title"
|
||||
android:layout_alignParentLeft="true"
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignRight="@+id/text_music_track_list_title"
|
||||
android:layout_alignEnd="@+id/text_music_track_list_title"
|
||||
android:maxLines="2" />
|
||||
</RelativeLayout>
|
||||
</RelativeLayout>
|
35
playmusicexporter/src/main/res/values-de/strings.xml
Normal file
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ Copyright (c) 2015 David Schulte
|
||||
~
|
||||
~ Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
~ of this software and associated documentation files (the "Software"), to deal
|
||||
~ in the Software without restriction, including without limitation the rights
|
||||
~ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
~ copies of the Software, and to permit persons to whom the Software is
|
||||
~ furnished to do so, subject to the following conditions:
|
||||
~
|
||||
~ The above copyright notice and this permission notice shall be included in
|
||||
~ all copies or substantial portions of the Software.
|
||||
~
|
||||
~ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
~ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
~ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
~ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
~ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
~ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
~ THE SOFTWARE.
|
||||
-->
|
||||
|
||||
<resources>
|
||||
<string name="app_name">Play Music Exporter</string>
|
||||
<string name="navigation_drawer_close">Drawer schließen</string>
|
||||
<string name="view_type_selection_title">Ansicht</string>
|
||||
<string name="title_view_rated">Positiv bewertet</string>
|
||||
<string name="title_view_playlist">Playlists</string>
|
||||
<string name="title_view_artist">Interpreten</string>
|
||||
<string name="title_view_album">Alben</string>
|
||||
<string name="navigation_drawer_open">Drawer öffnen</string>
|
||||
<string name="title_track_detail">Titeldetails</string>
|
||||
<string name="title_settings">Einstellungen</string>
|
||||
</resources>
|
|
@ -26,10 +26,22 @@
|
|||
<color name="application_main_dark">#e65100</color>
|
||||
|
||||
<color name="text_music_number">#ff000000</color>
|
||||
<color name="text_music_disc_number">#88000000</color>
|
||||
<color name="text_music_title">#ff000000</color>
|
||||
<color name="text_music_description">#88000000</color>
|
||||
|
||||
<color name="text_music_disable_number">#44000000</color>
|
||||
<color name="text_music_disable_disc_number">#22000000</color>
|
||||
<color name="text_music_disable_title">#44000000</color>
|
||||
<color name="text_music_disable_description">#22000000</color>
|
||||
|
||||
<color name="navigation_drawer_background">#f5f5f5</color>
|
||||
|
||||
|
||||
<color name="button_navigation_drawer_normal">#00000000</color>
|
||||
<color name="button_navigation_drawer_selected">#11000000</color>
|
||||
<color name="button_navigation_drawer_hover">#808080</color>
|
||||
<color name="button_navigation_drawer_active">#11000000</color>
|
||||
<color name="button_navigation_drawer_text">#88000000</color>
|
||||
<color name="button_navigation_drawer_text_active">#ef6c00</color>
|
||||
</resources>
|
|
@ -23,4 +23,8 @@
|
|||
|
||||
<resources>
|
||||
<dimen name="music_track_list_artwork_size">86dp</dimen>
|
||||
<dimen name="music_track_list_header_artwork_size">128dp</dimen>
|
||||
<dimen name="music_track_artwork_size">86dp</dimen>
|
||||
|
||||
<dimen name="navigation_drawer_width">280dp</dimen>
|
||||
</resources>
|
|
@ -26,4 +26,14 @@
|
|||
<string name="app_name">Play Music Exporter</string>
|
||||
<string name="title_track_detail">Track Detail</string>
|
||||
|
||||
<string name="navigation_drawer_open">Open drawer</string>
|
||||
<string name="navigation_drawer_close">Close drawer</string>
|
||||
|
||||
<string name="view_type_selection_title">View</string>
|
||||
<string name="title_view_album">Albums</string>
|
||||
<string name="title_view_artist">Artists</string>
|
||||
<string name="title_view_playlist">Playlists</string>
|
||||
<string name="title_view_rated">Good rated</string>
|
||||
|
||||
<string name="title_settings">Settings</string>
|
||||
</resources>
|
||||
|
|
|
@ -27,5 +27,24 @@
|
|||
<!-- Customize your theme here. -->
|
||||
<item name="colorPrimary">@color/application_main</item>
|
||||
<item name="colorPrimaryDark">@color/application_main_dark</item>
|
||||
<item name="actionBarStyle">@style/AppTheme.ActionBar</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.ActionBar" parent="Widget.AppCompat.Light.ActionBar.Solid.Inverse">
|
||||
<!-- Removes the shadow from the action bar -->
|
||||
<item name="elevation">0dp</item>
|
||||
</style>
|
||||
|
||||
<style name="AppTheme.Button">
|
||||
<item name="android:background">@drawable/button_navigation_drawer</item>
|
||||
<item name="android:buttonStyle">@null</item>
|
||||
<item name="android:textColor">@color/button_navigation_drawer_text</item>
|
||||
<item name="android:paddingTop">5dp</item>
|
||||
<item name="android:paddingBottom">5dp</item>
|
||||
<item name="android:paddingLeft">10dp</item>
|
||||
<item name="android:paddingRight">10dp</item>
|
||||
<item name="android:textSize">16sp</item>
|
||||
<item name="android:drawablePadding">10dp</item>
|
||||
<item name="android:gravity">start|center_vertical</item>
|
||||
</style>
|
||||
</resources>
|
||||
|
|
|
@ -38,6 +38,7 @@ import com.mpatric.mp3agic.ID3v23Tag;
|
|||
import com.mpatric.mp3agic.ID3v24Tag;
|
||||
import com.mpatric.mp3agic.Mp3File;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
@ -437,6 +438,11 @@ public class PlayMusicManager {
|
|||
}
|
||||
}
|
||||
|
||||
// Creates the destination directory
|
||||
String directory = new File(dest).getParent();
|
||||
if (directory != null && !FileTools.directoryExists(directory))
|
||||
FileTools.directoryCreate(directory);
|
||||
|
||||
// We want to export the ID3 tags
|
||||
if (mID3Enable) {
|
||||
// Adds the meta data
|
||||
|
@ -536,11 +542,13 @@ public class PlayMusicManager {
|
|||
tagID3v2.setPartOfSet("" + musicTrack.getDiscNumber());
|
||||
tagID3v2.setYear(musicTrack.getYear());
|
||||
|
||||
try {
|
||||
// Maybe the genre is not supported
|
||||
tagID3v2.setGenreDescription(musicTrack.getGenre());
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logger.getInstance().logWarning("TrackWriteID3", e.getMessage());
|
||||
if (!TextUtils.isEmpty(musicTrack.getGenre())) {
|
||||
try {
|
||||
// Maybe the genre is not supported
|
||||
tagID3v2.setGenreDescription(musicTrack.getGenre());
|
||||
} catch (IllegalArgumentException e) {
|
||||
Logger.getInstance().logWarning("TrackWriteID3", e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
// Add the artwork to the meta data
|
||||
|
|
|
@ -62,6 +62,11 @@ public class AlbumDataSource extends DataSource<Album> {
|
|||
*/
|
||||
private String mSearchKey;
|
||||
|
||||
/**
|
||||
* If this is set the data source will only load tracks which are positive rated
|
||||
*/
|
||||
private boolean mRatedOnly;
|
||||
|
||||
/**
|
||||
* @return Returns whether the data source should only load offline tracks
|
||||
*/
|
||||
|
@ -90,6 +95,20 @@ public class AlbumDataSource extends DataSource<Album> {
|
|||
mSearchKey = searchKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Returns whether the data source should only load positive rated tracks
|
||||
*/
|
||||
public boolean getRatedOnly() {
|
||||
return mRatedOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param ratedOnly Sets whether the data source should only load positive rated tracks
|
||||
*/
|
||||
public void setRatedOnly(boolean ratedOnly) {
|
||||
mRatedOnly = ratedOnly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new data source
|
||||
* @param playMusicManager The manager
|
||||
|
@ -114,6 +133,10 @@ public class AlbumDataSource extends DataSource<Album> {
|
|||
if (mOfflineOnly)
|
||||
where = combineWhere(where, "LocalCopyPath IS NOT NULL");
|
||||
|
||||
// Loads only positive rated tracks
|
||||
if (mRatedOnly)
|
||||
where = combineWhere(where, "Rating > 0");
|
||||
|
||||
// Search only items which contains the key
|
||||
if (!TextUtils.isEmpty(mSearchKey)) {
|
||||
String searchKey = DatabaseUtils.sqlEscapeString("%" + mSearchKey + "%");
|
||||
|
|
|
@ -100,7 +100,7 @@ public abstract class DataSource<T> {
|
|||
*/
|
||||
protected List<T> getItems(String table, String[] columns, String where, String orderBy, String groupBy) {
|
||||
// No connection; abort
|
||||
if (!mPlayMusicManager.getDatabase().isOpen()) return null;
|
||||
if (mPlayMusicManager.getDatabase() == null || !mPlayMusicManager.getDatabase().isOpen()) return null;
|
||||
|
||||
// Creates the list
|
||||
List<T> items = new LinkedList<>();
|
||||
|
|
|
@ -58,6 +58,7 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
private final static String COLUMN_TRACK_NUMBER = "MUSIC.TrackNumber";
|
||||
private final static String COLUMN_DISC_NUMBER = "MUSIC.DiscNumber";
|
||||
private final static String COLUMN_DURATION = "MUSIC.Duration";
|
||||
private final static String COLUMN_RATING = "MUSIC.Rating";
|
||||
private final static String COLUMN_ALBUM_ID = "MUSIC.AlbumId";
|
||||
private final static String COLUMN_CLIENT_ID = "MUSIC.ClientId";
|
||||
private final static String COLUMN_SOURCE_ID = "MUSIC.SourceId";
|
||||
|
@ -67,7 +68,7 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
// All columns
|
||||
private final static String[] COLUMNS_ALL = { COLUMN_ID, COLUMN_SIZE,
|
||||
COLUMN_LOCALCOPYPATH, COLUMN_LOCALCOPYTYPE, COLUMN_LOCALCOPYSTORAGETYPE, COLUMN_TITLE, COLUMN_ARTIST_ID, COLUMN_ARTIST, COLUMN_ALBUM_ARTIST,
|
||||
COLUMN_ALBUM, COLUMN_GENRE, COLUMN_YEAR, COLUMN_TRACK_NUMBER, COLUMN_DISC_NUMBER, COLUMN_DURATION,
|
||||
COLUMN_ALBUM, COLUMN_GENRE, COLUMN_YEAR, COLUMN_TRACK_NUMBER, COLUMN_DISC_NUMBER, COLUMN_DURATION, COLUMN_RATING,
|
||||
COLUMN_ALBUM_ID, COLUMN_CLIENT_ID, COLUMN_SOURCE_ID, COLUMN_ARTWORK_FILE, COLUMN_CPDATA };
|
||||
|
||||
/**
|
||||
|
@ -183,6 +184,7 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
instance.setTrackNumber(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_TRACK_NUMBER)));
|
||||
instance.setDiscNumber(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_DISC_NUMBER)));
|
||||
instance.setDuration(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_DURATION)));
|
||||
instance.setRating(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_RATING)));
|
||||
instance.setAlbumId(cursor.getLong(getColumnsIndex(COLUMNS_ALL, COLUMN_ALBUM_ID)));
|
||||
instance.setClientId(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_CLIENT_ID)));
|
||||
instance.setSourceId(cursor.getString(getColumnsIndex(COLUMNS_ALL, COLUMN_SOURCE_ID)));
|
||||
|
|
|
@ -31,7 +31,7 @@ import de.arcus.playmusiclib.PlayMusicManager;
|
|||
*/
|
||||
public class MusicTrack {
|
||||
// Variables
|
||||
private long mId, mSize, mTrackNumber, mDiscNumber, mAlbumId, mArtistId, mLocalCopyType, mLocalCopyStorageType, mDuration;
|
||||
private long mId, mSize, mTrackNumber, mDiscNumber, mAlbumId, mArtistId, mLocalCopyType, mLocalCopyStorageType, mDuration, mRating;
|
||||
private String mTitle, mArtist, mAlbum, mAlbumArtist, mLocalCopyPath, mGenre, mYear, mClientId, mSourceId, mArtworkFile;
|
||||
private byte[] mCpData;
|
||||
|
||||
|
@ -121,6 +121,20 @@ public class MusicTrack {
|
|||
this.mDuration = duration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the rating of the track
|
||||
*/
|
||||
public long getRating() {
|
||||
return mRating;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param rating Sets the rating of the track
|
||||
*/
|
||||
public void setRating(long rating) {
|
||||
this.mRating = rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Gets the local copy type
|
||||
*/
|
||||
|
|