Android:How to play song from within RecyclerView adapter onClick method (With Music Service Class)
<p>I am doing a project in which I have to create a simple music player app with RecyclerView (Already followed Codetut plus tutorials).
I inflated RecyclerView inside a Fragment.
But I'm stuck on how to play a song when on item click.</p>

<p>I am trying to play song when a user click any item (contains list of songs) in RecyclerView.
I am trying to play song with help of MusicService class, but don't know how to do it.
Any help regarding how can I do this would be helpful.</p>

<p>Tho I tried to call <strong>MusicService Class</strong> with Intent inside onClick method but I'm getting Error.! ( Error code is displayed at bottom )</p>

<p>This is <strong>Fragment</strong></p>

<pre><code>public class Tab3 extends Fragment {

private MusicService musicSrv;
private Intent playIntent;
private boolean musicBound=false;

private static final String KEY_LAYOUT_MANAGER = "layoutManager";

private RecyclerView mRecyclerView;
private SongAdapter mAdapter;
protected List&lt;SongsData&gt; songsList;

private enum LayoutManagerType {
    GRID_LAYOUT_MANAGER,
    LINEAR_LAYOUT_MANAGER
}

protected LayoutManagerType mCurrentLayoutManagerType;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    songsList = new ArrayList&lt;SongsData&gt;();

    getSongList();

    Collections.sort(songsList, new Comparator&lt;SongsData&gt;(){
        public int compare(SongsData a, SongsData b){
            return a.getTitle().compareTo(b.getTitle());
        }
    });

}


public Tab3() {
}


@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View rootView = inflater.inflate(R.layout.fragment_tab3, container,
            false);

    mRecyclerView = (RecyclerView) rootView.findViewById(R.id.recyclerview);

    mRecyclerView.setLayoutManager(new LinearLayoutManager(getActivity()));

    mCurrentLayoutManagerType = LayoutManagerType.LINEAR_LAYOUT_MANAGER;

    if (savedInstanceState != null) {
        mCurrentLayoutManagerType = (LayoutManagerType) savedInstanceState
                .getSerializable(KEY_LAYOUT_MANAGER);
    }

    mAdapter = new SongAdapter(songsList, getContext());
    mRecyclerView.setAdapter(mAdapter);

    return rootView;
}


public void getSongList() {

    ContentResolver musicResolver = getActivity().getContentResolver();
    Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
    Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);

    if(musicCursor!=null &amp;&amp; musicCursor.moveToFirst()){
        int titleColumn = musicCursor.getColumnIndex
                (android.provider.MediaStore.Audio.Media.TITLE);
        int idColumn = musicCursor.getColumnIndex
                (android.provider.MediaStore.Audio.Media._ID);
        int artistColumn = musicCursor.getColumnIndex
                (android.provider.MediaStore.Audio.Media.ARTIST);
                (MediaStore.Audio.Albums.ALBUM_ART); 
        do {
            long thisId = musicCursor.getLong(idColumn);
            String thisTitle = musicCursor.getString(titleColumn);
            String thisArtist = musicCursor.getString(artistColumn);
            songsList.add(new SongsData(thisId, thisTitle, thisArtist));
        }
        while (musicCursor.moveToNext());
    }
}  }
</code></pre>

<p>This is <strong>Music Service Class</strong> (implemented from Codetutplus)</p>

<pre><code>public class MusicService extends Service implements
    MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
    MediaPlayer.OnCompletionListener {

private final IBinder musicBind = new MusicBinder();

//media player
private MediaPlayer player;
//song list
private ArrayList&lt;SongsData&gt; songs;
//current position
private int songPosn;


private MusicService musicSrv;
private Intent playIntent;
private boolean musicBound=false;


public void onCreate(){
    //create the service
    super.onCreate();
    //initialize position
    songPosn=0;
    //create player
    player = new MediaPlayer();
    initMusicPlayer();
}

public void initMusicPlayer(){
    //set player properties
    player.setWakeMode(getApplicationContext(),
            PowerManager.PARTIAL_WAKE_LOCK);
    player.setAudioStreamType(AudioManager.STREAM_MUSIC);

    player.setOnPreparedListener(this);
    player.setOnCompletionListener(this);
    player.setOnErrorListener(this);
}

public void setList(List&lt;SongsData&gt; list){
    songs= (ArrayList&lt;SongsData&gt;) list;
}

public class MusicBinder extends Binder {
    MusicService getService() {
        return MusicService.this;
    }
}


@Nullable
@Override
public IBinder onBind(Intent intent) {
    return musicBind;
}

@Override
public void onCompletion(MediaPlayer mediaPlayer) {

}

@Override
public boolean onUnbind(Intent intent){
    player.stop();
    player.release();
    return false;
}

@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
    return false;
}

@Override
public void onPrepared(MediaPlayer mp) {
    //Start playback
    mp.start();
}


