Nikhil
Nikhil

Reputation: 51

Service stops when activity is destroyed

I have searched a lot on stackoverflow regarding this issue but nothing seems to work.

I am developing a music player which plays music by binding to a service. I have two activities.The first activity(called as AllSongs) provides me with the list of songs.When I select a song it starts another activity(called as SongUI) which plays the song by binding to a service.

Now when I move back to my AllSongs activity the music stops.Now when I select a song again,my SongUI activity is started and when I go back to my AllSongs activity, the music does not stop and plays in the background.I am not able to understand what is causing this issue. I think I am doing something silly somewhere but am not able to figure it out. I want songs to be played in the background same as any music player does.Here is the code.

AllSongs activity:

public class AllSongs extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.allsongs_activity);

    getSongList();
    from = new String[]{MediaStore.Audio.Media.TITLE, MediaStore.Audio.Media.ARTIST, MediaStore.Audio.Media.DURATION};
    to = new int[]{R.id.title_entry,R.id.artist_entry,R.id.duration_entry};
    listView = (ListView) findViewById(R.id.listView);
    SimpleCursorAdapter adapter = new SimpleCursorAdapter(this,R.layout.singlesong,myCursor,from,to,SimpleCursorAdapter.FLAG_REGISTER_CONTENT_OBSERVER);
    listView.setAdapter(adapter);

listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            Intent songUIIntent = new Intent(getApplicationContext(),SongUI.class);             
            songUIIntent.putExtra("position",id);
            startActivity(songUIIntent);
        }
    });
}

private void getSongList() {

    ContentResolver myContentResolver = getContentResolver();
    myCursor = myContentResolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,null,null,null,null);
    if(myCursor!=null && myCursor.moveToFirst()) {
        int titleColumn = myCursor.getColumnIndex(MediaStore.Audio.Media.TITLE);           
        int idColumn = myCursor.getColumnIndex(android.provider.MediaStore.Audio.Media._ID);            
        int artistColumn = myCursor.getColumnIndex(android.provider.MediaStore.Audio.Media.ARTIST);          
        long albumID = myCursor.getLong(myCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));         

        do {
            long ID = myCursor.getLong(idColumn);              
            String title = myCursor.getString(titleColumn);             
            String artist = myCursor.getString(artistColumn);              
            songList.add(new currentSong(ID,title,artist));
        }while (myCursor.moveToNext());
    }
}

@Override
protected void onDestroy() {
        super.onDestroy();
    }
}

SongUI activity:

public class SongUI extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {

    super.onCreate(savedInstanceState);
    setContentView(R.layout.song_ui);
    button = (Button) findViewById(R.id.play);
    isBound = false;       
    Intent receivedIntent = getIntent();
    position = receivedIntent.getLongExtra("position",0);       
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.menu_main,menu);
    return super.onCreateOptionsMenu(menu);
}

public void playAudio(View view) {     
    Intent objIntent = new Intent(this,MyService.class);   
    if(!isBound)
    {          
        objIntent.putExtra("position", position);
        startService(objIntent);          
        isBound=true;
        button.setBackgroundResource(R.drawable.play);           
        bindService(objIntent, myConnection, Context.BIND_AUTO_CREATE);           
    }
    else
    {          
        myServiceObject.pauseAudio();    
        button.setBackgroundResource(R.drawable.play);
        isBound=false;         
        unbindService(myConnection);        
    }
}

public void stopAudio(View view) {     
    Intent objIntent = new Intent(this,MyService.class);    
    if(isBound)
    {         
        isBound=false;           
        unbindService(myConnection);           
        stopService(objIntent);          

    }
    else {      
        stopService(objIntent);           
    }
    button.setBackgroundResource(R.drawable.play);
}

private ServiceConnection myConnection = new ServiceConnection() {
    public void onServiceConnected(ComponentName className,
                                   IBinder service) {            
        myServiceObject = ((MusicBinder) service).getService();         
        isBound = true;
    }

    public void onServiceDisconnected(ComponentName arg0) {           
        isBound = false;
    }
};

@Override
protected void onDestroy() {       
    super.onDestroy();      
    if (isBound) {           
       unbindService(myConnection);          
        isBound = false;
    }
}

}

MyService class

 public class MyService extends Service {

@Override
public void onCreate() {
    super.onCreate();      
    player = new MediaPlayer();
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    Log.d(TAG, "on startCommand is called");
    long id = intent.getLongExtra("position",0);
    Uri contentUri = ContentUris.withAppendedId(
            android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, id);
    Log.d(TAG, "Service is Started");
    player = MediaPlayer.create(this,contentUri);      
    player.start();

    Intent notIntent = new Intent(this, SongUI.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.drawable.play)
            .setTicker(songTitle)
            .setOngoing(true)
            .setContentTitle("Playing")
            .setContentText(songTitle);
    Notification notification = builder.build();
    startForeground(NOTIFY_ID, notification);

    return Service.START_STICKY;

}
@Override
public IBinder onBind(Intent intent) {
    Log.d(TAG, "on Bind is called");
    return myBinder;
}
@Override
public boolean onUnbind(Intent intent){
    Log.d(TAG,"onUnbind is called");
    player.stop();
    player.release();
    return false;
}

public class MusicBinder extends Binder {
    MyService getService() {
        return MyService.this;
    }
}
 public void pauseAudio() {      
    if(player.isPlaying()) {         
        player.pause();
    }
}
  @Override
public void onDestroy() {
    Log.d(TAG,"on destroy is called");
    stopForeground(true);
}

Upvotes: 2

Views: 1241

Answers (1)

Nikhil
Nikhil

Reputation: 51

I have figured out where I was going wrong. I was calling unbindService(myConnection) in onDestroy of my SongsUI activity which was stopping the playback.

And the reason why this was not the case the second time round was that I was returning false in onUnbind method. So the system was not calling onBind method the second time and subsequently onUnbind was also not getting called. Hence the playback was also not stopping.

Upvotes: 1

Related Questions