public class MusicPlayerService extends Service{
    public static final int CMD_START = 0;
    public static final int CMD_PAUSE = 1;
    public static final int CMD_STOP = 2;
    public static final int CMD_RESUME = 3;
    public static final int CMD_NEXT = 4;
    public static final int CMD_PREV = 5;
    public static final int CMD_SEEK = 6;
    public static final int CMD_JUMP = 7;
    
    public static final int CMD_REFRESH = 8;
   
    //播放状态,播放、暂停、停止
    public static final int STATUS_PLAYING = 0;
    public static final int STATUS_PAUSED = 1;
    public static final int STATUS_STOPPED = 2;
    public static final int STATUS_REFRESH = 3;
    
    public static final String MUSIC_CONTROL = "MusicPlayerActivity.ACTION_CONTROL";
    public static final String UPDATE_STATUS = "MusicPlayerActivity.ACTION_UPDATE_STATUS";
    public static final String UPDATE_TIME = "MusicPlayerActivity.ACTION_UPDATE_TIME";
    public static final String UPDATE_INFO = "MusicPlayerActivity.ACTION_UPDATE_INFO";
    
    //public static final String MUSIC_REFRESH = "MusicPlayerActivity.ACTION_CONTROL";    public static final String PREF = "NOW_PLAYING";
    
    private File file = null;
    private MediaPlayer mp;
    private int status;
    //播放状态接收器
    private CommandReceiver doCommand;
    
    //播放模式接收器
    private PlayModeReceiver doPlayMode;
    
    private Cursor c;
    private ContentResolver resolver;
    private SharedPreferences sp;
    private Uri nowPlaying;
    private CharSequence title;
    private CharSequence artist;
    private CharSequence album;
    
    private int _id;
    
    private int duration;
    private int current = 0;
    private Thread thr;
    private boolean endthr = false;
    private NotificationManager nMgr;
    
    public class CommandReceiver extends BroadcastReceiver{ @Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
switch(intent.getIntExtra("cmd", -1)){
case CMD_START:
play(context);
break;
case CMD_PAUSE:
mp.pause();
status = STATUS_PAUSED;
updateStatus();
nMgr.cancel(1);
saveStatus();
break;
case CMD_STOP:
if(status != STATUS_STOPPED)
stop();
break;
case CMD_RESUME:
mp.start();
status = STATUS_PLAYING;
updateStatus();
showNotification(1);
break;
case CMD_PREV:
if(c.isFirst())
c.moveToLast();
else
c.moveToPrevious();

changeSong();
play(context);
break;
case CMD_NEXT:
if(c.isLast())
c.moveToFirst();
else
c.moveToNext(); changeSong();
play(context);
break;
case CMD_SEEK:
current = (intent.getIntExtra("progress", 0))*duration / 100;
if(status != STATUS_STOPPED)
mp.seekTo(current);
break;
case CMD_JUMP:
c.moveToPosition(intent.getIntExtra("pos", -1));
changeSong();
play(context);
break;
case CMD_REFRESH:
//这里接收删除通知 break;

default:
updateStatus();
updateInfo();
updateTime();
break;
}
}
    }
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate() {
// TODO Auto-generated method stub
super.onCreate();
mp = new MediaPlayer();
resolver = getContentResolver();
c = resolver.query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI, 
null, null, null, null);
c.moveToFirst();
sp = getSharedPreferences(PREF, 0); int state_position = sp.getInt("key",-1);
if(state_position != -1){
c.moveToPosition(state_position);
}
changeSong();
status = sp.getInt("status", STATUS_STOPPED);
updateStatus();
if(status == STATUS_PAUSED){
current = sp.getInt("time", 0);
prepare(this);
}
//注册Receiver
doCommand = new CommandReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(MUSIC_CONTROL);
registerReceiver(doCommand, filter);
doPlayMode = new PlayModeReceiver();
IntentFilter filter1 = new IntentFilter();
filter1.addAction("com.genny.play_mode");
registerReceiver(doPlayMode, filter1);
} @Override
public void onDestroy() {
// TODO Auto-generated method stub
//解除Receiver
unregisterReceiver(doCommand);
unregisterReceiver(doPlayMode); super.onDestroy();
System.out.println("退出Service");
}

//保存状态
private void saveStatus(){
SharedPreferences.Editor editor = sp.edit();
editor.putInt("key", c.getPosition());
editor.putInt("time", current);
editor.putInt("status", status);
editor.commit();
}
    }
