mirror of
https://github.com/playmusicexporter/playmusicexporter
synced 2024-05-14 04:46:42 +00:00
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:
parent
ed4446e48e
commit
b6194613a5
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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>
|
|
@ -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>
|
|
@ -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" />
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -98,7 +98,7 @@ public class AlbumDataSource extends DataSource<Album> {
|
|||
super(playMusicManager);
|
||||
|
||||
// Load global settings
|
||||
setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
//setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -93,7 +93,7 @@ public class ArtistDataSource extends DataSource<Artist> {
|
|||
super(playMusicManager);
|
||||
|
||||
// Load global settings
|
||||
setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
//setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -126,7 +126,7 @@ public class MusicTrackDataSource extends DataSource<MusicTrack> {
|
|||
super(playMusicManager);
|
||||
|
||||
// Load global settings
|
||||
setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
//setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -96,7 +96,7 @@ public class PlaylistDataSource extends DataSource<Playlist> {
|
|||
super(playMusicManager);
|
||||
|
||||
// Load global settings
|
||||
setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
//setOfflineOnly(playMusicManager.getOfflineOnly());
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue