com.andryr.musicplayer.activities.MusicPicker.java Source code

Java tutorial

Introduction

Here is the source code for com.andryr.musicplayer.activities.MusicPicker.java

Source

/*
 * Copyright 2016 andryr
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.andryr.musicplayer.activities;

import android.content.ContentResolver;
import android.content.Intent;
import android.database.Cursor;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.support.v4.view.MenuItemCompat;
import android.support.v7.view.ActionMode;
import android.support.v7.widget.LinearLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.SearchView;
import android.support.v7.widget.SearchView.OnCloseListener;
import android.support.v7.widget.SearchView.OnQueryTextListener;
import android.util.SparseBooleanArray;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Filter;
import android.widget.Filterable;
import android.widget.TextView;

import com.andryr.musicplayer.R;
import com.andryr.musicplayer.model.Song;
import com.andryr.musicplayer.model.db.favorites.FavoritesContract;

import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;

//TODO utiliser des Loaders, selon le modle de SearchActivity
public class MusicPicker extends BaseActivity {

    public static final String EXTRA_IDS = "ids";
    private static final String[] sProjection = { MediaStore.Audio.Media._ID, MediaStore.Audio.Media.TITLE,
            MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM, MediaStore.Audio.Media.ALBUM_ID,
            MediaStore.Audio.Media.ARTIST_ID, MediaStore.Audio.Media.TRACK, MediaStore.Audio.Media.DURATION };

    private OnClickListener mOnClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            int position = mRecyclerView.getChildPosition(v);
            mAdapter.toggleSelection(position);

        }
    };

    private ActionMode mActionMode;

    private ActionMode.Callback mActionModeCallback = new ActionMode.Callback() {

        @Override
        public boolean onCreateActionMode(ActionMode mode, Menu menu) {
            MenuInflater inflater = mode.getMenuInflater();
            inflater.inflate(R.menu.music_picker_context, menu);
            return true;
        }

        @Override
        public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
            return false;
        }

        @Override
        public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
            switch (item.getItemId()) {
            case R.id.action_submit:
                ArrayList<Song> songList = new ArrayList<>();
                SparseBooleanArray positions = mAdapter.getSelectedPositions();
                int count = positions.size();
                for (int i = 0; i < count; i++) {
                    int key = positions.keyAt(i);
                    if (positions.get(key)) {
                        songList.add(mSongList.get(key));
                    }
                }

                Intent data = new Intent();
                long[] ids = new long[songList.size()];
                for (int i = 0; i < songList.size(); i++) {
                    ids[i] = songList.get(i).getId();
                }
                data.putExtra(EXTRA_IDS, ids);

                setResult(RESULT_OK, data);
                finish();
                return true;
            case R.id.action_cancel:
                setResult(RESULT_CANCELED);
                finish();
                return true;

            }
            return false;
        }

        @Override
        public void onDestroyActionMode(ActionMode mode) {
            mActionMode = null;
        }
    };

    private List<Song> mSongList = new ArrayList<>();
    private MusicPickerAdapter mAdapter;

    private RecyclerView mRecyclerView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music_picker);
        getSongList();

        mRecyclerView = (RecyclerView) findViewById(R.id.list_view);
        mAdapter = new MusicPickerAdapter(mSongList);
        mRecyclerView.setLayoutManager(new LinearLayoutManager(this));

        mRecyclerView.setAdapter(mAdapter);
    }

    private void getSongList() {
        ContentResolver resolver = getContentResolver();
        Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

        Cursor cursor = resolver.query(musicUri, sProjection, null, null, null);

        if (cursor != null && cursor.moveToFirst()) {
            int idCol = cursor.getColumnIndex(MediaStore.Audio.Playlists.Members.AUDIO_ID);
            if (idCol == -1) {
                idCol = cursor.getColumnIndex(MediaStore.Audio.Media._ID);
            }
            int titleCol = cursor.getColumnIndex(MediaStore.Audio.Media.TITLE);
            int artistCol = cursor.getColumnIndex(MediaStore.Audio.Media.ARTIST);
            int albumCol = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM);
            int albumIdCol = cursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID);
            int trackCol = cursor.getColumnIndex(MediaStore.Audio.Media.TRACK);

            int durationCol = cursor.getColumnIndex(MediaStore.Audio.Media.DURATION);

            do {
                long id = cursor.getLong(idCol);
                String title = cursor.getString(titleCol);

                String artist = cursor.getString(artistCol);

                String album = cursor.getString(albumCol);

                long albumId = cursor.getLong(albumIdCol);

                int track = cursor.getInt(trackCol);

                long duration = cursor.getLong(durationCol);

                mSongList.add(new Song(id, title, artist, album, albumId, track, duration));
            } while (cursor.moveToNext());

            Collections.sort(mSongList, new Comparator<Song>() {

                @Override
                public int compare(Song lhs, Song rhs) {
                    Collator c = Collator.getInstance(Locale.getDefault());
                    c.setStrength(Collator.PRIMARY);
                    return c.compare(lhs.getTitle(), rhs.getTitle());
                }
            });

        }
        if (cursor != null) {
            cursor.close();
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.music_picker, menu);
        SearchView search = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.action_search));

        search.setOnQueryTextListener(new OnQueryTextListener() {

            @Override
            public boolean onQueryTextChange(String newText) {
                mAdapter.getFilter().filter(newText);
                return true;
            }

            @Override
            public boolean onQueryTextSubmit(String query) {
                // TODO Auto-generated method stub
                return true;
            }

        });
        search.setOnCloseListener(new OnCloseListener() {

            @Override
            public boolean onClose() {
                mAdapter.getFilter().filter("");
                return false;
            }
        });
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {

        return super.onOptionsItemSelected(item);
    }

    class SongViewHolder extends RecyclerView.ViewHolder {

        TextView vTitle;
        TextView vArtist;

        private View mItemView;

        public SongViewHolder(View itemView) {
            super(itemView);

            vTitle = (TextView) itemView.findViewById(R.id.title);
            vArtist = (TextView) itemView.findViewById(R.id.artist);

            mItemView = itemView;

        }

        public void setSelected(boolean selected) {
            mItemView.setSelected(selected);
        }

    }

    class MusicPickerAdapter extends RecyclerView.Adapter<SongViewHolder> implements Filterable {
        private List<Song> mSongList;
        private List<Song> mVisibleSongs = new ArrayList<>();
        private SparseBooleanArray mSelectedPositions = new SparseBooleanArray();

        private Filter mFilter = new Filter() {

            @SuppressWarnings("unchecked")
            @Override
            protected void publishResults(CharSequence constraint, FilterResults results) {
                mVisibleSongs.clear();
                mVisibleSongs.addAll((List<Song>) results.values);
                notifyDataSetChanged();

            }

            @Override
            protected FilterResults performFiltering(CharSequence constraint) {
                FilterResults results = new FilterResults();
                ArrayList<Song> filteredList = new ArrayList<>();

                if (constraint == null || constraint == "") {
                    filteredList.addAll(mSongList);
                } else {

                    Locale l = Locale.getDefault();
                    constraint = constraint.toString().trim().toLowerCase(l);
                    for (Song s : mSongList) {
                        if (s.getTitle().toLowerCase(l).contains(constraint)
                                || s.getArtist().toLowerCase(l).contains(constraint)
                                || s.getAlbum().toLowerCase(l).contains(constraint)) {
                            filteredList.add(s);
                        }
                    }
                }
                results.values = filteredList;
                results.count = filteredList.size();
                return results;
            }
        };

        public MusicPickerAdapter(List<Song> songList) {

            mSongList = songList;
            mVisibleSongs.addAll(mSongList);
        }

        @Override
        public int getItemCount() {
            return mVisibleSongs.size();
        }

        @Override
        public void onBindViewHolder(SongViewHolder viewHolder, int position) {
            Song song = mVisibleSongs.get(position);

            viewHolder.vTitle.setText(song.getTitle());
            viewHolder.vArtist.setText(song.getArtist());

            position = mSongList.indexOf(song);

            viewHolder.setSelected(mSelectedPositions.get(position, false));

        }

        @Override
        public SongViewHolder onCreateViewHolder(ViewGroup parent, int type) {
            View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.music_picker_list_item,
                    parent, false);
            itemView.setOnClickListener(mOnClickListener);
            SongViewHolder viewHolder = new SongViewHolder(itemView);

            return viewHolder;
        }

        public void setSelected(int position, boolean selected) {
            Song s = mVisibleSongs.get(position);
            int index = mSongList.indexOf(s);
            if (index != -1) {
                if (selected) {
                    mSelectedPositions.append(index, true);

                } else {
                    mSelectedPositions.delete(index);

                }

                if (mActionMode == null && mSelectedPositions.size() > 0) {
                    mActionMode = startSupportActionMode(mActionModeCallback);
                } else if (mActionMode != null && mSelectedPositions.size() == 0) {
                    mActionMode.finish();
                }

                notifyItemChanged(position);
            }
        }

        public void toggleSelection(int position) {
            Song s = mVisibleSongs.get(position);
            int index = mSongList.indexOf(s);
            boolean selected = mSelectedPositions.get(index, false);
            setSelected(position, !selected);

        }

        public SparseBooleanArray getSelectedPositions() {
            return mSelectedPositions;
        }

        @Override
        public Filter getFilter() {
            return mFilter;
        }

    }
}