//更新歌曲信息    private void changeSong(){
     /*通过_ID来获取歌曲位置,哪怕断续得再厉害也不怕连接不上了*/
     _id = c.getColumnIndex(MediaStore.Audio.AudioColumns._ID);
        nowPlaying = Uri.withAppendedPath(
                MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
                "/"+c.getString(_id));        Cursor c = resolver.query(nowPlaying, null, null, null, null);
        
        int titleIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.TITLE);
        int artistIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.ARTIST);
        int albumIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.ALBUM);
        int durationIndex = c.getColumnIndex(MediaStore.Audio.AudioColumns.DURATION);
        if (c.getCount() != 0) {
            c.moveToFirst();
            title = c.getString(titleIndex);
            artist = c.getString(artistIndex);
            album = c.getString(albumIndex);
            duration = c.getInt(durationIndex);
        }
        
        updateInfo();
    }  //发送更新的播放状态    private void updateStatus(){
        Intent i = new Intent(UPDATE_STATUS);
        i.putExtra("status", status);
        sendBroadcast(i);
    }  //发送更新的歌曲信息    private void updateInfo(){
        Intent i = new Intent(UPDATE_INFO);
        i.putExtra("title", title);
        i.putExtra("artist", artist);
        i.putExtra("album", album);
        i.putExtra("duration", duration);
        sendBroadcast(i);
    }  //发送跟新的播放时间    private void updateTime(){
        Intent i = new Intent(UPDATE_TIME);
        i.putExtra("current", current);
        i.putExtra("duration", duration);
        sendBroadcast(i);
    }    private void stop(){
        endthr = true;
        try {
               thr.join();
           } catch (InterruptedException e) {
               // TODO Auto-generated catch block
               e.printStackTrace();
           }
           endthr = false;
           mp.stop();
           mp.release();
           status = STATUS_STOPPED;
           updateStatus();
           nMgr.cancel(1);
           current = 0;
           //saveStatus();
        }    private void prepare(Context context){
        mp = MediaPlayer.create(context,nowPlaying);
        mp.seekTo(current);      
        //每隔一段时间更新已播放时间
        thr = new Thread(new Runnable() {        
           @Override
           public void run() {
              // TODO Auto-generated method stub
              while(endthr != true){
                  if(status == STATUS_PLAYING){
                     current = mp.getCurrentPosition();
                     updateTime();
                  }
                  try {
                     Thread.sleep(100);
                  } catch (InterruptedException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
                  }
              }
           }
       });
        thr.start();       
        //歌曲播放完毕发出播放下一首的命令
        mp.setOnCompletionListener(new OnCompletionListener() {         
           @Override
           public void onCompletion(MediaPlayer arg0) {
              // TODO Auto-generated method stub            Intent i = new Intent(MusicPlayerService.MUSIC_CONTROL);
            i.putExtra("cmd", MusicPlayerService.CMD_NEXT);
           }
       });
    }    private void play(Context context){
        if(status != STATUS_STOPPED){
         stop();
        }
        prepare(context);
        mp.start();
        status = STATUS_PLAYING;
        updateStatus();
        showNotification(1);       
    }
}以上是我用于播放音乐的service。在列表ListActivity中执行了删除命令,在上面service的红色部分能够接收到删除通知,我的问题是:如何在service中更新Cursor呢?
以下是ListActivity的删除代码
private void delete(){
   file = new File(_path[index]);
if(file.exists()){
file.delete();
}
//刷新listview
Cursor c2 = this.getContentResolver().query(MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
null, null, null, null);
adapter = new SimpleCursorAdapter(this, R.layout.listitem, c2, 
new String[]{MediaStore.Audio.AudioColumns.TITLE,
MediaStore.Audio.AudioColumns.ARTIST}, 
new int[]{R.id.music, R.id.songer});

adapter.notifyDataSetChanged();
scanSdCard();
//通知service
startService(new Intent(this,MusicPlayerService.class));
Intent i = new Intent(MusicPlayerService.MUSIC_CONTROL);
i.putExtra("cmd", MusicPlayerService.CMD_REFRESH);
i.putExtra("pos", index);
sendBroadcast(i);
   }
小弟新手,求大鸟指教。谢谢!

解决方案 »

  1.   

    以上是我用于播放音乐的service。在列表ListActivity中执行了删除命令,在上面service的红色部分能够接收到删除通知,我的问题是:如何在service中更新Cursor呢?
    以下是ListActivity的删除代码
    service的红色部分能够接收到删除通知,红色部分在哪?
      

  2.   

    public class CommandReceiver extends BroadcastReceiver{        @Override
            public void onReceive(Context context, Intent intent) {
                // TODO Auto-generated method stub
                switch(intent.getIntExtra("cmd", -1)){
                case CMD_START:
                    play(context);
                    break;
                case CMD_PAUSE:
                    mp.pause();
                    status = STATUS_PAUSED;
                    updateStatus();
                    nMgr.cancel(1);
                    saveStatus();
                    break;
                case CMD_STOP:
                    if(status != STATUS_STOPPED)
                        stop();
                    break;
                case CMD_RESUME:
                    mp.start();
                    status = STATUS_PLAYING;
                    updateStatus();
                    showNotification(1);
                    break;
                case CMD_PREV:
                    if(c.isFirst())
                        c.moveToLast();
                    else
                        c.moveToPrevious();
                    
                    changeSong();
                    play(context);
                    break;
                case CMD_NEXT:
                    if(c.isLast())
                        c.moveToFirst();
                    else
                        c.moveToNext();                changeSong();
                    play(context);
                    break;
                case CMD_SEEK:
                    current = (intent.getIntExtra("progress", 0))*duration / 100;
                    if(status != STATUS_STOPPED)
                        mp.seekTo(current);
                    break;
                case CMD_JUMP:
                    c.moveToPosition(intent.getIntExtra("pos", -1));
                    changeSong();
                    play(context);
                    break;
                case CMD_REFRESH:
                    //这里接收删除通知                break;

                    default:
                        updateStatus();
                        updateInfo();
                        updateTime();
                        break;
                }
            }
        }
    不好意思,插入代码没有显示文字颜色,“//这里接收删除通知”,是在CMD_REFRESH这个case里面
      

  3.   

    可以用handler更新你要的信息。
      

  4.   

      貌似不必那么麻烦  在service中的代码本来就是在ui主线程中运行的。  想这样的你要定义广播 或者将service和Activity绑定  把你的播放代码写到一个接口中  在service中返回的ibander对象要实现播放接口。  在Activity中就可以调用ibander对象来操作service中的方法了