org.yammp.fragment.ArtistFragment.java Source code

Java tutorial

Introduction

Here is the source code for org.yammp.fragment.ArtistFragment.java

Source

/*
 *  YAMMP - Yet Another Multi Media Player for android
 *  Copyright (C) 2011-2012  Mariotaku Lee <mariotaku.lee@gmail.com>
 *
 *  This file is part of YAMMP.
 *
 *  YAMMP is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *  (at your option) any later version.
 *
 *  YAMMP is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with YAMMP.  If not, see <http://www.gnu.org/licenses/>.
 */

package org.yammp.fragment;

import java.io.File;

import org.yammp.Constants;
import org.yammp.R;
import org.yammp.YAMMPApplication;
import org.yammp.app.TrackBrowserActivity;
import org.yammp.dialog.DeleteDialogFragment;
import org.yammp.util.LazyImageLoader;
import org.yammp.util.MediaUtils;

import android.app.SearchManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.provider.MediaStore.Audio;
import android.support.v4.app.FragmentTransaction;
import android.support.v4.app.LoaderManager;
import android.support.v4.content.CursorLoader;
import android.support.v4.content.Loader;
import android.support.v4.widget.SimpleCursorAdapter;
import android.util.Log;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.LayoutInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnCreateContextMenuListener;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ExpandableListView;
import android.widget.ExpandableListView.ExpandableListContextMenuInfo;
import android.widget.ExpandableListView.OnGroupExpandListener;
import android.widget.GridView;
import android.widget.ImageView;
import android.widget.SimpleCursorTreeAdapter;
import android.widget.TextView;

import com.actionbarsherlock.app.SherlockFragment;

