Search code examples
javaandroidandroid-studioandroid-mediaplayer

MediaPlayer error: Attempt to invoke virtual method 'void android.media.MediaPlayer.start()' on a null object reference


I'm trying to make an app to play music files from the internal storage of the phone.

This is the first method where all the songs are listed in a ListView.

    public void fileSearch() {
    String[] loadSongs = {MediaStore.Audio.Media._ID, MediaStore.Audio.Media.DISPLAY_NAME};
    Cursor audioCursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, loadSongs, null, null, null);
    if (audioCursor != null) {
        if (audioCursor.moveToFirst()) {
            do {
                int audioIndex = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DISPLAY_NAME);

                audioList.add(audioCursor.getString(audioIndex));
            } while (audioCursor.moveToNext());
        }
    }
    audioCursor.close();
    ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, audioList);
    listSongs.setAdapter(adapter);
    listSongs.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            selectedSong(position);
        }
    });



}

And this method should be playing the song selected by the user in the previous list.

 public void selectedSong(int position) {
    ArrayAdapter<String> adapter = new ArrayAdapter<>(this, android.R.layout.simple_list_item_1, android.R.id.text1, audioList);
    Toast.makeText(MainActivity.this, "You  have selected the song:" + adapter.getItem(position), Toast.LENGTH_SHORT).show();
    File songSelectedPath = getFileStreamPath(adapter.getItem(position));

    Uri uri = Uri.fromFile(songSelectedPath);
    Log.d("Adapter", "AdapterToStringPath: " + uri);
    Log.d("Pointer", "Pointer: " + position);

    MediaPlayer mediaPlayer = new MediaPlayer();
    mediaPlayer = MediaPlayer.create(this,uri);
    mediaPlayer.start();
}

The error comes from this line mediaPlayer = MediaPlayer.create(this,uri);

Attempt to invoke virtual method 'void android.media.MediaPlayer.start()' on a null object reference

Solution

  • The problem is you are adding an invalid path to the MediaPlayer. To get the correct path you can use Cursor to find the name of your selected songs and get its path. in short I have to modify the signature of your method in order to send the name of the file directly without passing again by the adapter this is the method :

    public void selectedSong(String songName) {
        String[] loadSongs = {MediaStore.Audio.Media.DATA, MediaStore.Audio.Media.DISPLAY_NAME};
        String selection1 = MediaStore.Audio.Media.DISPLAY_NAME + " = ?";
        String[] selectionArgs = new String[]{songName};
        Cursor audioCursor = getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, loadSongs, selection1, selectionArgs, null);
    
        if (audioCursor != null) {
            if (audioCursor.moveToFirst()) {
                int audioIndex = audioCursor.getColumnIndexOrThrow(MediaStore.Audio.Media.DATA);
                String path = audioCursor.getString(audioIndex);
                Log.e("TAG", "selectedSong: " + path);
                Uri uri = Uri.fromFile(new File(path));
                Log.d("Adapter", "AdapterToStringPath: " + uri);
                MediaPlayer mediaPlayer = new MediaPlayer();
                Log.e("TAG", "selectedSong: " + uri);
                mediaPlayer = MediaPlayer.create(this, uri);
                mediaPlayer.start();
            }
        }
    

    and on your listener call it like below :

       listSongs.setOnItemClickListener(new AdapterView.OnItemClickListener() {
                @Override
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    selectedSong(audioList.get(position));
                }
            });
    

    The method that I have mounted above may not work correctly let's imagine we have a file of the same Name on different Folders in this case it is quite possible that you are mistaken on a file because we will get the file path from its name.

    So I suggest you create an Object which contains the Filename and the Path and add it to the list of songs, to display an item you need the Dispalyed_Name and when you click on a song you get the Path I think it's easier to do. do not hesitate to leave a comment if you did not understand what I suggested