Learn, Share, Build

244
September 25, 2017, at 10:42 AM

This question already has an answer here:

  • What is a NullPointerException, and how do I fix it? 12 answers

I'm trying to build a simple media player app. I created a RecyclerViewAdapter with CursorAdapter in it's constructor and managed to implement a way to use External Storage to create a playlist. Now I want to make an onClickListener but I'm having trouble. I just need to get the TAG of the view that is clicked so that I can get the necessary values from it and pass it on to media player to play. Please help. I tried to do this using an interface but it's not working.

This is my onClick method implementation through interface

public class MainActivity extends AppCompatActivity implements RecyclerViewAdapter.OnItemClickListener{
@Override
protected void onCreate(Bundle savedInstanceState) {
    ActivityCompat.requestPermissions(MainActivity.this,
            new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
            1);
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    selectedFile = (TextView) findViewById(R.id.selected_file);
    seekBar = (SeekBar) findViewById(R.id.seekbar);
    playButton = (ImageButton) findViewById(R.id.play);
    nextButton = (ImageButton) findViewById(R.id.next);
    prevButton = (ImageButton) findViewById(R.id.prev);
    player = new MediaPlayer();
    player.setOnCompletionListener(onCompletion);
    player.setOnErrorListener(onError);
    seekBar.setOnSeekBarChangeListener(seekBarChanged);
    recyclerView = (RecyclerView) findViewById(R.id.playlist);

    c = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
    if(null != c) {
        c.moveToFirst();
        layoutManager = new LinearLayoutManager(this);
        recyclerView.setLayoutManager(layoutManager);
        mAdapter = new RecyclerViewAdapter(this, c);
        recyclerView.setAdapter(mAdapter);
        playButton.setOnClickListener(onButtonClick);
        nextButton.setOnClickListener(onButtonClick);
        prevButton.setOnClickListener(onButtonClick);
    }
public void onItemClick(View v) {
    songName = ((TextView) v.findViewById(R.id.songname)).getText().toString();
    albumName = ((TextView)v.findViewById(R.id.album)).getText().toString();
    currentFile = (String) v.getTag();
    Log.e("File","Selected");
    selectedFile.setText(songName);
    startPlay(currentFile);
}
/*other code */

And this is my recyclerview adapter

package com.veloxigami.android.audioplayerusingservice;
import android.content.Context;
import android.content.Intent;
import android.database.Cursor;
import android.provider.MediaStore;
import android.support.v4.widget.CursorAdapter;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import android.widget.TextView;
import org.w3c.dom.Text;

public class RecyclerViewAdapter extends RecyclerView.Adapter<RecyclerViewAdapter.ViewHolder> {
// Because RecyclerView.Adapter in its current form doesn't natively
// support cursors, we wrap a CursorAdapter that will do all the job
// for us.
CursorAdapter mCursorAdapter;
Context mContext;
public interface OnItemClickListener {
    void onItemClick(View view);
}
public RecyclerViewAdapter.OnItemClickListener clickListener;
public RecyclerViewAdapter(Context context, Cursor c) {
    mContext = context;
    mCursorAdapter = new CursorAdapter(mContext, c, 0) {
        @Override
        public void bindView(View view, Context context, Cursor cursor) {
            // Binding operations
            TextView songName = (TextView) view.findViewById(R.id.songname);
            TextView album = (TextView) view.findViewById(R.id.album);
            TextView duration = (TextView) view.findViewById(R.id.duration);
            songName.setText(cursor.getString(
                    cursor.getColumnIndex(MediaStore.MediaColumns.DISPLAY_NAME)
            ));
            album.setText(cursor.getString(
                    cursor.getColumnIndex(MediaStore.Audio.AlbumColumns.ALBUM)
            ));
            if(cursor.getString(cursor.getColumnIndex(
                    MediaStore.Audio.AudioColumns.DURATION
            ))!=null){
                long durationInMs = Long.parseLong(cursor.getString(
                        cursor.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION)
                ));
                int durationInMin = ((int) durationInMs / 1000) /60;
                int durationInSec = ((int) durationInMs / 1000) % 60;
                duration.setText(""+ durationInMin+ ":" +String.format("%02d",durationInSec));
                view.setTag(cursor.getString(cursor.getColumnIndex(MediaStore.MediaColumns.DATA)));
            }

        }
        @Override
        public View newView(Context context, Cursor cursor, ViewGroup parent) {
            // Inflate the view here
            LayoutInflater inflater = LayoutInflater.from(context);
            View v = inflater.inflate(R.layout.list_item,parent,false);
            bindView(v,context,cursor);
            return v;
        }

    };
}
public class ViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener {
    TextView songName, album, duration;
    View layout;
    CursorAdapter mCursorAdapter;
    LinearLayout ll;
    public ViewHolder(View itemView) {
        super(itemView);
        layout = itemView;
        songName = (TextView) itemView.findViewById(R.id.songname);
        album = (TextView) itemView.findViewById(R.id.album);
        duration = (TextView) itemView.findViewById(R.id.duration);
        ll = (LinearLayout) itemView.findViewById(R.id.playlist_item);
        ll.setOnClickListener(this);
    }
    @Override
    public void onClick(View v) {
        if(v == ll)
            clickListener.onItemClick(ll);
    }
}
@Override
public int getItemCount() {
    return mCursorAdapter.getCount();
}

@Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
    // Passing the inflater job to the cursor-adapter
    View v = mCursorAdapter.newView(mContext, mCursorAdapter.getCursor(), parent);
    return new ViewHolder(v);
}
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
    // Passing the binding operation to cursor loader
    mCursorAdapter.getCursor().moveToPosition(position); //EDITED: added this line as suggested in the comments below, thanks :)
    mCursorAdapter.bindView(holder.itemView, mContext, mCursorAdapter.getCursor());
}

}

