我有一个服务,它传递了一组变量(歌曲、艺术家专辑等),包括一个 MediaPlayer,以及该 MediaPlayer 的一堆方法(播放下一个、上一个等)。
我还有一个活动,它向用户显示 UI,包括下一个/上一个按钮、一个搜索栏和艺术家/专辑/歌曲的显示。
我想知道的是如何让 UI 活动对服务进行更改,以及如何让服务根据选择的歌曲更新活动。
例如:艺术家/专辑/歌曲组合被发送到服务。该服务告诉 MediaPlayer 开始播放该歌曲。歌曲名称/专辑/艺术家显示在活动中,用户可以在 UI 中按播放/暂停等。点击后,服务将采取相应的行动。
我不知道如何让所有这些事情发生,我正忙于广播、意图和静态。我真的很感激一些明确的指导,以及如何做到这一点的一个很好的例子。
感谢您的耐心和帮助。
请在下面找到代码:
音乐服务.java:
package awesome.music.player;
import java.io.IOException;
import java.util.ArrayList;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.ContentUris;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
public class MusicService extends Service implements OnCompletionListener,
OnSeekCompleteListener {
Intent intent;
MediaPlayer mediaPlayer = new MediaPlayer();
String isComplete;
String serviceStatus;
String sntSeekPos;
String artist;
String selection;
String album;
String numSongs;
int albumId;
String currentSongPath;
String[] selectionArgs;
Uri currentSongUri;
int songEnded;
int currentSongIndex;
int totalSongDuration;
int intSeekPos;
int mediaPosition;
int mediaMax;
ArrayList<String> pathList;
ArrayList<String> artistList;
ArrayList<String> albumList;
ArrayList<String> titleList;
ArrayList<String> idList;
ArrayList<String> durationList;
private final Handler handler = new Handler();
public final String BROADCAST_ACTION = "awesome.music.player.seekprogress";
public final String BROADCAST_OTHER = "awesome.music.player.displaysong";
Intent seekIntent;
Intent displayIntent;
Utilities utils;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
this.intent = intent;
Bundle extras = intent.getExtras();
artist = extras.getString("artist");
selection = extras.getString("selection");
selectionArgs = extras.getStringArray("selectionArgs");
album = extras.getString("album");
albumId = extras.getInt("albumId");
numSongs = extras.getString("numSongs");
currentSongIndex = extras.getInt("currentSongIndex");
currentSongPath = extras.getString("currentSongPath");
totalSongDuration = extras.getInt("totalSongDuration");
pathList = extras.getStringArrayList("pathList");
artistList = extras.getStringArrayList("artistList");
albumList = extras.getStringArrayList("albumList");
titleList = extras.getStringArrayList("titleList");
idList = extras.getStringArrayList("idList");
durationList = extras.getStringArrayList("durationList");
prepareSong(currentSongPath);
playSong();
displaySong();
utils = new Utilities();
seekIntent = new Intent(BROADCAST_ACTION);
displayIntent = new Intent(BROADCAST_ACTION);
setupHandler();
return START_STICKY;
}
/*
* @Override public void onCreate() { super.onCreate();
*
* utils = new Utilities();
*
* seekIntent = new Intent(BROADCAST_ACTION);
*
* setupHandler();
*
* prepareSong(currentSongPath); playSong(); }
*/
public void prepareSong(String currentSongPath) {
try {
mediaPlayer.reset();
mediaPlayer.setDataSource(currentSongPath);
mediaPlayer.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
public void playSong() {
try {
mediaPlayer.start();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
}
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
public void onCompletion(MediaPlayer mediaPlayer) {
playNext();
}
@Override
public void onStart(Intent intent, int startId) {
registerReceiver(broadcastReceiver, new IntentFilter(
MusicPlayer.BROADCAST_SEEKBAR));
super.onCreate();
prepareSong(currentSongPath);
playSong();
}
private void setupHandler() {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000);
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
LogMediaPosition();
handler.postDelayed(this, 1000);
}
};
private void LogMediaPosition() {
if (mediaPlayer.isPlaying()) {
mediaPosition = mediaPlayer.getCurrentPosition();
MusicPlayer.currentDurationLabel.setText(""
+ utils.milliSecondsToTimer(mediaPosition));
mediaMax = mediaPlayer.getDuration();
seekIntent.putExtra("counter", String.valueOf(mediaPosition));
seekIntent.putExtra("mediamax", String.valueOf(mediaMax));
seekIntent.putExtra("song_ended", String.valueOf(songEnded));
sendBroadcast(seekIntent);
}
}
private void displaySong() {
utils = new Utilities();
String title = titleList.get(currentSongIndex);
String artist = artistList.get(currentSongIndex);
String album = albumList.get(currentSongIndex);
Uri sArtworkUri = Uri.parse("content://media/external/audio/albumart");
Uri currentSongUri = ContentUris.withAppendedId(sArtworkUri, albumId);
String totalDuration = utils.milliSecondsToTimer(totalSongDuration);
mediaPosition = mediaPlayer.getCurrentPosition();
MusicPlayer.currentDurationLabel.setText(""
+ utils.milliSecondsToTimer(mediaPosition));
displayIntent.putExtra("title", title);
displayIntent.putExtra("artist", artist);
displayIntent.putExtra("album", album);
displayIntent.putExtra("totalDuration", totalDuration);
displayIntent.putExtra("currentSongUri", currentSongUri);
sendBroadcast(displayIntent);
}
// receive seekbar position
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
updateSeekPos(intent);
}
};
// Update seek position from Activity
public void updateSeekPos(Intent intent) {
int seekPos = intent.getIntExtra("seekpos", 0);
if (mediaPlayer.isPlaying()) {
handler.removeCallbacks(sendUpdatesToUI);
mediaPlayer.seekTo(seekPos);
setupHandler();
}
}
@Override
public void onDestroy() {
super.onDestroy();
mediaPlayer.stop();
handler.removeCallbacks(sendUpdatesToUI);
// Unregister seek receiver
unregisterReceiver(broadcastReceiver);
}
public void onSeekComplete(MediaPlayer mediaPlayer) {
if (!mediaPlayer.isPlaying()) {
mediaPlayer.start();
}
}
public void playNext() {
if (mediaPlayer.isPlaying()) {
if (currentSongIndex < (pathList.size() - 1)) {
currentSongIndex = currentSongIndex + 1;
currentSongPath = pathList.get(currentSongIndex);
prepareSong(currentSongPath);
playSong();
} else {
currentSongIndex = 0;
currentSongPath = pathList.get(currentSongIndex);
prepareSong(currentSongPath);
playSong();
}
} else {
if (currentSongIndex < (pathList.size() - 1)) {
currentSongIndex = currentSongIndex + 1;
currentSongPath = pathList.get(currentSongIndex);
prepareSong(currentSongPath);
} else {
currentSongIndex = 0;
prepareSong(currentSongPath);
}
}
displaySong();
}
void playPrevious() {
if (mediaPlayer.isPlaying()) {
if (currentSongIndex > 0) {
currentSongIndex = currentSongIndex - 1;
currentSongPath = pathList.get(currentSongIndex);
prepareSong(currentSongPath);
playSong();
} else {
currentSongIndex = pathList.size() - 1;
currentSongPath = pathList.get(currentSongIndex);
prepareSong(currentSongPath);
playSong();
}
} else {
if (currentSongIndex > 0) {
currentSongIndex = currentSongIndex - 1;
currentSongPath = pathList.get(Playlist.currentSongIndex);
prepareSong(currentSongPath);
} else {
currentSongIndex = pathList.size() - 1;
currentSongPath = pathList.get(currentSongIndex);
prepareSong(currentSongPath);
}
}
displaySong();
}
}
音乐播放器.java:
package awesome.music.player;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.ImageButton;
import android.widget.ImageView;
import android.widget.SeekBar;
import android.widget.SeekBar.OnSeekBarChangeListener;
import android.widget.TextView;
public class MusicPlayer extends Activity implements OnSeekBarChangeListener {
public ImageButton play;
public ImageButton next;
public ImageButton previous;
public static ImageView albumArt;
static TextView songArtistAlbumLabel;
static TextView songTitleLabel;
static TextView currentDurationLabel;
static TextView totalDurationLabel;
static String serviceStatus;
private SeekBar seekBar;
private int seekMax;
boolean mBroadcastIsRegistered;
public static Utilities utils;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.playing);
play = (ImageButton) findViewById(R.id.playButton);
next = (ImageButton) findViewById(R.id.nextButton);
previous = (ImageButton) findViewById(R.id.previousButton);
albumArt = (ImageView) findViewById(R.id.imageView1);
songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
songTitleLabel = (TextView) findViewById(R.id.songTitleLabel);
totalDurationLabel = (TextView) findViewById(R.id.totalDurationLabel);
songArtistAlbumLabel = (TextView) findViewById(R.id.songArtistAlbumLabel);
play.setOnClickListener(playListener);
next.setOnClickListener(nextListener);
previous.setOnClickListener(previousListener);
seekBar = (SeekBar) findViewById(R.id.seekBar);
seekBar.setOnSeekBarChangeListener(this);
intent = new Intent(BROADCAST_SEEKBAR);
if (mBroadcastIsRegistered != true) {
registerReceiver(broadcastReceiver, new IntentFilter(
MusicService.BROADCAST_ACTION));
;
mBroadcastIsRegistered = true;
}
}
private OnClickListener playListener = new OnClickListener() {
public void onClick(View v) {
MusicService.playSong();
}
};
private OnClickListener nextListener = new OnClickListener() {
public void onClick(View v) {
MusicService.playNext();
}
};
private OnClickListener previousListener = new OnClickListener() {
public void onClick(View v) {
MusicService.playPrevious();
}
};
public static final String BROADCAST_SEEKBAR = "awesome.music.player.sendseekbar";
Intent intent;
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent serviceIntent) {
updateUI(serviceIntent);
}
};
private void updateUI(Intent serviceIntent) {
String counter = serviceIntent.getStringExtra("counter");
String mediamax = serviceIntent.getStringExtra("mediamax");
String strSongEnded = serviceIntent.getStringExtra("song_ended");
int seekProgress = Integer.parseInt(counter);
seekMax = Integer.parseInt(mediamax);
Integer.parseInt(strSongEnded);
seekBar.setMax(seekMax);
seekBar.setProgress(seekProgress);
}
public void onProgressChanged(SeekBar seekBar, int progress,
boolean fromUser) {
if (fromUser) {
int seekPos = seekBar.getProgress();
intent.putExtra("seekpos", seekPos);
sendBroadcast(intent);
}
}
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
播放.xml:
<?xml version="1.0" encoding="utf-8"?>
<AbsoluteLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent" >
<SeekBar
android:id="@+id/seekBar"
android:layout_width="296dp"
android:layout_height="wrap_content"
android:layout_marginBottom="20dp"
android:layout_marginLeft="20dp"
android:layout_marginRight="20dp"
android:layout_x="10dp"
android:layout_y="446dp"
android:paddingLeft="6dp"
android:paddingRight="6dp"
android:progressDrawable="@drawable/seekbar_progress"
android:thumb="@drawable/seek_handler" />
<ImageView
android:id="@+id/imageView2"
android:layout_width="37dp"
android:layout_height="37dp"
android:layout_x="6dp"
android:layout_y="397dp"
android:src="@drawable/ic_tab_albums_white" />
<TextView
android:id="@+id/songTitleLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="55dp"
android:layout_y="395dp"
android:text="Song Label"
android:textSize="20sp" />
<TextView
android:id="@+id/songArtistAlbumLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="55dp"
android:layout_y="417dp"
android:text="Artist - Album Label"
android:textSize="15sp" />
<TextView
android:id="@+id/currentDurationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="10dp"
android:layout_y="481dp"
android:text="0:00" />
<TextView
android:id="@+id/totalDurationLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="281dp"
android:layout_y="477dp"
android:text="3:30" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="41dp"
android:layout_y="312dp"
android:gravity="center_horizontal" >
<ImageButton
android:id="@+id/previousButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_x="132dp"
android:layout_y="308dp"
android:src="@drawable/ic_previous" />
<ImageButton
android:id="@+id/playButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="50sp"
android:layout_marginRight="50sp"
android:src="@drawable/ic_pause" />
<ImageButton
android:id="@+id/nextButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/ic_next" />
</LinearLayout>
<ImageView
android:id="@+id/imageView1"
android:layout_width="287dp"
android:layout_height="272dp"
android:layout_x="16dp"
android:layout_y="13dp"
android:background="@drawable/dummy_album_art"
android:scaleType="fitXY" />
</AbsoluteLayout>