我知道它有点重复的问题,但我完全不知道什么是错的。 实际上,我正在尝试创建一个应该通过通知栏(播放,暂停,恢复)控制的媒体播放器。播放器播放正常并显示通知栏,但是当我单击暂停按钮时,它会抛出空指针异常。我猜错误是在按钮本身的动作中,因为它无法启动服务来执行这些功能。 此外,通知栏未更新,即使被杀,服务也会不断创建。
这是我的代码:
MusicService.java
// play the music in the Service class, but control it from the Activity class,
public class MusicService extends Service implements
MediaPlayer.OnPreparedListener, MediaPlayer.OnErrorListener,
MediaPlayer.OnCompletionListener {
private String songTitle="";
//media player
private MediaPlayer player;
//song list
private ArrayList<Music> songs;
//current position
private int songPosn;
private int length=0;
private static final String LOG_TAG = "ForegroundService";
@Override
public void onCreate() {
super.onCreate();
player =new MediaPlayer();
songPosn=0;
Toast.makeText(this, "Service was Created", Toast.LENGTH_LONG).show();
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
songs = (ArrayList<Music>)intent.getSerializableExtra("array");
songPosn=intent.getIntExtra("id",0);
playSong();
Notify();
if(intent.getAction().equals(Constants.ACTION.STARTFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Start Foreground Intent ");}
else if (intent.getAction().equals(Constants.ACTION.RESUME_ACTION)) {
Log.i(LOG_TAG, "Clicked Resume");
} else if (intent.getAction().equals(Constants.ACTION.PLAY_ACTION)) {
Log.i(LOG_TAG, "Clicked Play");
} else if (intent.getAction().equals(Constants.ACTION.PAUSE_ACTION)) {
Log.i(LOG_TAG, "Clicked pause");
} else if (intent.getAction().equals(
Constants.ACTION.STOPFOREGROUND_ACTION)) {
Log.i(LOG_TAG, "Received Stop Foreground Intent");
stopForeground(true);
stopSelf();
}
return START_REDELIVER_INTENT;
}
@Override
public void onDestroy() {
super.onDestroy();
if (player.isPlaying()) {
player.stop();
}
player.release();
Log.i(LOG_TAG, "In onDestroy");
stopForeground(true);
}
public void pauseMusic()
{
if(player.isPlaying())
{
player.pause();
length=player.getCurrentPosition();
}
}
public void resumeMusic()
{
if(player.isPlaying()==false)
{
player.seekTo(length);
player.start();
}
}
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
songPosn=songPosn+1;
playSong();
mediaPlayer.start();
}
@Override
public boolean onError(MediaPlayer mediaPlayer, int i, int i1) {
return false;
}
@Override
public void onPrepared(MediaPlayer mediaPlayer) {
player.start();
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
public void playSong() {
player.reset();
//get song
Music playSong = songs.get(songPosn);
songTitle=playSong.getMusicTitle();
//get id
long currSong = playSong.getMusicId();
// set uri
Uri trackUri = ContentUris.withAppendedId(
android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI,
currSong);
player.setAudioStreamType(AudioManager.STREAM_MUSIC);
player.setOnPreparedListener(this); // listner when the MediaPlayer instance is prepared
player.setOnErrorListener(this); // an error is thrown
player.setOnCompletionListener(this);
try{
player.setDataSource(getApplicationContext(), trackUri);
}
catch(Exception e){
Log.e("MUSIC SERVICE", "Error setting data source", e);
}
player.prepareAsync();
Toast.makeText(this, "play music",
Toast.LENGTH_LONG).show();
}
public void Notify()
{
Intent notificationIntent = new Intent(this, MainActivity.class);
notificationIntent.setAction(Constants.ACTION.MAIN_ACTION);
notificationIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0,
notificationIntent, 0);
Intent resumeIntent = new Intent(this, MusicService.class);
resumeIntent.setAction(Constants.ACTION.RESUME_ACTION);
PendingIntent rresumeIntent = PendingIntent.getService(this, 0,
resumeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent playIntent = new Intent(this, MusicService.class);
playIntent.setAction(Constants.ACTION.PLAY_ACTION);
PendingIntent pplayIntent = PendingIntent.getService(this, 0,
playIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Intent pauseIntent = new Intent(this, MusicService.class);
pauseIntent.setAction(Constants.ACTION.PAUSE_ACTION);
PendingIntent ppauseIntent = PendingIntent.getService(this, 0,
pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
Bitmap icon = BitmapFactory.decodeResource(getResources(),
R.drawable.pic);
NotificationCompat.Builder notification = new NotificationCompat.Builder(this)
.setContentTitle(songTitle)
.setTicker(songTitle)
.setContentText("My Music")
.setSmallIcon(R.drawable.pic)
.setLargeIcon(
Bitmap.createScaledBitmap(icon, 128, 128, false))
.setContentIntent(pendingIntent)
.setPriority(Notification.PRIORITY_MAX)
.addAction(android.R.drawable.ic_media_ff,
"Resume", rresumeIntent)
.addAction(android.R.drawable.ic_media_play, "Play",
pplayIntent)
.addAction(android.R.drawable.ic_media_pause, "Pause",
ppauseIntent);
NotificationManager mNotifyMgr = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
mNotifyMgr.notify(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,
notification.build());
notification.setContentTitle(songTitle);
mNotifyMgr.notify(Constants.NOTIFICATION_ID.FOREGROUND_SERVICE,notification.build());
}
}
MusicFragment.java
public class MusicFragment extends android.support.v4.app.Fragment {
private final String LOG_TAG = MusicFragment.class.getSimpleName();
private ArrayList<Music> songList;
private ListView songView;
private MusicService musicSrv = new MusicService() ;
private Intent playIntent;
private boolean musicBound=false;
private LinearLayout songsLayout;
private MusicController controller;
SongAdapter songAdt;
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View myView = inflater.inflate(R.layout.activity_music_fragment, container, false);
songView = (ListView)myView.findViewById(R.id.song_list);
songsLayout =(LinearLayout)myView.findViewById(R.id.song_layout);
setHasOptionsMenu(true);
songList = new ArrayList<Music>();
getSongList();
// sort songs alphabitcally
Collections.sort(songList, new Comparator<Music>(){
public int compare(Music a, Music b){
return a.getMusicTitle().compareTo(b.getMusicTitle());
}
});
songAdt = new SongAdapter(getActivity(), songList);
songView.setAdapter(songAdt);
songView.setOnItemClickListener(new ListClickHandler());
return myView;
}
@Override
public void onCreateOptionsMenu (Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.service_menu, menu);
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.action_end:
getActivity().stopService(playIntent);
musicSrv=null;
System.exit(0);
break;
}
return super.onOptionsItemSelected(item);
}
public void getSongList() {
ContentResolver musicResolver = getContext().getContentResolver();
Uri musicUri = android.provider.MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
Cursor musicCursor = musicResolver.query(musicUri, null, null, null, null);
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 Music(thisId, thisTitle, thisArtist));
}
while (musicCursor.moveToNext());
}
}
public class ListClickHandler implements AdapterView.OnItemClickListener {
@Override
public void onItemClick(AdapterView<?> adapter, View view, int position, long arg3) {
// TODO Auto-generated method stub
Intent startIntent = new Intent(getActivity(), MusicService.class);
startIntent.setAction(Constants.ACTION.STARTFOREGROUND_ACTION);
startIntent.putExtra("array",songList);
startIntent.putExtra("id",Integer.parseInt(view.getTag().toString()));
getActivity().startService(startIntent);
}}
@Override
public void onDestroy() {
super.onDestroy();
musicSrv.stopForeground(true);
}
}
Logcat:
E/AndroidRuntime: FATAL EXCEPTION: main java.lang.RuntimeException: Unable to start service .MusicService@42bb1fa0 with Intent { act=.MusicService.action.pause flg=0x10000000 cmp=/.MusicService bnds=[518,1047][720,1143] }: java.lang.NullPointerException
at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:2850)
at android.app.ActivityThread.access$2000(ActivityThread.java:159)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1419)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:176)
at android.app.ActivityThread.main(ActivityThread.java:5419)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:525)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
at dalvik.system.NativeStart.main(Native Method)