This is the error it shows:

 FATAL EXCEPTION: main
                                                                                            Process: com.veloxigami.android.audioplayerusingservice, PID: 24341
                                                                                            java.lang.NullPointerException: Attempt to invoke interface method 'void com.veloxigami.android.audioplayerusingservice.RecyclerViewAdapter$OnItemClickListener.onItemClick(android.view.View)' on a null object reference
                                                                                                at com.veloxigami.android.audioplayerusingservice.RecyclerViewAdapter$ViewHolder.onClick(RecyclerViewAdapter.java:106)
                                                                                                at android.view.View.performClick(View.java:5207)
                                                                                                at android.view.View$PerformClick.run(View.java:21168)
                                                                                                at android.os.Handler.handleCallback(Handler.java:746)
                                                                                                at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                                at android.os.Looper.loop(Looper.java:148)
                                                                                                at android.app.ActivityThread.main(ActivityThread.java:5443)
                                                                                                at java.lang.reflect.Method.invoke(Native Method)
                                                                                                at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:728)
                                                                                                at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
Answer 1

You need to assign the listener.

You can try this since you made the Activity implement the listener.

public RecyclerViewAdapter.OnItemClickListener clickListener;
public RecyclerViewAdapter(Context context, Cursor c) {
    mContext = context;
    if (context instanceof RecyclerViewAdapter.OnItemClickListener) {
        clickListener = (RecyclerViewAdapter.OnItemClickListener) context;
    }

Also a good idea to always null-check the listener.

@Override
public void onClick(View v) {
    if(v == ll && clickListener != null)
        clickListener.onItemClick(ll);
}
Rent Charter Buses Company
READ ALSO
Learn, Share, Build

Learn, Share, Build

How can I get the data I want after the user approves the requesting permission? I know how to make the request permission, but after that, how can I take the data out of it?

229
Learn, Share, Build

Learn, Share, Build

In the below posted code, I am tring to code a utility method and I want to check if an object is null or not and a string is null and not emptyso, I coded the way shown below with throwing some exception, but I think the code could have been coded in a better...

251
Learn, Share, Build

Learn, Share, Build

I would like to use firebase to store general info on the author, submission date, and file system location (on the server)Then when the user opens the app, it will bring them to where I would curate specific photos (think IFunny, etc)

246
Learn, Share, Build

Learn, Share, Build

I would like to know if or how it is possible to contribute into a map of a parent component

239