0

I'm trying to create an app that plays an audio file when a button, on a specific item of a RecyclerView, is clicked. The first item, actually. I'm trying to do it in the most efficient way.

So far, I'm trying to store the path to the file (R.raw.something) in a Arraylist with a custom Class I created. I just want to play the audio from the first item in the recyclerView.

// Here's the function I call to add items to the list

public void getSongsContent(){
        if (mExampleList.size()==0){
            mExampleList.add(new ExampleItems("The Lion Sleeps Tonight", "Meme Community",R.raw.thelionsleepstonight ));
            mExampleList.add(new ExampleItems("And I Oop!", "Jasmine Master",R.raw.andioop ));
            mExampleList.add(new ExampleItems("Hoes Mad!","Famous Dex" ,R.raw.hoesmad ));
        }

    }
// Here's the ExampleItems class

public class ExampleItems {
    private String mNameoftheSong;
    private String mNameoftheArtists;
    private int mSongPath;

    public ExampleItems(String NameoftheSong, String NameoftheArtists, int PathofTheSong){
        mNameoftheSong = NameoftheSong;
        mSongPath = PathofTheSong;
        mNameoftheArtists = NameoftheArtists;
    }
    public String getNameoftheSong(){
        return mNameoftheSong;
    }
    public String getNameoftheArtists(){
        return mNameoftheArtists;
    }
    public int getPathtoTheSong(){
        return mSongPath;
    }
}
// And Here's the playAudio function which makes the app crash.

private void playAudio(){
        int path = mExampleList.get(0).getPathtoTheSong();
        if (player==null){
            player = MediaPlayer.create(this,path );
            player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    stopPlayer();
                }
            });
        }
        player.start();
    }

I'm expecting the correct audio to be played depending on which Item I have put first in the recyclerView. I have seen on another post that it is not possible to store any ressource paths into an Arraylist, and that I should probably move the files to the "/Assets" Right now, the app crashes when the button is pressed. How can I fix this?

Here's the stack trace:

E/AndroidRuntime: FATAL EXCEPTION: main
    Process: com.awolobes.pavilion.wavedrop, PID: 25947
    android.content.res.Resources$NotFoundException: Resource ID #0x0
        at android.content.res.ResourcesImpl.getValue(ResourcesImpl.java:190)
        at android.content.res.ResourcesImpl.openRawResourceFd(ResourcesImpl.java:287)
        at android.content.res.Resources.openRawResourceFd(Resources.java:1446)
        at android.media.MediaPlayer.create(MediaPlayer.java:941)
        at android.media.MediaPlayer.create(MediaPlayer.java:924)
        at com.awolobes.pavilion.wavedrop.MainActivity.playAudio(MainActivity.java:112)
        at com.awolobes.pavilion.wavedrop.MainActivity.access$400(MainActivity.java:22)
        at com.awolobes.pavilion.wavedrop.MainActivity$5.onButtonClick(MainActivity.java:145)
        at com.awolobes.pavilion.wavedrop.RecyclerViewAdapter$PinnedViewHolder$1.onClick(RecyclerViewAdapter.java:61)
        at android.view.View.performClick(View.java:5675)
        at android.view.View$PerformClick.run(View.java:22641)
        at android.os.Handler.handleCallback(Handler.java:836)
        at android.os.Handler.dispatchMessage(Handler.java:103)
        at android.os.Looper.loop(Looper.java:203)
        at android.app.ActivityThread.main(ActivityThread.java:6251)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1063)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:924)

Finally, here's the entire MainActivity.java

public class MainActivity extends AppCompatActivity {