public void playSong(){
    //play a song
    player.reset();
    //get song
    SongsData playSong = songs.get(songPosn);
    long currSong = playSong.getID();
    Uri trackUri = ContentUris.withAppendedId(android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            currSong);
    try {
        player.setDataSource(getApplicationContext(), trackUri);
    } catch (IOException e) {
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    } catch (IllegalArgumentException e) {
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    } catch (IllegalStateException e) {
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    } catch (SecurityException e) {
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    }
    player.prepareAsync();
}

public void setSong(int songIndex){
    songPosn=songIndex;
}  }
</code></pre>

<p>This is <strong>ViewHolder Class</strong></p>

<pre><code>public class CustomViewHolder  extends RecyclerView.ViewHolder
    implements View.OnClickListener, View.OnLongClickListener{

CardView cv;
TextView title;
TextView description;
ImageView imageView;

private ClickListener clickListener;

public CustomViewHolder(View itemView) {
    super(itemView);
    cv = (CardView) itemView.findViewById(R.id.cardView);
    title = (TextView) itemView.findViewById(R.id.title);
    description = (TextView) itemView.findViewById(R.id.description);
    imageView = (ImageView) itemView.findViewById(R.id.imageView);
    itemView.setOnClickListener(this);
    itemView.setOnLongClickListener(this);
}
public interface ClickListener {
    void onClick(View v, int position, boolean isLongClick);

}
public void setClickListener(ClickListener clickListener) {
    this.clickListener = clickListener;
}

@Override
public void onClick(View v) {
    clickListener.onClick(v, getPosition(), false);
}

@Override
public boolean onLongClick(View v) {
    clickListener.onClick(v, getPosition(), true);
    return true;
}   }
</code></pre>

<p>This is <strong>Adapter Class</strong></p>

<pre><code>public class SongAdapter extends RecyclerView.Adapter&lt;CustomViewHolder&gt; {

public List&lt;SongsData&gt; list = Collections.emptyList();
Context context;

public SongAdapter(List&lt;SongsData&gt; list, Context context) {
    this.list = list;
    this.context = context;
}

@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    View songView = LayoutInflater.from(parent.getContext()).inflate(R.layout.fragment_sample, parent, false);
    CustomViewHolder myHolder = new CustomViewHolder(songView);
    return myHolder;
}

@Override
public void onBindViewHolder(CustomViewHolder holder, int position) {

    holder.setClickListener(new CustomViewHolder.ClickListener() {

        @Override
        public void onClick(View v, int pos, boolean isLongClick) {
            if (isLongClick) {
                // View v at position pos is long-clicked.
                Toast.makeText(context, "You just Long Clicked me.. Wowww LOL", Toast.LENGTH_SHORT).show();
            } else {
                // View v at position pos is clicked.
                Intent intent = new Intent(context.getApplicationContext(), MusicService.class);
                context.startService(intent);
                Toast.makeText(context, "You just Clicked me.. Wowww LOL", Toast.LENGTH_SHORT).show();
            }
        }
    });

    holder.getItemId();
    holder.title.setText(list.get(position).title);
    holder.description.setText(list.get(position).description);
}

@Override
public int getItemCount() {
    //returns the number of elements the RecyclerView will displaye
    return list.size();
}

@Override
public void onAttachedToRecyclerView(RecyclerView recyclerView) {
    super.onAttachedToRecyclerView(recyclerView);
}


//Insert a new item to the RecyclerView on a predefined position
public void insert(int position, SongsData data) {
    list.add(position, data);
    notifyItemChanged(position);
}

public void remove(SongsData data) {
    int position = list.indexOf(data);
    list.remove(position);
    notifyItemRemoved(position);
}  }  
</code></pre>

<p>And Here's Error when I click an Item - <code>E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                  Process: com.example.ansh.makingmusicapp2, PID: 16713
                                                                                  java.lang.RuntimeException: Unable to start service com.example.ansh.makingmusicapp2.MusicService@b433953 with Intent { cmp=com.example.ansh.makingmusicapp2/.MusicService }: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                                      at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3027)
                                                                                      at android.app.ActivityThread.-wrap17(ActivityThread.java)
                                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442)
                                                                                      at android.os.Handler.dispatchMessage(Handler.java:102)
                                                                                      at android.os.Looper.loop(Looper.java:148)
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)
                                                                                   Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equals(java.lang.Object)' on a null object reference
                                                                                      at com.example.ansh.makingmusicapp2.MusicService.onStartCommand(MusicService.java:64)
                                                                                      at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:3010)
                                                                                      at android.app.ActivityThread.-wrap17(ActivityThread.java) 
                                                                                      at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1442) 
                                                                                      at android.os.Handler.dispatchMessage(Handler.java:102) 
                                                                                      at android.os.Looper.loop(Looper.java:148) 
                                                                                      at android.app.ActivityThread.main(ActivityThread.java:5417) 
                                                                                      at java.lang.reflect.Method.invoke(Native Method) 
                                                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726) 
                                                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)</code></p>