Reputation: 401
I refer this tut http://code.tutsplus.com/tutorials/create-a-music-player-on-android-user-controls--mobile-22787 to create app to play mp3 file. But when I press back button, playback is stopped. Certainly, on onDestroy() method, I don't implement stop service like this tut.
Thanks for help.
public class MainActivity extends Activity {
//song list variables
private ArrayList<Song> songList;
private ListView songView;
//service
private MusicService musicSrv;
private Intent playIntent;
//binding
private boolean musicBound=false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//retrieve list view
songView = (ListView)findViewById(R.id.song_list);
//instantiate list
songList = new ArrayList<Song>();
//get songs from device
getSongList();
//sort alphabetically by title
Collections.sort(songList, new Comparator<Song>(){
public int compare(Song a, Song b){
return a.getTitle().compareTo(b.getTitle());
}
});
//create and set adapter
SongAdapter songAdt = new SongAdapter(this, songList);
songView.setAdapter(songAdt);
}
//connect to the service
private ServiceConnection musicConnection = new ServiceConnection(){
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
MusicBinder binder = (MusicBinder)service;
//get service
musicSrv = binder.getService();
//pass list
musicSrv.setList(songList);
musicBound = true;
}
@Override
public void onServiceDisconnected(ComponentName name) {
musicBound = false;
}
};
//start and bind the service when the activity starts
@Override
protected void onStart() {
super.onStart();
if(playIntent==null){
playIntent = new Intent(this, MusicService.class);
bindService(playIntent, musicConnection, Context.BIND_AUTO_CREATE);
startService(playIntent);
}
}
//user song select
public void songPicked(View view){
musicSrv.setSong(Integer.parseInt(view.getTag().toString()));
musicSrv.playSong();
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
//menu item selected
switch (item.getItemId()) {
case R.id.action_shuffle:
//shuffle
break;
case R.id.action_end:
stopService(playIntent);
musicSrv=null;
System.exit(0);
break;
}
return super.onOptionsItemSelected(item);
}
//method to retrieve song info from device
public void getSongList(){
//query external audio
ContentResolver musicResolver = getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
//iterate over results if valid
if(musicCursor!=null && musicCursor.moveToFirst()){
//get columns
int titleColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.TITLE);
int idColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media._ID);
int artistColumn = musicCursor.getColumnIndex
(android.provider.MediaStore.Audio.Media.ARTIST);
//add songs to list
do {
long thisId = musicCursor.getLong(idColumn);
String thisTitle = musicCursor.getString(titleColumn);
String thisArtist = musicCursor.getString(artistColumn);
songList.add(new Song(thisId, thisTitle, thisArtist));
}
while (musicCursor.moveToNext());
}
}
@Override
protected void onDestroy() {
super.onDestroy();
}
}
Music Service
public class MusicService extends Service implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener {
//media player
private MediaPlayer player;
//song list
private ArrayList<Song> songs;
//current position
private int songPosn;
//binder
private final IBinder musicBind = new MusicBinder();
public void onCreate(){
//create the service
super.onCreate();
//initialize position
songPosn=0;
//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<Song> theSongs){
songs=theSongs;
}
//binder
public class MusicBinder extends Binder {
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
Song playSong = songs.get(songPosn);
//get id
long currSong = playSong.getID();
//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){
songPosn=songIndex;
}
@Override
public void onCompletion(MediaPlayer mp) {
// TODO Auto-generated method stub
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onPrepared(MediaPlayer mp) {
//start playback
mp.start();
}
}
Upvotes: 0
Views: 4615
Reputation: 401
Good example for startforeground(): https://github.com/commonsguy/cw-android/tree/master/Notifications/FakePlayer
Good example for interact with service: http://code.tutsplus.com/tutorials/create-a-music-player-on-android-user-controls--mobile-22787
Upvotes: 1
Reputation: 401
God dang it, because the stupid snippet code
@Override
public boolean onUnbind(Intent intent){
player.stop();
player.release();
return false;
}
Upvotes: 0
Reputation: 3248
try this:
in the onStartCommand, after your codes for playing mps, return START_STICKY
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
// play mp3 code here
return START_STICKY;
}
UPDATE AFTER CODE:
You bounded your service to your play intent which is related to your activity, so when you destroy your activity, eq. press back, the service will be unBinded
simple solution will be to not bind the service to your activity, and put your services codes in the onBind
Section in the onStartCommand
and return it as START_STICKY
this way your service will continue to run in background until you call DestroySelf()
which probably should be called when the music finishes
Upvotes: 0
Reputation: 401
I realize that because I created MusicSrv in MainActivity, when Activity's destroyed MusicSrv gone. But if I do not create MusicSrv in MainActivity, how can I set list song or put MainActivity into MusicSrv to update UI.
Upvotes: 0