0

I have made a list of musics and and a service to play music in background but when i click on music from list it always return null

I have never before work with music service so i maybe doing wrong here am i passing wrong position in adopter or something else?

service

public class MusicService extends Service implements
        MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
        MediaPlayer.OnCompletionListener {

    //media player
    private MediaPlayer player;
    //song list
    private ArrayList<SongModel> songs;
    //current position
    private int songPosn;
    //binder
    private final IBinder musicBind = new MusicBinder();
    //title of current song
    private String songTitle = "";
    //notification id
    private static final int NOTIFY_ID = 1;
    //shuffle flag and random
    private boolean shuffle = false;
    private Random rand;

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

    public void initMusicPlayer() {
        //set player properties
        player.setWakeMode(getApplicationContext(),
                PowerManager.PARTIAL_WAKE_LOCK);
        player.setAudioStreamType(AudioManager.STREAM_MUSIC);
        //set listeners
        player.setOnPreparedListener(this);
        player.setOnCompletionListener(this);
        player.setOnErrorListener(this);
    }

    //pass song list
    public void setList(ArrayList<SongModel> theSongs) {
        songs = theSongs;
    }

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

    //activity will bind to service
    @Override
    public IBinder onBind(Intent intent) {
        return musicBind;
    }

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

    //play a song
    public void playSong() {
        //play
        player.reset();
        //get song
        SongModel playSong = songs.get(songPosn);
        //get title
        songTitle = playSong.getSongTitle();
        //get id
        long currSong = playSong.getmSongID();
        //set uri
        Uri trackUri = ContentUris.withAppendedId(
                android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                currSong);
        //set the data source
        try {
            player.setDataSource(getApplicationContext(), trackUri);
        } catch (Exception e) {
            Log.e("MUSIC SERVICE", "Error setting data source", e);
        }
        player.prepareAsync();
    }

    //set the song
    public void setSong(int songIndex) {
        Log.e("click", " service" + songIndex);
        for (int i = 0; i < songs.size(); i++) {
            Log.e("click", songs.get(i).getArtistname() + "  " + songs.get(i).getmSongID());
        }
        songPosn = songIndex;
    }

    @Override
    public void onCompletion(MediaPlayer mp) {
        //check if playback has reached the end of a track
        if (player.getCurrentPosition() > 0) {
            mp.reset();
            playNext();
        }
    }

    @Override
    public boolean onError(MediaPlayer mp, int what, int extra) {
        Log.v("MUSIC PLAYER", "Playback Error");
        mp.reset();
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mp) {
        //start playback
        mp.start();
        //notification
        Intent notIntent = new Intent(this, MainActivity.class);
        notIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
        PendingIntent pendInt = PendingIntent.getActivity(this, 0,
                notIntent, PendingIntent.FLAG_UPDATE_CURRENT);

        Notification.Builder builder = new Notification.Builder(this);

        builder.setContentIntent(pendInt)
                .setSmallIcon(R.mipmap.ic_play_circle_filled_black_24dp)
                .setTicker(songTitle)
                .setOngoing(true)
                .setContentTitle("Playing")
                .setContentText(songTitle);
        Notification not = builder.build();
        startForeground(NOTIFY_ID, not);
    }

    //playback methods
    public int getPosn() {
        return player.getCurrentPosition();
    }

    public int getDur() {
        return player.getDuration();
    }

    public boolean isPng() {
        return player.isPlaying();
    }

    public void pausePlayer() {
        player.pause();
    }

    public void seek(int posn) {
        player.seekTo(posn);
    }

    public void go() {
        player.start();
    }

    //skip to previous track
    public void playPrev() {
        songPosn--;
        if (songPosn < 0) songPosn = songs.size() - 1;
        playSong();
    }

    //skip to next
    public void playNext() {
        if (shuffle) {
            int newSong = songPosn;
            while (newSong == songPosn) {
                newSong = rand.nextInt(songs.size());
            }
            songPosn = newSong;
        } else {
            songPosn++;
            if (songPosn >= songs.size()) songPosn = 0;
        }
        playSong();
    }

    @Override
    public void onDestroy() {
        stopForeground(true);
    }

    //toggle shuffle
    public void setShuffle() {
        if (shuffle) shuffle = false;
        else shuffle = true;
    }}

activity class

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

    public static ArrayList<SongModel> songList;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        load();
    @Override
    protected void onStart() {
        super.onStart();
        if(playIntent==null){
            playIntent = new Intent(this, MusicService.class);
            bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
            startService(playIntent);
        }
    }

private ServiceConnection musicConnection = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        MusicService.MusicBinder binder = (MusicService.MusicBinder) service;
        //get service
        musicSrv = binder.getService();
        //pass list
        musicSrv.setList(songList);
        musicBound = true;
    }

    @Override
    public void onServiceDisconnected(ComponentName name) {
        musicBound = false;
    }
};

    private void initLayout() {
        final Uri uri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
        final String[] cursor_cols = {MediaStore.Audio.Media._ID,
                MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.ALBUM,
                MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.DATA,
                MediaStore.Audio.Media.ALBUM_ID,
                MediaStore.Audio.Media.DURATION};
        final String where = MediaStore.Audio.Media.IS_MUSIC + "=1";
        final Cursor cursor = getContentResolver().query(uri,
                cursor_cols, where, null, null);


        while (cursor.moveToNext()) {
            String artist = cursor.getString(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.ARTIST));
            String album = cursor.getString(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM));
            String track = cursor.getString(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.TITLE));
            String data = cursor.getString(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));
            Long albumId = cursor.getLong(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.ALBUM_ID));

            int duration = cursor.getInt(cursor
                    .getColumnIndexOrThrow(MediaStore.Audio.Media.DURATION));

            Uri sArtworkUri = Uri
                    .parse("content://media/external/audio/albumart");
            Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, albumId);

            Log.e("art", albumArtUri.toString());
            /*Bitmap bitmap = null;
            try {
                bitmap = MediaStore.Images.Media.getBitmap(
                        getActivity().getContentResolver(), albumArtUri);
                bitmap = Bitmap.createScaledBitmap(bitmap, 30, 30, true);

            } catch (FileNotFoundException exception) {
                exception.printStackTrace();
                bitmap = BitmapFactory.decodeResource(getActivity().getResources(),
                        R.mipmap.ic_music_note_black_24dp);
            } catch (IOException e) {

                e.printStackTrace();
            }*/

            SongModel audioListModel = new SongModel();
            audioListModel.setArtistname(artist);
            //  audioListModel.setBitmap(bitmap);
            audioListModel.setmSongTitle(album);
            audioListModel.setmSongTitle(track);
            audioListModel.setData(data);
            audioListModel.setmSongID(albumId);
            audioListModel.setSongLength(String.valueOf(duration));
            audioListModel.setUri(String.valueOf(albumArtUri));
            Log.e("data", "artist :" + artist + "  album  " + album + "  track  " + track + "  data  " + data + "  " + "albumId  " + albumId
                    + "  " + "duration  " + duration + " art:  " + albumArtUri);

            songList.add(audioListModel);

        }

    }


    private class GetAudioListAsynkTask extends AsyncTask<Void, Void, Boolean> {

        private Context context;

        public GetAudioListAsynkTask(Context context) {

            this.context = context;
        }

        @Override
        protected void onPreExecute() {
            super.onPreExecute();

        }

        @Override
        protected Boolean doInBackground(Void... params) {
            try {
                initLayout();

                return true;
            } catch (Exception e) {
                return false;

            }

        }

        @Override
        protected void onPostExecute(Boolean result) {
            Collections.sort(songList, new Comparator<SongModel>() {
                public int compare(SongModel a, SongModel b) {
                    return a.getSongTitle().compareTo(b.getSongTitle());
                }
            });

        }
    }

    public void load() {
        songList = new ArrayList<>();
        new GetAudioListAsynkTask(this).execute((Void) null);


    }

adapter class

@Override
public void onBindViewHolder(final Holder holder, final int position) {
    final SongModel songModel = list.get(holder.getAdapterPosition());
    Glide.with(holder.itemView.getContext()).load(songModel.getUri()).error(R.mipmap.ic_music_note_black_24dp).into(holder.imageView);
    holder.imageView.setImageURI(Uri.parse(songModel.getUri()));
    holder.artistname.setText(songModel.getArtistname());
    holder.duration.setText(songModel.getSongLength());
    holder.songname.setText(songModel.getSongTitle());
    holder.itemView.setTag(position);

    holder.itemView.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            songPicked(position);
        }
    });


}
 private void songPicked(int position) {
    musicSrv.setSong(position);
    musicSrv.playSong();
}

error log

    04-21 19:01:37.847 3983-29870/? E/DatabaseUtils: Writing exception to parcel
                                                 java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media/1 from pid=2608, uid=1000 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()
                                                     at android.content.ContentProvider.enforceReadPermissionInner(ContentProvider.java:646)
                                                     at android.content.ContentProvider$Transport.enforceReadPermission(ContentProvider.java:493)
                                                     at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:484)
                                                     at android.content.ContentProvider$Transport.openFile(ContentProvider.java:380)
                                                     at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:240)
                                                     at android.os.Binder.execTransact(Binder.java:453)


                                                 [ 04-21 19:01:37.847  2264:16266 D/         ]
                                                 openContentUri(content://media/external/audio/media/1) caught exception -1
04-21 19:01:37.847 2264-16266/? E/MediaPlayerService: Couldn't open fd for content://media/external/audio/media/1
04-21 19:01:37.847 19273-19273/? E/MediaPlayer: Unable to create media player
04-21 19:01:37.847 19273-19273/? E/MUSIC SERVICE: Error setting data source
                                                  java.io.IOException: setDataSource failed.: status=0x80000000
                                                      at android.media.MediaPlayer.nativeSetDataSource(Native Method)
                                                      at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1231)
                                                      at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1215)
                                                      at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1169)
                                                      at android.media.MediaPlayer.setDataSource(MediaPlayer.java:1105)
                                                      at com.nowsip.musicplayer.service.MusicService.playSong(MusicService.java:118)
                                                      at com.nowsip.musicplayer.adapter.SongAdapter.songPicked(SongAdapter.java:86)
                                                      at com.nowsip.musicplayer.adapter.SongAdapter.access$000(SongAdapter.java:24)
                                                      at com.nowsip.musicplayer.adapter.SongAdapter$1.onClick(SongAdapter.java:52)
                                                      at android.view.View.performClick(View.java:5721)
                                                      at android.view.View$PerformClick.run(View.java:22620)
                                                      at android.os.Handler.handleCallback(Handler.java:739)
                                                      at android.os.Handler.dispatchMessage(Handler.java:95)
                                                      at android.os.Looper.loop(Looper.java:148)
                                                      at android.app.ActivityThread.main(ActivityThread.java:7409)
                                                      at java.lang.reflect.Method.invoke(Native Method)
                                                      at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                      at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
04-21 19:01:37.847 19273-19273/? E/MediaPlayer: prepareAsync called in state 1
04-21 19:01:37.847 19273-19273/? E/AndroidRuntime: FATAL EXCEPTION: main
                                                   Process: com.nowsip.musicplayer, PID: 19273
                                                   java.lang.IllegalStateException
                                                       at android.media.MediaPlayer.prepareAsync(Native Method)
                                                       at com.nowsip.musicplayer.service.MusicService.playSong(MusicService.java:122)
                                                       at com.nowsip.musicplayer.adapter.SongAdapter.songPicked(SongAdapter.java:86)
                                                       at com.nowsip.musicplayer.adapter.SongAdapter.access$000(SongAdapter.java:24)
                                                       at com.nowsip.musicplayer.adapter.SongAdapter$1.onClick(SongAdapter.java:52)
                                                       at android.view.View.performClick(View.java:5721)
                                                       at android.view.View$PerformClick.run(View.java:22620)
                                                       at android.os.Handler.handleCallback(Handler.java:739)
                                                       at android.os.Handler.dispatchMessage(Handler.java:95)
                                                       at android.os.Looper.loop(Looper.java:148)
                                                       at android.app.ActivityThread.main(ActivityThread.java:7409)
                                                       at java.lang.reflect.Method.invoke(Native Method)
                                                       at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
                                                       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)
