title: Android:How to play song from within RecyclerView adapter onClick method (With Music Service Class)
body: <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>