Add a track list to the main app when selecting an album

Add deserializer from id and type to the MusicTrackList
Add a ImageLoader to load artworks to ImageViews
This commit is contained in:
David Schulte 2015-01-27 23:08:24 +01:00
parent ed4446e48e
commit b6194613a5
21 changed files with 675 additions and 122 deletions

View file

@ -57,6 +57,10 @@ public class SuperUserCommand {
*/
private boolean mSuperUserFailed;
/**
* If this value is set, the command will not store any input to the logger
*/
private boolean mHideInput = false;
/**
* If this value is set, the command will not store any standard output to the logger
*/
@ -66,6 +70,20 @@ public class SuperUserCommand {
*/
private boolean mHideErrorOutput = false;
/**
* @return Gets whether the command hides the input log
*/
public boolean getHideInput() {
return mHideInput;
}
/**
* @param hideInput Set this to hide the input to the logger
*/
public void setHideInput(boolean hideInput) {
mHideInput = hideInput;
}
/**
* @return Gets whether the command hides the standard output log
*/
@ -266,7 +284,8 @@ public class SuperUserCommand {
// Sends the command
for (String command : mCommands) {
Logger.getInstance().logInfo("SuperUser", "< " + command);
if (!mHideInput) // Check if we want to hide this
Logger.getInstance().logInfo("SuperUser", "< " + command);
dataOutputStream.writeBytes(command + "\n");
}
dataOutputStream.flush();

View file

@ -83,6 +83,7 @@ public class SuperUserTools {
SuperUserCommand superUserCommand = new SuperUserCommand("cat '" + path + "'");
// Don't spam the log with binary code
superUserCommand.setHideInput(true);
superUserCommand.setHideStandardOutput(true);
superUserCommand.setBinaryStandardOutput(true);
@ -105,6 +106,7 @@ public class SuperUserTools {
SuperUserCommand superUserCommand = new SuperUserCommand("cat '" + path + "'");
// Don't spam the log with binary code
superUserCommand.setHideInput(true);
superUserCommand.setHideStandardOutput(true);
superUserCommand.setBinaryStandardOutput(true);

View file

@ -61,8 +61,13 @@ public class TrackDetailActivity extends ActionBarActivity {
// Create the detail fragment and add it to the activity
// using a fragment transaction.
Bundle arguments = new Bundle();
arguments.putString(TrackDetailFragment.ARG_MUSIC_TRACK_LIST,
getIntent().getStringExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST));
arguments.putLong(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID,
getIntent().getLongExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, 0));
arguments.putString(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE,
getIntent().getStringExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE));
TrackDetailFragment fragment = new TrackDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()

View file

@ -27,8 +27,12 @@ import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ListView;
import android.widget.TextView;
import de.arcus.playmusicexporter2.adapter.MusicTrackAdapter;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.items.MusicTrackList;
@ -43,15 +47,14 @@ public class TrackDetailFragment extends Fragment {
* The fragment argument representing the item ID that this fragment
* represents.
*/
public static final String ARG_MUSIC_TRACK_LIST = "music_track_list";
public static final String ARG_MUSIC_TRACK_LIST_ID = "music_track_list_id";
public static final String ARG_MUSIC_TRACK_LIST_TYPE = "music_track_list_type";
/**
* The track list
*/
private MusicTrackList mMusicTrackList;
private String mTest;
/**
* Mandatory empty constructor for the fragment manager to instantiate the
* fragment (e.g. upon screen orientation changes).
@ -63,12 +66,18 @@ public class TrackDetailFragment extends Fragment {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if (getArguments().containsKey(ARG_MUSIC_TRACK_LIST)) {
// Load the dummy content specified by the fragment
// arguments. In a real-world scenario, use a Loader
// to load content from a content provider.
// mMusicTrackList = (MusicTrackList)getArguments().getSerializable(ARG_MUSIC_TRACK_LIST);
mTest = getArguments().getString(ARG_MUSIC_TRACK_LIST);
if (getArguments().containsKey(ARG_MUSIC_TRACK_LIST_ID)
&& getArguments().containsKey(ARG_MUSIC_TRACK_LIST_TYPE)) {
// Loads the track list
long id = getArguments().getLong(ARG_MUSIC_TRACK_LIST_ID);
String type = getArguments().getString(ARG_MUSIC_TRACK_LIST_TYPE);
PlayMusicManager playMusicManager = PlayMusicManager.getInstance();
if (playMusicManager != null) {
mMusicTrackList = MusicTrackList.deserialize(playMusicManager, id, type);
}
}
}
@ -78,8 +87,14 @@ public class TrackDetailFragment extends Fragment {
View rootView = inflater.inflate(R.layout.fragment_track_detail, container, false);
// Show the dummy content as text in a TextView.
if (mTest != null) {
((TextView) rootView.findViewById(R.id.track_detail)).setText(mTest);
if (mMusicTrackList != null) {
ListView listView = (ListView)rootView.findViewById(R.id.list_music_track);
MusicTrackAdapter musicTrackAdapter = new MusicTrackAdapter(getActivity());
musicTrackAdapter.setList(mMusicTrackList.getMusicTrackList());
listView.setAdapter(musicTrackAdapter);
}
return rootView;

View file

@ -32,6 +32,7 @@ import de.arcus.framework.crashhandler.CrashHandler;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.datasources.AlbumDataSource;
import de.arcus.playmusiclib.enums.ID3v2Version;
import de.arcus.playmusiclib.items.MusicTrackList;
/**
* An activity representing a list of Tracks. This activity
@ -88,30 +89,36 @@ public class TrackListActivity extends ActionBarActivity
.setActivateOnItemClick(true);
}
// Gets the running instance
PlayMusicManager playMusicManager = PlayMusicManager.getInstance();
PlayMusicManager playMusicManager = new PlayMusicManager(this);
// Create a new instance
if (playMusicManager == null) {
playMusicManager = new PlayMusicManager(this);
try {
// Simple play ground
playMusicManager.startUp();
playMusicManager.setOfflineOnly(true);
try {
// Simple play ground
playMusicManager.startUp();
playMusicManager.setOfflineOnly(true);
// Setup ID3
playMusicManager.setID3Enable(true);
playMusicManager.setID3EnableArtwork(true);
playMusicManager.setID3EnableFallback(true);
playMusicManager.setID3v2Version(ID3v2Version.ID3v23);
playMusicManager.setID3Enable(true);
playMusicManager.setID3EnableArtwork(true);
playMusicManager.setID3EnableFallback(true);
playMusicManager.setID3v2Version(ID3v2Version.ID3v23);
playMusicManager.copyDatabaseToSdCard();
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
((TrackListFragment) getSupportFragmentManager()
.findFragmentById(R.id.track_list)).setList(albumDataSource.getAll());
} catch (Exception e) {
Logger.getInstance().logError("Test", e.toString());
} catch (Exception e) {
Logger.getInstance().logError("Test", e.toString());
}
}
// Load all albums to the list
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
((TrackListFragment) getSupportFragmentManager()
.findFragmentById(R.id.track_list)).setMusicTrackList(albumDataSource.getAll());
}
/**
@ -119,13 +126,14 @@ public class TrackListActivity extends ActionBarActivity
* indicating that the item with the given ID was selected.
*/
@Override
public void onItemSelected(String id) {
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.putString(TrackDetailFragment.ARG_MUSIC_TRACK_LIST, id);
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()
@ -136,7 +144,8 @@ public class TrackListActivity extends ActionBarActivity
// 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);
detailIntent.putExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_ID, musicTrackList.getMusicTrackListID());
detailIntent.putExtra(TrackDetailFragment.ARG_MUSIC_TRACK_LIST_TYPE, musicTrackList.getMusicTrackListType());
startActivity(detailIntent);
}
}

View file

@ -72,7 +72,7 @@ public class TrackListFragment extends ListFragment {
/**
* Callback for when an item has been selected.
*/
public void onItemSelected(String id);
public void onItemSelected(MusicTrackList musicTrackList);
}
/**
@ -81,7 +81,7 @@ public class TrackListFragment extends ListFragment {
*/
private static Callbacks sDummyCallbacks = new Callbacks() {
@Override
public void onItemSelected(String id) {
public void onItemSelected(MusicTrackList musicTrackList) {
}
};
@ -97,7 +97,7 @@ public class TrackListFragment extends ListFragment {
/**
* @param list Set the list
*/
public void setList(List<? extends MusicTrackList> list) {
public void setMusicTrackList(List<? extends MusicTrackList> list) {
// Create a new list
List<MusicTrackList> newList = new ArrayList<>();
@ -157,7 +157,7 @@ public class TrackListFragment extends ListFragment {
// Notify the active callbacks interface (the activity, if the
// fragment is attached to one) that an item has been selected.
mCallbacks.onItemSelected(mMusicTrackListAdapter.getList().get(position).getTitle());
mCallbacks.onItemSelected(mMusicTrackListAdapter.getList().get(position));
}
@Override

View file

@ -0,0 +1,168 @@
/*
* 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.adapter;
import android.content.Context;
import android.database.DataSetObserver;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ListAdapter;
import android.widget.TextView;
import java.util.List;
import de.arcus.playmusicexporter2.R;
import de.arcus.playmusiclib.items.MusicTrack;
/**
* Adapter for the music tracks
*/
public class MusicTrackAdapter implements ListAdapter {
/**
* The context of the app
*/
private Context mContext;
/**
* The list
*/
private List<MusicTrack> mList;
/**
* @param list Sets a new list
*/
public void setList(List<MusicTrack> list) {
mList = list;
}
/**
* @return Gets the list
*/
public List<MusicTrack> getList() {
return mList;
}
/**
* Create a new track adapter
* @param context The app context
*/
public MusicTrackAdapter(Context context) {
mContext = context;
}
@Override
public boolean areAllItemsEnabled() {
return false;
}
@Override
public boolean isEnabled(int position) {
return false;
}
@Override
public void registerDataSetObserver(DataSetObserver observer) {
}
@Override
public void unregisterDataSetObserver(DataSetObserver observer) {
}
@Override
public int getCount() {
if (mList == null) return 0;
return mList.size();
}
@Override
public Object getItem(int position) {
return mList.get(position);
}
@Override
public long getItemId(int position) {
// We don't have ids
return 0;
}
@Override
public boolean hasStableIds() {
// We don't have ids
return false;
}
@Override
public View getView(int position, View convertView, ViewGroup parent) {
// The track
MusicTrack musicTrack = mList.get(position);
View view = convertView;
// Inflates a view
if (view == null) {
LayoutInflater inflater = (LayoutInflater) mContext.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
view = inflater.inflate(R.layout.adapter_music_track, parent, false);
}
TextView textView;
// Set the track number
textView = (TextView)view.findViewById(R.id.text_music_track_number);
if (musicTrack.getTrackNumber() > 0)
textView.setText("" + musicTrack.getTrackNumber());
else
textView.setText("");
// Set the title
textView = (TextView)view.findViewById(R.id.text_music_track_title);
textView.setText(musicTrack.getTitle());
// Set the artist
textView = (TextView)view.findViewById(R.id.text_music_track_artist);
textView.setText(musicTrack.getArtist());
view.setEnabled(musicTrack.isOfflineAvailable());
return view;
}
@Override
public int getItemViewType(int position) {
// We don't have view types
return 0;
}
@Override
public int getViewTypeCount() {
// We don't have view types
return 1;
}
@Override
public boolean isEmpty() {
return (mList == null || mList.isEmpty());
}
}

View file

@ -24,8 +24,6 @@ package de.arcus.playmusicexporter2.adapter;
import android.content.Context;
import android.database.DataSetObserver;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
@ -35,10 +33,8 @@ import android.widget.TextView;
import java.util.List;
import de.arcus.framework.superuser.SuperUserCommand;
import de.arcus.framework.superuser.SuperUserCommandCallback;
import de.arcus.framework.superuser.SuperUserTools;
import de.arcus.playmusicexporter2.R;
import de.arcus.playmusicexporter2.utils.ImageViewLoader;
import de.arcus.playmusiclib.items.MusicTrackList;
/**
@ -124,6 +120,7 @@ public class MusicTrackListAdapter implements ListAdapter {
}
TextView textView;
ImageView imageView;
// Set the title
textView = (TextView)view.findViewById(R.id.text_music_track_list_title);
@ -134,47 +131,16 @@ public class MusicTrackListAdapter implements ListAdapter {
textView.setText(musicTrackList.getDescription());
// Final for the callback
final ImageView imageViewArtwork = (ImageView)view.findViewById(R.id.image_music_track_artwork);
imageView = (ImageView)view.findViewById(R.id.image_music_track_artwork);
// Default icon
imageViewArtwork.setImageResource(R.drawable.cd_case);
imageView.setImageResource(R.drawable.cd_case);
// Gets the artwork
String artworkPath = musicTrackList.getArtworkPath();
if (artworkPath != null) {
// Be careful! Don't scroll to fast! This will spam the superuser to do list!
SuperUserTools.fileReadToByteArrayAsync(artworkPath, new SuperUserCommandCallback() {
@Override
public void onFinished(SuperUserCommand command) {
// Success
if (command.commandWasSuccessful()) {
// Binary data
byte[] bitmapData = command.getStandardOutputBinary();
// Load the bitmap
try {
final Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length);
// The the bitmap in the UI thread
Runnable runnable = new Runnable() {
@Override
public void run() {
imageViewArtwork.setImageBitmap(bitmap);
}
};
imageViewArtwork.post(runnable);
} catch (Exception e) {
e.printStackTrace();
}
} else {
// File not found
imageViewArtwork.setImageResource(R.drawable.cd_case);
}
}
});
ImageViewLoader.loadImage(imageView, artworkPath);
}

View file

@ -0,0 +1,177 @@
/*
* 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.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.widget.ImageView;
import java.lang.ref.WeakReference;
import de.arcus.framework.superuser.SuperUserCommand;
import de.arcus.framework.superuser.SuperUserCommandCallback;
import de.arcus.framework.superuser.SuperUserTools;
import de.arcus.playmusicexporter2.R;
/**
* Class to load Artworks
*/
public class ImageViewLoader {
/**
* A weak reference to the image view
*/
private WeakReference<ImageView> mImageView;
/**
* Is the artwork loaded?
*/
private boolean mIsLoading = false;
/**
* @return Gets whether the loader is loading an artwork
*/
public boolean isLoading() {
return mIsLoading;
}
/**
* Path of the image
*/
private String mImagePath;
/**
* Path of the new image which will be loaded after the current loading is completed
*/
private String mNewImagePath;
/**
* @return Gets the path of the image we want to load
*/
public String getImagePath() {
return mImagePath;
}
public static void loadImage(ImageView imageView, String path) {
// Checks for an old artwork loader on this image view
ImageViewLoader imageViewLoader = (ImageViewLoader)imageView.getTag();
if (imageViewLoader == null) {
imageViewLoader = new ImageViewLoader(imageView, path);
// Save the loader in the tag
// If someone wants to load another artwork to this view
imageView.setTag(imageViewLoader);
imageViewLoader.loadImage();
} else {
// Updates the old loader
imageViewLoader.updateImage(path);
}
}
/**
* Loads a image to an image view
* @param imageView The image view we want to set
* @param path The path to load
*/
private ImageViewLoader(ImageView imageView, String path) {
mImageView = new WeakReference<>(imageView);
mImagePath = path;
}
/**
* Loads the image asynchronously
*/
private void loadImage() {
mIsLoading = true;
// Be careful! Don't scroll to fast! This will spam the superuser to do list!
SuperUserTools.fileReadToByteArrayAsync(mImagePath, new SuperUserCommandCallback() {
@Override
public void onFinished(SuperUserCommand command) {
final ImageView imageView = mImageView.get();
if (imageView != null) {
// Success
if (command.commandWasSuccessful()) {
// Binary data
byte[] bitmapData = command.getStandardOutputBinary();
// Loads the bitmap
try {
// We already want to load a new image, so we don't need to set this
if (mNewImagePath == null) {
// Loads the bitmap
final Bitmap bitmap = BitmapFactory.decodeByteArray(bitmapData, 0, bitmapData.length);
// The the bitmap in the UI thread
Runnable runnable = new Runnable() {
@Override
public void run() {
imageView.setImageBitmap(bitmap);
}
};
imageView.post(runnable);
}
} catch (Exception e) {
e.printStackTrace();
}
} else {
// File not found
imageView.setImageResource(R.drawable.cd_case);
}
}
mIsLoading = false;
// Loads the next image
if (mNewImagePath != null) {
mImagePath = mNewImagePath;
mNewImagePath = null;
loadImage();
}
}
});
}
/**
* Loads a new artwork
* @param path New artwork path
*/
private void updateImage(String path) {
// The same artwork; nothing to do
if (path.equals(mImagePath)) return;
if (mIsLoading) {
mNewImagePath = path;
} else {
mImagePath = path;
loadImage();
}
}
}

View file

@ -0,0 +1,65 @@
<?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="wrap_content"
android:gravity="center_vertical"
android:paddingTop="16dp"
android:paddingBottom="16dp">
<TextView
android:layout_width="64dp"
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" />
<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:paddingRight="8dp"
android:id="@+id/relativeLayout">
<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_title"
android:layout_alignParentTop="true" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="@+id/text_music_track_artist"
android:layout_below="@+id/text_music_track_title" />
</RelativeLayout>
</RelativeLayout>

View file

@ -25,42 +25,61 @@
android:orientation="vertical" android:layout_width="match_parent"
android:layout_height="match_parent">
<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:paddingLeft="8dp"
android:paddingTop="16dp"
android:paddingRight="16dp"
android:layout_toRightOf="@+id/image_music_track_artwork"
android:layout_toEndOf="@+id/image_music_track_artwork" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="@+id/text_music_track_list_description"
android:layout_below="@+id/text_music_track_list_title"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:paddingTop="0dp"
android:paddingLeft="8dp"
android:paddingRight="16dp"
android:paddingBottom="16dp"
android:layout_toRightOf="@+id/image_music_track_artwork"
android:layout_toEndOf="@+id/image_music_track_artwork" />
<ImageView
android:layout_width="96dp"
android:layout_height="96dp"
android:id="@+id/image_music_track_artwork"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true" />
android:layout_alignParentStart="true"
android:scaleType="centerCrop" />
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="96dp"
android:layout_alignParentTop="true"
android:layout_toRightOf="@+id/image_music_track_artwork"
android:layout_toEndOf="@+id/image_music_track_artwork"
android:gravity="center_vertical">
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:layout_alignParentTop="false"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:layout_alignParentBottom="false"
android:paddingLeft="16dp"
android:paddingTop="8dp"
android:paddingRight="8dp"
android:paddingBottom="8dp">
<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"
android:textSize="16dp" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAppearance="?android:attr/textAppearanceSmall"
android:text="Small Text"
android:id="@+id/text_music_track_list_description"
android:layout_below="@+id/text_music_track_list_title"
android:layout_alignParentRight="true"
android:layout_alignParentEnd="true"
android:layout_alignParentLeft="true"
android:layout_alignParentStart="true"
android:maxLines="2" />
</RelativeLayout>
</RelativeLayout>
</RelativeLayout>

View file

@ -20,8 +20,8 @@
~ THE SOFTWARE.
-->
<TextView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/track_detail"
style="?android:attr/textAppearanceLarge" android:layout_width="match_parent"
android:layout_height="match_parent" android:padding="16dp" android:textIsSelectable="true"
<ListView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:id="@+id/list_music_track"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".TrackDetailFragment" />

View file

@ -62,6 +62,18 @@ public class PlayMusicManager {
*/
public static final String PLAYMUSIC_PACKAGE_ID = "com.google.android.music";
/**
* The last created instance
*/
private static PlayMusicManager instance;
/**
* @return Gets the last created instance or returns null if there is no instance
*/
public static PlayMusicManager getInstance() {
return instance;
}
/**
* Context of the app, needed to access to the package manager
*/
@ -227,14 +239,15 @@ public class PlayMusicManager {
*/
public PlayMusicManager(Context context) {
mContext = context;
instance = this;
}
/**
* Loads all needed information and opens the database
* @throws de.arcus.playmusiclib.exceptions.PlayMusicNotFoundException PlayMusic is not installed
* @throws PlayMusicNotFoundException PlayMusic is not installed
* @throws NoSuperUserException No super user permissions
* @throws de.arcus.playmusiclib.exceptions.CouldNotOpenDatabaseException Could not open the database
* @throws CouldNotOpenDatabaseException Could not open the database
*/
public void startUp() throws PlayMusicNotFoundException, NoSuperUserException, CouldNotOpenDatabaseException {
// Gets the package manager
@ -296,9 +309,10 @@ public class PlayMusicManager {
/**
* Reloads the database from PlayMusic
* @throws NoSuperUserException No super user permissions
* @throws de.arcus.playmusiclib.exceptions.CouldNotOpenDatabaseException Could not open the database
* @throws CouldNotOpenDatabaseException Could not open the database
*/
public void realoadDatabase() throws NoSuperUserException, CouldNotOpenDatabaseException {
// Reload database
loadDatabase();
}

View file

@ -98,7 +98,7 @@ public class AlbumDataSource extends DataSource<Album> {
super(playMusicManager);
// Load global settings
setOfflineOnly(playMusicManager.getOfflineOnly());
//setOfflineOnly(playMusicManager.getOfflineOnly());
}
/**

View file

@ -93,7 +93,7 @@ public class ArtistDataSource extends DataSource<Artist> {
super(playMusicManager);
// Load global settings
setOfflineOnly(playMusicManager.getOfflineOnly());
//setOfflineOnly(playMusicManager.getOfflineOnly());
}
/**

View file

@ -126,7 +126,7 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
super(playMusicManager);
// Load global settings
setOfflineOnly(playMusicManager.getOfflineOnly());
//setOfflineOnly(playMusicManager.getOfflineOnly());
}
/**

View file

@ -96,7 +96,7 @@ public class PlaylistDataSource extends DataSource<Playlist> {
super(playMusicManager);
// Load global settings
setOfflineOnly(playMusicManager.getOfflineOnly());
//setOfflineOnly(playMusicManager.getOfflineOnly());
}
/**

View file

@ -99,6 +99,21 @@ public class Album extends MusicTrackList {
return getAlbumArtist();
}
@Override
/**
* Gets the id of the track list
*/
public long getMusicTrackListID() {
return getAlbumId();
}
/**
* @return Albums tracks shouldn't show the album artwork again
*/
public boolean getShowArtworkInTrack() {
return false;
}
@Override
/**
* Loads all tracks from this album

View file

@ -85,6 +85,21 @@ public class Artist extends MusicTrackList {
return ""; // TODO
}
@Override
/**
* Gets the id of the track list
*/
public long getMusicTrackListID() {
return getArtistId();
}
/**
* @return Artists tracks should show the album artwork
*/
public boolean getShowArtworkInTrack() {
return true;
}
@Override
/**
* Loads all tracks from this artist

View file

@ -25,6 +25,9 @@ package de.arcus.playmusiclib.items;
import java.util.List;
import de.arcus.playmusiclib.PlayMusicManager;
import de.arcus.playmusiclib.datasources.AlbumDataSource;
import de.arcus.playmusiclib.datasources.ArtistDataSource;
import de.arcus.playmusiclib.datasources.PlaylistDataSource;
/**
* List of {@link de.arcus.playmusiclib.items.MusicTrack MusicTracks}.
@ -106,6 +109,24 @@ public abstract class MusicTrackList {
*/
public abstract String getDescription();
/**
* Gets the id of the track list
*/
public abstract long getMusicTrackListID();
/**
* Gets the type of the track list
*/
public String getMusicTrackListType() {
return this.getClass().getSimpleName();
}
/**
* @return Returns whether the music track should also show its album art in the list view
* Needed for playlists and artists
*/
public abstract boolean getShowArtworkInTrack();
/**
* Gets the artwork path
* @return Path to the artwork
@ -117,6 +138,34 @@ public abstract class MusicTrackList {
return mArtworkPath;
}
/**
* Loads a music track list by type and id
* @param playMusicManager The PlayMusicManager
* @param id The id of the list
* @param type The type of the list
* @return Returns the music track list
*/
public static MusicTrackList deserialize(PlayMusicManager playMusicManager, long id, String type) {
// Loads the music track list
switch (type) {
case "Album":
AlbumDataSource albumDataSource = new AlbumDataSource(playMusicManager);
albumDataSource.setOfflineOnly(false);
return albumDataSource.getById(id);
case "Artist":
ArtistDataSource artistDataSource = new ArtistDataSource(playMusicManager);
artistDataSource.setOfflineOnly(false);
return artistDataSource.getById(id);
case "Playlist":
PlaylistDataSource playlistDataSource = new PlaylistDataSource(playMusicManager);
playlistDataSource.setOfflineOnly(false);
return playlistDataSource.getById(id);
}
// Failed
return null;
}
@Override
public String toString() {
return getTitle();

View file

@ -136,6 +136,21 @@ public class Playlist extends MusicTrackList {
return getOwnerName();
}
@Override
/**
* Gets the id of the track list
*/
public long getMusicTrackListID() {
return getId();
}
/**
* @return Playlist tracks should show the album artwork
*/
public boolean getShowArtworkInTrack() {
return true;
}
@Override
/**
* Loads all tracks from this playlist