我制作了一个音乐播放器。音乐在前台服务中播放。如何在音乐更改或开始新音乐时更新通知?
这是我的服务类:
public class EngineBackground extends Service implements MediaPlayer.OnCompletionListener{
private static MainActivity m = new MainActivity();
private static Uri uri;
public int songId;
public static SharedPreferences sp;
private static SharedPreferences.Editor editor;
TaskStackBuilder stackBuilder;
PendingIntent pendingIntent;
static MediaPlayer mp = null;
public static Notification notification;
NotificationManager notificationManager;
@Override
public void onCreate() {
super.onCreate();
stackBuilder = TaskStackBuilder.create(this);
sp = getSharedPreferences("setPrefernces", Context.MODE_PRIVATE);
editor = sp.edit();
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
if(mp == null){
Uri uri = Uri.parse("" + m.songsPath.get(0));
mp = MediaPlayer.create(this, uri);
}
startInForground();
}
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
void startInForground(){
RemoteViews remoteViews = new RemoteViews(getPackageName(),
R.layout.notification_layout_big);
Intent myIntent = new Intent(this, Player.class);
myIntent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
pendingIntent = PendingIntent.getActivity(this, 0, myIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Log.e("Api version:", "" + Build.VERSION.SDK_INT);
if (Build.VERSION.SDK_INT >= 16){
notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setPriority(128)
.build();
notification.bigContentView = remoteViews;
} else{
notification = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_launcher)
.setContentIntent(pendingIntent)
.setAutoCancel(true)
.setPriority(128)
.setContentTitle(getTitle())
.setContentText(getArtist())
.setTicker(getTitle())
.build();
}
startForeground(1, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (uri != null) {
mp.stop();
mp.release();
mp = MediaPlayer.create(this, uri);
mp.start();
}
mp.setOnCompletionListener(this);
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public void onCompletion(MediaPlayer mp) {
mp.pause();
songId = sp.getInt("songId", 0) + 1;
editor.putInt("songId", songId);
editor.commit();
startInForground();
switch (sp.getInt("repeat", 0)) {
case 0:
break;
case 1:
break;
case 2:
break;
}
if (songId < m.songsPath.size()) {
uri = Uri.parse("" + m.songsPath.get(songId));
mp = MediaPlayer.create(this, uri);
this.mp = mp;
this.mp.setOnCompletionListener(this);
this.mp.start();
}
}
public void nextSong(){
songId = sp.getInt("songId", 0) + 1;
editor.putInt("songId", songId);
editor.commit();
if(mp.isPlaying()){
mp.stop();
mp.release();
mp = null;
this.uri = Uri.parse("" + m.songsPath.get(songId));
mp = MediaPlayer.create(this, this.uri);
mp.setOnCompletionListener(this);
mp.start();
Log.e("From next ", "" + songId);
}else{
mp.stop();
mp.release();
mp = null;
this.uri = Uri.parse("" + m.songsPath.get(songId));
mp = MediaPlayer.create(this, this.uri);
mp.setOnCompletionListener(this);
mp.start();
Log.e("From next ", "" + songId);
}
startInForground();
}
public void previousSong(){
songId = sp.getInt("songId", 0) - 1;
editor.putInt("songId", songId);
editor.commit();
if(mp.isPlaying()){
mp.stop();
mp.release();
this.uri = Uri.parse("" + m.songsPath.get(songId));
mp = MediaPlayer.create(this, this.uri);
mp.setOnCompletionListener(this);
mp.start();
Log.e("From pre ", "" + songId);
}else{
mp.stop();
mp.release();
this.uri = Uri.parse("" + m.songsPath.get(songId));
mp = MediaPlayer.create(this, this.uri);
mp.setOnCompletionListener(this);
mp.start();
Log.e("From pre ", "" + songId);
}
startInForground();
}
public void setUri(String uri, int songId){
this.uri = Uri.parse(uri);
//this.songId = songId;
Log.e("From setUri ", "" + this.songId);
}
@Override
public void onDestroy() {
editor.putInt("songId", songId);
editor.commit();
super.onDestroy();
}
public CharSequence getTitle() {
return "" + m.title.get(songId = sp.getInt("songId", 0));
//startInForground();
}
public CharSequence getArtist() {
return "" + m.artist.get(songId = sp.getInt("songId", 0));
}
}
我在播放器活动中创建了此服务的实例。如果按下相应的按钮,则调用nextSong()
或previousSong()
方法。
所以通常当一首歌完成并启动另一首歌时,它会调用startInForeground()
方法并更新通知而没有任何问题。但是,如果我在nextSong()
或previousSong()
中调用相同的方法,则会抛出错误。
这是按下按钮的方法:
private static EngineBackground f = new EngineBackground();
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(f.mp.isPlaying()){
f.nextSong();
}else{
f.nextSong();
}
}
});
任何人都可以帮助我吗?这段代码有什么问题?为什么我无法从startInForeGround()
调用nextSong()
方法?
java.lang.NullPointerException
at android.content.ContextWrapper.getPackageName(ContextWrapper.java:120)
at prime.myapplication.EngineBackground.startInForground(EngineBackground.java:74)
at prime.myapplication.EngineBackground.nextSong(EngineBackground.java:178)
at prime.myapplication.Player$4.onClick(Player.java:178)
at android.view.View.performClick(View.java:2485)
at android.view.View$PerformClick.run(View.java:9080)
at android.os.Handler.handleCallback(Handler.java:587)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:3683)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:507)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:839)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:597)
at dalvik.system.NativeStart.main(Native Method)
答案 0 :(得分:0)
您的媒体播放器可能为空 试试这个
private static EngineBackground f = new EngineBackground();
next.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(f.mp == null)){
// Media play is null and needs initialized <---- see if this helps
}else if(f.mp.isPlaying()){
f.nextSong();
}else{
f.nextSong();
}
}
});
答案 1 :(得分:0)
这背后的原因是您从活动中创建EngineBackground
的实例,然后在其上调用next方法。该服务尚未启动,因此服务中的上下文仍为空,因此您的NullPointerException
您访问服务的方式完全错误,不推荐使用。看看这个 : http://developer.android.com/guide/components/services.html