    MediaPlayer player;
    // RecyclerView Variables
    private ArrayList<ExampleItems> mExampleList;
    private RecyclerView mRecylerView;
    private RecyclerViewAdapter mAdapter;
    private RecyclerView.LayoutManager mLayoutManager;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        loadData();
        setContentView(R.layout.activity_main);
        getSongsContent();
        createRecyclerView();
    }

    @Override
    protected void onPause() {
        super.onPause();
        saveData();
    }

    public void getSongsContent(){
        if (mExampleList.size()==0){
            mExampleList.add(new ExampleItems("The Lion Sleeps Tonight", "Meme Community",R.raw.thelionsleepstonight ));
            mExampleList.add(new ExampleItems("And I Oop!", "Jasmine Master",R.raw.andioop ));
            mExampleList.add(new ExampleItems("Hoes Mad!","Famous Dex" ,R.raw.hoesmad ));
        }

    }
    private void saveData(){
        SharedPreferences sharedPreferences = getSharedPreferences("shared preferences",MODE_PRIVATE );
        SharedPreferences.Editor editor = sharedPreferences.edit();
        Gson gson = new Gson();
        String json = gson.toJson(mExampleList);
        editor.putString("State",json );
        editor.apply();
    }
    private void loadData(){
        SharedPreferences sharedPreferences = getSharedPreferences("shared preferences",MODE_PRIVATE );
        Gson gson = new Gson();
        String json = sharedPreferences.getString("State",null );
        Type type = new TypeToken<ArrayList<ExampleItems>>() {}.getType();
        mExampleList = gson.fromJson(json,type );

        if (mExampleList == null){
            mExampleList = new ArrayList<>();
        }
    }
    private void playAudio(){
        int path = mExampleList.get(0).getPathtoTheSong();
        if (player==null){
            player = MediaPlayer.create(this,path );
            player.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                @Override
                public void onCompletion(MediaPlayer mp) {
                    stopPlayer();
                }
            });
        }
        player.start();
    }
    private void stopPlayer(){
        if (player != null){
            player.release();
            player = null;
        }
    }
    public void createRecyclerView(){
        mRecylerView = findViewById(R.id.Recyclerview);
        mRecylerView.setHasFixedSize(true);
        mLayoutManager = new LinearLayoutManager(this);
        mAdapter = new RecyclerViewAdapter(mExampleList);
        mRecylerView.setLayoutManager(mLayoutManager);
        mRecylerView.setAdapter(mAdapter);

        mAdapter.setOnitemClickListener(new RecyclerViewAdapter.OnItemClickListener() {
            @Override
            public void onItemClick(int position) {
                swapData(position);

            }

            @Override
            public void onButtonClick(int position) {
                playAudio();
            }
        });

    }
    public void swapData(int position){
        mExampleList.add(0,mExampleList.remove(position));
        mAdapter.notifyItemMoved(position,0 );
    }
}

I hope it can help.

Ricochet
  • 65
  • 1
  • 8
  • Please [edit] your question to provide the complete [stack trace from the crash](https://stackoverflow.com/a/23353174). – Mike M. Aug 26 '19 at 11:59
  • It would seem that you're somehow creating an `ExampleItems` with a `PathofTheSong` value of `0`. I don't see it in this code, though. Are you sure that you're not adding `ExampleItems` to `mExampleList` somewhere else, too? – Mike M. Aug 26 '19 at 13:29
  • I am not adding ExampleItems to mExampleList somewhere else. I've provided the entire MainActivity.java to clarify. – Ricochet Aug 28 '19 at 09:38
  • You kinda are, with the Gson load. What happens if you temporarily change the `loadData()` method to be just `mExampleList = new ArrayList<>();`? – Mike M. Aug 28 '19 at 09:49
  • It works. Thank you. Is there a way to modify the `loadData()` method so I can keep it in the code? I'm new to Android Studio and still have trouble understanding everything. Especially serialization. – Ricochet Aug 28 '19 at 11:20
  • 1
    Your posted code works just fine for me, as far as the Gson stuff. I'm guessing that you might've previously saved some different song list, maybe one with some test items that didn't have a valid path value, and that's what is getting loaded. Try clearing out your app's data. There are a couple of ways: open the device Settings, go to your app's page, and select the "Clear data" option (it might under a submenu, like "Storage"), or you can just uninstall and reinstall your app. – Mike M. Aug 28 '19 at 12:05
  • 1
    Everything's working fine now. Thank you a lot. – Ricochet Aug 28 '19 at 12:20

0 Answers0