2

I have a IntentService that queries the MediaStore to get songs, albums, artist, whatnot. that way if someone tries to add an entire artist and there are a lot of albums the IntentService can do the expensive operations of getting all the albums from an artist, then looping through them to get all the songs from each album and it won't take up the ui so the app can still function. My problem/question is, is there a way to send results multiple times from the same service call?

Example: Someone clicks on an artist. That starts the IntentService with the artist_id and the IntentService starts doing its work. What I would like to have happen is, the IntentService gets the first album, then the first song and sends that result back, but it also continues to process the rest of the albums and songs, then when that is done it sends them all back. I don't know if that makes sense or not, so here is an example of my current setup...

BaseActivity...

public GetSongsReceiver receiver;
public GetSongsReceiver.Receiver returnReceiver = new GetSongsReceiver.Receiver() {
  @Override
  public void onReceiveResult(int resultCode, Bundle resultData) {
    if(resultCode == RESULT_OK) {
      ArrayList<Song> songs = resultData.getParcelableArrayList("songs");
        if(songs != null && songs.size() > 0) {
            if(musicBound) {
              musicService.addAllSongs(songs);
              musicService.playSong();
            }
        }
    }
};
...
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    //processing and such.
    if(musicBound) {
      musicService.setPlayType(MusicService.PlayType.ARTIST);
      Intent i = new Intent(BaseActivity.this, GetPlaylistItemsService.class);
      Bundle extras = new Bundle();
      extras.putParcelable("key", data.getParcelableExtra("artist"));
      extras.putString("service_type", "artist");
      extras.putParcelable("receiver", returnReceiver);
      i.putExtras(extras);
      startService(i);
    }
}

GetPlaylistItemsService...

@Override
protected void onHandleIntent(Intent intent) {
  ResultReceiver rec = intent.getParcelableExtra("receiver");
  Artist artist = intent.getParcelableExtra("key");
  ArrayList<Album> albums = getAlbumsFromArtist(artist);
  ArrayList<Song> songs = new ArrayList<>();
  for(Album album : albums) {
    songs.addAll(getSongsFromAlbum(album);
  }
  Bundle extras = new Bundle();
  extras.putParcelableArrayList("songs", songs);
  rec.send(Activity.RESULT_OK, extras);
}

What I would like to be able to do is have the "rec.send..." send more than one time. That way I can get the first album and first song, send that result back so the media player can start playing it, then process the rest in the background and add them when they are finished. That would mean the IntentService would need to be able to rec.send more than once. Is that possible or do I need to break this into 2 different IntentService calls, one to get the first item and then another to get the rest?

Neglected Sanity
  • 1,770
  • 6
  • 23
  • 46

1 Answers1

1

it won't take up the ui so the app can still function

You do not need an IntentService for this. An ordinary background thread (perhaps tied to a LiveData), AsyncTask, RxJava chain, etc. can handle this.

That would mean the IntentService would need to be able to rec.send more than once. Is that possible

Sure. It would be more efficient to use an ordinary background thread, AsyncTask, RxJava chain, etc. But, you should be able to send() as many times as you like. The results will be handed to onReceiveResult() one at a time (i.e., you call send() 6 times, you get 6 onReceiveResult() calls).

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • Beautiful. Thank you. I thought about doing it as an AsyncTask. I have used them in the past, but I was thinking the IntentService would also allow my app to be updated in the future to include things like MediaScanner complete events and such. So my app can automatically update when certain things happen outside my app as well. – Neglected Sanity Jul 13 '18 at 23:09
  • @NeglectedSanity: It is possible that your proposed scenario better justifies the `IntentService`, but I am still skeptical. Regardless, you may as well get it working with what you have, and you can consider possible changes down the road if your current approach gets too complicated. – CommonsWare Jul 13 '18 at 23:10