04-21 19:01:37.887 19790-19790/? E/Zygote: v2
04-21 19:01:37.887 2608-19795/? E/android.os.Debug: ro.product_ship = true
04-21 19:01:37.887 2608-19795/? E/android.os.Debug: ro.debug_level = 0x4f4c
04-21 19:01:37.887 2608-19795/? E/android.os.Debug: sys.mobilecare.preload = false
04-21 19:01:37.897 19790-19790/? E/Zygote: accessInfo : 0
04-21 19:01:37.897 2608-2803/? E/Qmage: isQIO : stream is not a QIO file
04-21 19:01:38.457 11589-11589/? E/Qmage: isQIO : stream is not a QIO file
04-21 19:01:38.497 11589-11589/? E/Qmage: isQIO : stream is not a QIO file
04-21 19:01:38.497 11589-11589/? E/Qmage: isQIO : stream is not a QIO file
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
androidpie
  • 55
  • 1
  • 8

2 Answers2

0

Confirm that when your onServiceConnected method called and you set song list in your service, at that time your songList is prapared or not ?

I mean your song list may be null when you call below line.

    //pass list
    musicSrv.setList(songList);

In case of when service is connected before your initLayout method completed.

Update

According to below line of error logs you need to add READ_EXTERNAL_STORAGE permission in your manifest file.

java.lang.SecurityException: Permission Denial: reading com.android.providers.media.MediaProvider uri content://media/external/audio/media/1 from pid=2608, uid=1000 requires android.permission.READ_EXTERNAL_STORAGE, or grantUriPermission()

Set data source using file FileDescriptor:

//play a song
public void playSong() {
    //play
    player.reset();
    //get song
    SongModel playSong = songs.get(songPosn);
    //get title
    songTitle = playSong.getSongTitle();
    //get id
    long currSong = playSong.getmSongID();
    //set uri
    Uri trackUri = ContentUris.withAppendedId(
            android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
            currSong);
    //set the data source
    try {
        String filePath = getPathFromContentUri(context, trackUri);
        File file = new File(filePath);
        FileInputStream inputStream = new FileInputStream(file);    
        player.setDataSource(inputStream.getFD());
        inputStream.close();
    } catch (Exception e) {
        Log.e("MUSIC SERVICE", "Error setting data source", e);
    }
    player.prepareAsync();
}


public static String getPathFromContentUri(Context context, Uri contentUri) {
    String[] proj = { MediaStore.Audio.Media.DATA };
    Cursor cursor = context.getContentResolver().query(contentUri,
            proj, null, null, null);
    cursor.moveToFirst();

    String path = cursor.getString(cursor
            .getColumnIndexOrThrow(MediaStore.Audio.Media.DATA));

    cursor.close();
    return path;
}

Checkout this answer for more information. It might be helpful to you.

Community
  • 1
  • 1
Priyank Patel
  • 12,244
  • 8
  • 65
  • 85
0

That is not music service problem that is Permission problem

First you need to give service name to android manifest like

After that if you running 6.0 or more then you need to ask permission for user to write an read external storage when first time running application in lollipop or kit kat or other that give permission at installation time but in marshmallow or more you give to manually to ask user

check this out Storage permission error in Marshmallow

Jigar Fumakiya
  • 2,039
  • 1
  • 8
  • 21