public class ArtistFragment extends SherlockFragment
        implements LoaderManager.LoaderCallbacks<Cursor>, Constants, OnGroupExpandListener, OnItemSelectedListener {

    private ArtistsAdapter mArtistsAdapter;

    private ExpandableListView mListView;

    private int mSelectedGroupPosition;
    private long mSelectedGroupId, mSelectedChildId;
    private Cursor mGroupCursor;
    private String mCurrentGroupArtistName, mCurrentChildArtistNameForAlbum, mCurrentChildAlbumName;
    private boolean mGroupSelected, mChildSelected = false;
    private LazyImageLoader mImageLoader;

    private int mGroupArtistIdIdx, mGroupArtistIdx, mGroupAlbumIdx, mGroupSongIdx;

    private BroadcastReceiver mMediaStatusReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            mListView.invalidateViews();
        }

    };

    private MediaUtils mUtils;

    public ArtistFragment() {

    }

    public ArtistFragment(Bundle args) {
        setArguments(args);
    }

    @Override
    public void onActivityCreated(Bundle savedInstanceState) {
        super.onActivityCreated(savedInstanceState);
        mUtils = ((YAMMPApplication) getSherlockActivity().getApplication()).getMediaUtils();
        setHasOptionsMenu(true);

        mImageLoader = ((YAMMPApplication) getSherlockActivity().getApplication()).getLazyImageLoader();

        mArtistsAdapter = new ArtistsAdapter(getSherlockActivity(), null, R.layout.artist_list_item_group,
                new String[] {}, new int[] {}, R.layout.artist_list_item_child, new String[] {}, new int[] {});
        mListView = (ExpandableListView) getView().findViewById(R.id.artist_expandable_list);
        mListView.setAdapter(mArtistsAdapter);
        mListView.setOnGroupExpandListener(this);
        mListView.setOnCreateContextMenuListener(this);
        mListView.setOnItemSelectedListener(this);

        registerForContextMenu(mListView);

        getLoaderManager().initLoader(0, null, this);
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {

        if (item.getGroupId() == hashCode()) {
            switch (item.getItemId()) {
            case PLAY_SELECTION:
                if (mGroupSelected && !mChildSelected) {
                    long[] list = mUtils.getSongListForArtist(mSelectedGroupId);
                    mUtils.playAll(list, 0);
                } else if (mChildSelected && !mGroupSelected) {
                    long[] list = mUtils.getSongListForAlbum(mSelectedChildId);
                    mUtils.playAll(list, 0);
                }
                return true;
            case DELETE_ITEMS:
                if (mGroupSelected && !mChildSelected) {
                    DeleteDialogFragment.getInstance(false, mSelectedGroupId, DeleteDialogFragment.ARTIST)
                            .show(getFragmentManager(), "dialog");
                } else if (mChildSelected && !mGroupSelected) {
                    DeleteDialogFragment.getInstance(false, mSelectedChildId, DeleteDialogFragment.ARTIST)
                            .show(getFragmentManager(), "dialog");
                }
                return true;
            case DELETE_LYRICS:
                if (mGroupSelected && !mChildSelected) {
                    DeleteDialogFragment.getInstance(true, mSelectedGroupId, DeleteDialogFragment.ARTIST)
                            .show(getFragmentManager(), "dialog");
                } else if (mChildSelected && !mGroupSelected) {
                    DeleteDialogFragment.getInstance(true, mSelectedChildId, DeleteDialogFragment.ARTIST)
                            .show(getFragmentManager(), "dialog");
                }
                return true;
            case SEARCH:
                if (mGroupSelected && !mChildSelected) {
                    doSearch(mCurrentGroupArtistName, null);
                } else if (mChildSelected && !mGroupSelected) {
                    doSearch(mCurrentChildArtistNameForAlbum, mCurrentChildAlbumName);
                }
                return true;
            }
        }
        return super.onContextItemSelected(item);
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo info) {

        ExpandableListContextMenuInfo mi = (ExpandableListContextMenuInfo) info;

        int itemtype = ExpandableListView.getPackedPositionType(mi.packedPosition);
        mSelectedGroupPosition = ExpandableListView.getPackedPositionGroup(mi.packedPosition);
        int gpos = mSelectedGroupPosition;
        if (itemtype == ExpandableListView.PACKED_POSITION_TYPE_GROUP) {

            mGroupSelected = true;
            mChildSelected = false;
            mGroupCursor.moveToPosition(gpos);
            menu.add(hashCode(), PLAY_SELECTION, 0, R.string.play_selection);
            menu.add(hashCode(), DELETE_ITEMS, 0, R.string.delete_music);
            menu.add(hashCode(), DELETE_LYRICS, 0, R.string.delete_lyrics);
            if (gpos == -1) {
                // this shouldn't happen
                Log.d("Artist/Album", "no group");
                return;
            }
            mCurrentGroupArtistName = mGroupCursor.getString(mGroupArtistIdx);
            mSelectedGroupId = mGroupCursor.getLong(mGroupArtistIdIdx);
            if (mCurrentGroupArtistName != null && !MediaStore.UNKNOWN_STRING.equals(mCurrentGroupArtistName)) {
                menu.setHeaderTitle(mCurrentGroupArtistName);
                menu.add(hashCode(), SEARCH, 0, android.R.string.search_go);
            } else {
                menu.setHeaderTitle(getString(R.string.unknown_artist));
            }
        }
    }

    @Override
    public Loader<Cursor> onCreateLoader(int id, Bundle args) {

        String[] cols = new String[] { Audio.Artists._ID, Audio.Artists.ARTIST, Audio.Artists.NUMBER_OF_ALBUMS,
                Audio.Artists.NUMBER_OF_TRACKS };
        Uri uri = Audio.Artists.EXTERNAL_CONTENT_URI;
        return new CursorLoader(getSherlockActivity(), uri, cols, null, null, Audio.Artists.DEFAULT_SORT_ORDER);
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
        View view = inflater.inflate(R.layout.artist_album_browser, container, false);
        return view;
    }

    @Override
    public void onGroupExpand(int position) {
        long id = mArtistsAdapter.getGroupId(position);
        showGroupDetails(position, id);
    }

    @Override
    public void onItemSelected(AdapterView<?> adapter, View view, int position, long id) {

        if (view.getTag() != null && view.getTag() instanceof ViewHolderChild) {
            mListView.setDescendantFocusability(ViewGroup.FOCUS_AFTER_DESCENDANTS);
            ((ViewHolderChild) view.getTag()).gridview.requestFocus();
        } else {
            mListView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
            mListView.requestFocus();
        }

    }

    @Override
    public void onLoaderReset(Loader<Cursor> loader) {
        mArtistsAdapter.setGroupCursor(null);
    }

    @Override
    public void onLoadFinished(Loader<Cursor> loader, Cursor data) {

        if (data == null) {
            getSherlockActivity().finish();
            return;
        }

        mGroupCursor = data;

        mGroupArtistIdIdx = data.getColumnIndexOrThrow(Audio.Artists._ID);
        mGroupArtistIdx = data.getColumnIndexOrThrow(Audio.Artists.ARTIST);
        mGroupAlbumIdx = data.getColumnIndexOrThrow(Audio.Artists.NUMBER_OF_ALBUMS);
        mGroupSongIdx = data.getColumnIndexOrThrow(Audio.Artists.NUMBER_OF_TRACKS);

        mArtistsAdapter.changeCursor(data);

    }

    @Override
    public void onNothingSelected(AdapterView<?> arg0) {
        if (!mListView.isFocused()) {
            mListView.setDescendantFocusability(ViewGroup.FOCUS_BEFORE_DESCENDANTS);
            mListView.requestFocus();
        }
    }

    @Override
    public void onSaveInstanceState(Bundle outState) {
        outState.putAll(getArguments() != null ? getArguments() : new Bundle());
        super.onSaveInstanceState(outState);
    }

    @Override
    public void onStart() {
        super.onStart();

        IntentFilter filter = new IntentFilter();
        filter.addAction(BROADCAST_META_CHANGED);
        filter.addAction(BROADCAST_QUEUE_CHANGED);
        getSherlockActivity().registerReceiver(mMediaStatusReceiver, filter);
    }

    @Override
    public void onStop() {
        getSherlockActivity().unregisterReceiver(mMediaStatusReceiver);
        super.onStop();
    }

    private void doSearch(String artist, String album) {

        CharSequence title = null;
        String query = null;

        boolean isUnknownArtist = artist == null || MediaStore.UNKNOWN_STRING.equals(artist);
        boolean isUnknownAlbum = album == null || MediaStore.UNKNOWN_STRING.equals(album);
        if (isUnknownArtist && isUnknownAlbum)
            return;

        Intent i = new Intent();
        i.setAction(MediaStore.INTENT_ACTION_MEDIA_SEARCH);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

        title = album != null ? album : artist;
        query = album != null ? album : artist;

        if (!isUnknownArtist) {
            i.putExtra(MediaStore.EXTRA_MEDIA_ARTIST, artist);
        }
        if (!isUnknownAlbum) {
            i.putExtra(MediaStore.EXTRA_MEDIA_ALBUM, album);
        }
        i.putExtra(MediaStore.EXTRA_MEDIA_FOCUS, "audio/*");
        title = getString(R.string.mediasearch, title);
        i.putExtra(SearchManager.QUERY, query);

        startActivity(Intent.createChooser(i, title));
    }

    private void showGroupDetails(int groupPosition, long id) {

        View detailsFrame = getSherlockActivity().findViewById(R.id.frame_details);
        boolean mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;

        if (mDualPane) {

            mListView.setSelectedGroup(groupPosition);

            TrackFragment fragment = new TrackFragment();
            Bundle args = new Bundle();
            args.putString(INTENT_KEY_TYPE, MediaStore.Audio.Artists.CONTENT_TYPE);
            args.putLong(Audio.Artists._ID, id);

            fragment.setArguments(args);

            FragmentTransaction ft = getFragmentManager().beginTransaction();
            ft.replace(R.id.frame_details, fragment);
            ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
            ft.commit();

        }
    }

    private class AlbumChildAdapter extends SimpleCursorAdapter implements OnCreateContextMenuListener {

        private int mAlbumIndex;

        private int mArtistIndex;
        private int mAlbumArtIndex;

        private AlbumChildAdapter(Context context, int layout, Cursor cursor, String[] from, int[] to, int flags) {
            super(context, layout, cursor, from, to, flags);

            getColumnIndices(cursor);
        }

        @Override
        public void bindView(View view, Context context, Cursor cursor) {

            view.setOnCreateContextMenuListener(this);
            ViewHolderItem viewholder = (ViewHolderItem) view.getTag();

            if (viewholder == null)
                return;

            String album_name = cursor.getString(mAlbumIndex);
            boolean unknown = album_name == null || album_name.equals(MediaStore.UNKNOWN_STRING);
            if (unknown) {
                album_name = context.getString(R.string.unknown_album);
            }
            viewholder.album_name.setText(album_name);

            String artist_name = cursor.getString(mArtistIndex);
            if (artist_name == null || artist_name.equals(MediaStore.UNKNOWN_STRING)) {
                artist_name = context.getString(R.string.unknown_artist);
            }
            viewholder.artist_name.setText(artist_name);

            long aid = cursor.getLong(0);

            long currentalbumid = mUtils.getCurrentAlbumId();
            if (currentalbumid == aid) {
                viewholder.album_name.setCompoundDrawablesWithIntrinsicBounds(0, 0,
                        R.drawable.ic_indicator_nowplaying_small, 0);
            } else {
                viewholder.album_name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            }

            String art = cursor.getString(mAlbumArtIndex);

            if (art != null && art.toString().length() > 0) {
                mImageLoader.displayImage(new File(art), viewholder.album_art);
            } else {
                viewholder.album_art.setImageResource(R.drawable.ic_mp_albumart_unknown);
            }
            viewholder.album_id = aid;
            viewholder.album_name_string = album_name;
            viewholder.artist_name_string = artist_name;

        }

        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {

            View view = super.newView(context, cursor, parent);
            ViewHolderItem mViewHolder = new ViewHolderItem(view);
            view.setTag(mViewHolder);
            return view;
        }

        @Override
        public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo info) {

            mGroupSelected = false;
            mChildSelected = true;
            getSherlockActivity().getMenuInflater().inflate(R.menu.music_browser_item, menu);
            if (v.getTag() == null)
                return;
            ViewHolderItem viewholder = (ViewHolderItem) v.getTag();
            mCurrentChildArtistNameForAlbum = viewholder.artist_name_string;
            mCurrentChildAlbumName = viewholder.album_name_string;
            mSelectedChildId = viewholder.album_id;
            if (mCurrentChildAlbumName == null || MediaStore.UNKNOWN_STRING.equals(mCurrentChildAlbumName)) {
                menu.setHeaderTitle(getString(R.string.unknown_artist));
                menu.findItem(R.id.search).setEnabled(false);
                menu.findItem(R.id.search).setVisible(false);
            } else {
                menu.setHeaderTitle(mCurrentChildAlbumName);
            }

        }

        private void getColumnIndices(Cursor cursor) {

            if (cursor != null) {
                mAlbumIndex = cursor.getColumnIndexOrThrow(Audio.Albums.ALBUM);
                mArtistIndex = cursor.getColumnIndexOrThrow(Audio.Albums.ARTIST);
                mAlbumArtIndex = cursor.getColumnIndexOrThrow(Audio.Albums.ALBUM_ART);

            }
        }

        private class ViewHolderItem {

            TextView album_name;
            TextView artist_name;
            ImageView album_art;
            long album_id;
            String album_name_string;
            String artist_name_string;

            public ViewHolderItem(View view) {
                album_name = (TextView) view.findViewById(R.id.album_name);
                artist_name = (TextView) view.findViewById(R.id.artist_name);
                album_art = (ImageView) view.findViewById(R.id.album_art);
            }
        }

    }

    private class ArtistsAdapter extends SimpleCursorTreeAdapter implements OnItemClickListener {

        public ArtistsAdapter(Context context, Cursor cursor, int glayout, String[] gfrom, int[] gto, int clayout,
                String[] cfrom, int[] cto) {
            super(context, cursor, glayout, gfrom, gto, clayout, cfrom, cto);
        }

        @Override
        public void bindChildView(View view, Context context, Cursor cursor, boolean isLastChild) {

            ViewHolderChild viewholder = (ViewHolderChild) view.getTag();
            viewholder.gridview.setAdapter(new AlbumChildAdapter(context, R.layout.album_grid_item, cursor,
                    new String[] {}, new int[] {}, 0));
            viewholder.gridview.setOnItemClickListener(this);

            int item_width = getResources().getDimensionPixelOffset(R.dimen.gridview_item_width);
            int item_height = getResources().getDimensionPixelOffset(R.dimen.gridview_item_height);

            int parent_width = mListView.getWidth();
            int albums_count = cursor.getCount();
            int gridview_columns = (int) (Math.floor(parent_width / item_width) > 0
                    ? Math.floor(parent_width / item_width)
                    : 1);
            int gridview_rows = (int) Math.ceil((float) albums_count / gridview_columns);

            int default_padding = getResources().getDimensionPixelOffset(R.dimen.default_element_spacing);
            int paddings_sum = default_padding * (gridview_rows + 1);

            viewholder.gridview.getLayoutParams().height = item_height * gridview_rows + paddings_sum;

        }

        @Override
        public void bindGroupView(View view, Context context, Cursor cursor, boolean isexpanded) {

            ViewHolderGroup viewholder = (ViewHolderGroup) view.getTag();

            String artist = cursor.getString(mGroupArtistIdx);
            boolean unknown = artist == null || MediaStore.UNKNOWN_STRING.equals(artist);
            if (unknown) {
                viewholder.artist_name.setText(R.string.unknown_artist);
            } else {
                viewholder.artist_name.setText(artist);
            }

            int numalbums = cursor.getInt(mGroupAlbumIdx);
            int numsongs = cursor.getInt(mGroupSongIdx);

            String songs_albums = mUtils.makeAlbumsLabel(numalbums, numsongs, unknown);

            viewholder.album_track_count.setText(songs_albums);

            long currentartistid = mUtils.getCurrentArtistId();
            long aid = cursor.getLong(mGroupArtistIdIdx);
            if (currentartistid == aid) {
                viewholder.artist_name.setCompoundDrawablesWithIntrinsicBounds(0, 0,
                        R.drawable.ic_indicator_nowplaying_small, 0);
            } else {
                viewholder.artist_name.setCompoundDrawablesWithIntrinsicBounds(0, 0, 0, 0);
            }
        }

        @Override
        public int getChildrenCount(int groupPosition) {

            return 1;
        }

        @Override
        public View newChildView(Context context, Cursor cursor, boolean isLastChild, ViewGroup parent) {

            View view = super.newChildView(context, cursor, isLastChild, parent);
            ViewHolderChild viewholder = new ViewHolderChild(view);
            view.setTag(viewholder);

            return view;
        }

        @Override
        public View newGroupView(Context context, Cursor cursor, boolean isExpanded, ViewGroup parent) {

            View view = super.newGroupView(context, cursor, isExpanded, parent);
            ViewHolderGroup viewholder = new ViewHolderGroup(view);
            view.setTag(viewholder);
            return view;
        }

        @Override
        public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
            showDetails(position, id);
        }

        private void showDetails(int childPosition, long id) {

            View detailsFrame = getSherlockActivity().findViewById(R.id.frame_details);
            boolean mDualPane = detailsFrame != null && detailsFrame.getVisibility() == View.VISIBLE;

            Bundle bundle = new Bundle();
            bundle.putString(INTENT_KEY_TYPE, MediaStore.Audio.Albums.CONTENT_TYPE);
            bundle.putLong(MediaStore.Audio.Albums._ID, id);

            if (mDualPane) {

                TrackFragment fragment = new TrackFragment();
                fragment.setArguments(bundle);

                FragmentTransaction ft = getFragmentManager().beginTransaction();
                ft.replace(R.id.frame_details, fragment);
                ft.setTransition(FragmentTransaction.TRANSIT_FRAGMENT_FADE);
                ft.commit();

            } else {

                Intent intent = new Intent(getSherlockActivity(), TrackBrowserActivity.class);
                intent.putExtras(bundle);
                startActivity(intent);
            }
        }

        @Override
        protected Cursor getChildrenCursor(Cursor groupCursor) {

            long id = groupCursor.getLong(groupCursor.getColumnIndexOrThrow(Audio.Artists._ID));

            String[] cols = new String[] { Audio.Albums._ID, Audio.Albums.ALBUM, Audio.Albums.ARTIST,
                    Audio.Albums.NUMBER_OF_SONGS, Audio.Albums.NUMBER_OF_SONGS_FOR_ARTIST, Audio.Albums.ALBUM_ART };
            Uri uri = Audio.Artists.Albums.getContentUri(EXTERNAL_VOLUME, id);
            Cursor c = getSherlockActivity().getContentResolver().query(uri, cols, null, null,
                    Audio.Albums.DEFAULT_SORT_ORDER);

            return c;
        }

    }

    private class ViewHolderChild {

        GridView gridview;

        public ViewHolderChild(View view) {
            gridview = (GridView) view.findViewById(R.id.artist_child_grid_view);
        }
    }

    private class ViewHolderGroup {

        TextView artist_name;
        TextView album_track_count;

        public ViewHolderGroup(View view) {
            artist_name = (TextView) view.findViewById(R.id.name);
            album_track_count = (TextView) view.findViewById(R.id.summary);
        }
    }

}