问题
There were no errors until i added broadcast receiver for showing the progress of the seekbar.The app was working fine before.
Code for the activity.
package source.justanothermusicplayer;
import java.io.Serializable;
import java.util.ArrayList;
import source.justanothermusicplayer.classes.SongDetails;
import source.justanothermusicplayer.service.Music_service;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
import android.media.MediaMetadataRetriever;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.Toast;
import android.widget.SeekBar.OnSeekBarChangeListener;
public class NowPlaying extends Activity implements OnSeekBarChangeListener,
Serializable {
Intent serviceIntent;
private boolean boolMusicPlaying = false;
private Button buttonPlayStop;;
SeekBar seekbar;
ArrayList<SongDetails> songdetails = new ArrayList<SongDetails>();
public static final String BROADCAST_SEEKBAR = "source.justanothermusicplayer.sendseekbar";
Intent intent;
// Seekbar
private SeekBar seekBar;
private int seekMax;
private static int songEnded = 0;
boolean mBroadcastIsRegistered;
int position = 0;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.now_playing);
this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
Intent i = getIntent();
position = i.getIntExtra("Data2", 0);
songdetails = getIntent().getParcelableArrayListExtra("Data1");
try {intent = new Intent(BROADCAST_SEEKBAR);
serviceIntent = new Intent(this, Music_service.class);
initViews();
setListeners();
}
catch(Exception e)
{}
playAudio(position);
buttonPlayStop.setBackgroundResource(R.drawable.pause);
boolMusicPlaying = true;
}
private void setListeners() {
buttonPlayStop.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
buttonPlayStopClick();
}
});
seekbar.setOnSeekBarChangeListener(this);
}
// not working correctly,also i have to add pause and not stop
private void buttonPlayStopClick() {
if (!boolMusicPlaying) {
buttonPlayStop.setBackgroundResource(R.drawable.pause);
playAudio(position);
boolMusicPlaying = true;
} else {
if (boolMusicPlaying) {
buttonPlayStop.setBackgroundResource(R.drawable.play);
stopMusic_service();
boolMusicPlaying = false;
}
}
}
private void playAudio(int position2) {
position2 = position;
serviceIntent.putParcelableArrayListExtra("sentAudioLink", songdetails);
serviceIntent.putExtra("postion_service", position);
try {
startService(serviceIntent);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
e.getClass().getName() + " " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
registerReceiver(broadcastReceiver, new IntentFilter(
Music_service.BROADCAST_ACTION));
;
mBroadcastIsRegistered = true;
}
private void stopMusic_service() {
if (mBroadcastIsRegistered) {
try {
unregisterReceiver(broadcastReceiver);
mBroadcastIsRegistered = false;
} catch (Exception e) {
// Log.e(TAG, "Error in Activity", e);
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(
getApplicationContext(),
e.getClass().getName() + " " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
}
try {
stopService(serviceIntent);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(getApplicationContext(),
e.getClass().getName() + " " + e.getMessage(),
Toast.LENGTH_LONG).show();
}
boolMusicPlaying = false;
}
private void initViews() {
buttonPlayStop = (Button) findViewById(R.id.bPlayPause);
buttonPlayStop.setBackgroundResource(R.drawable.play);
seekbar = (SeekBar) findViewById(R.id.songProgressBar);
}
@Override
public void onProgressChanged(SeekBar sb, int progress,
boolean fromUser) {
if (fromUser) {
int seekPos = sb.getProgress();
intent.putExtra("seekpos", seekPos);
sendBroadcast(intent);
}
}
private void showPD(Intent bufferIntent) {
String bufferValue = bufferIntent.getStringExtra("buffering");
int bufferIntValue = Integer.parseInt(bufferValue);
// When the broadcasted "buffering" value is 1, show "Buffering"
// progress dialogue.
// When the broadcasted "buffering" value is 0, dismiss the progress
// dialogue.
switch (bufferIntValue) {
// Listen for "2" to reset the button to a play button
case 2:
buttonPlayStop.setBackgroundResource(R.drawable.play);
break;
}
}
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);
songEnded = Integer.parseInt(strSongEnded);
seekBar.setMax(seekMax);
seekBar.setProgress(seekProgress);
if (songEnded == 1) {
buttonPlayStop.setBackgroundResource(R.drawable.play);
}
}
private BroadcastReceiver broadcastBufferReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent bufferIntent) {
showPD(bufferIntent);
}
};
@Override
protected void onPause() {
// Unregister broadcast receiver
if (mBroadcastIsRegistered) {
unregisterReceiver(broadcastBufferReceiver);
mBroadcastIsRegistered = false;
}
super.onPause();
}
// -- onResume register broadcast receiver. To improve, retrieve saved
// screen data ---
@Override
protected void onResume() {
// Register broadcast receiver
if (!mBroadcastIsRegistered) {
registerReceiver(broadcastBufferReceiver, new IntentFilter(
Music_service.BROADCAST_BUFFER));
mBroadcastIsRegistered = true;
}
super.onResume();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
}
enter code here
now code for service:
import java.io.IOException;
import java.util.ArrayList;
import source.justanothermusicplayer.NowPlaying;
import source.justanothermusicplayer.R;
import source.justanothermusicplayer.classes.SongDetails;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnBufferingUpdateListener;
import android.media.MediaPlayer.OnCompletionListener;
import android.media.MediaPlayer.OnErrorListener;
import android.media.MediaPlayer.OnInfoListener;
import android.media.MediaPlayer.OnPreparedListener;
import android.media.MediaPlayer.OnSeekCompleteListener;
import android.net.Uri;
import android.os.Handler;
import android.os.IBinder;
import android.telephony.PhoneStateListener;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.widget.Toast;
public class Music_service extends Service implements OnCompletionListener,
OnPreparedListener, OnErrorListener, OnSeekCompleteListener,
OnInfoListener {
private static final String TAG = "TELSERVICE";
ArrayList<SongDetails> songdetails = new ArrayList<SongDetails>();
MediaPlayer mp = new MediaPlayer();
Intent bufferIntent;
int position;
private static final int NOTIFICATION_ID = 1;
private boolean isPausedInCall = false;
private PhoneStateListener phoneStateListener;
private TelephonyManager telephonyManager;
private int headsetSwitch = 1;
public static final String BROADCAST_BUFFER = "source.justanothermusicplayer.broadcastbuffer";
// ---Variables for seekbar processing---
String sntSeekPos;
int intSeekPos;
int mediaPosition;
int mediaMax;
// Intent intent;
private final Handler handler = new Handler();
private static int songEnded;
Intent seekIntent;
public static final String BROADCAST_ACTION = "source.justanothermusicplayer.seekprogress";
@Override
public void onCreate() {
mp.setOnCompletionListener(this);
mp.setOnPreparedListener(this);
mp.setOnErrorListener(this);
mp.setOnSeekCompleteListener(this);
mp.setOnInfoListener(this);
mp.reset();
bufferIntent = new Intent(BROADCAST_BUFFER);
// Register headset receiver
registerReceiver(headsetReceiver, new IntentFilter(
Intent.ACTION_HEADSET_PLUG));
seekIntent = new Intent(BROADCAST_ACTION);
}
@Override
public int onStartCommand(Intent intent, int flags, int startid) {
registerReceiver(broadcastReceiver, new IntentFilter(
NowPlaying.BROADCAST_SEEKBAR));
Log.v(TAG, "Starting telephony");
telephonyManager = (TelephonyManager) getSystemService(Context.TELEPHONY_SERVICE);
Log.v(TAG, "Starting listener");
phoneStateListener = new PhoneStateListener() {
@Override
public void onCallStateChanged(int state, String incomingNumber) {
// String stateString = "N/A";
Log.v(TAG, "Starting CallStateChange");
switch (state) {
case TelephonyManager.CALL_STATE_OFFHOOK:
case TelephonyManager.CALL_STATE_RINGING:
if (mp != null) {
pauseMedia();
isPausedInCall = true;
}
break;
case TelephonyManager.CALL_STATE_IDLE:
// Phone idle. Start playing.
if (mp != null) {
if (isPausedInCall) {
isPausedInCall = false;
playMedia();
}
}
break;
}
}
};
// Register the listener with the telephony manager
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_CALL_STATE);
initNotification();
songdetails = intent.getParcelableArrayListExtra("sentAudioLink");
position = intent.getIntExtra("postion_service", 0);
mp.reset();
// Set up the MediaPlayer data source using the strAudioLink value
// if (!mp.isPlaying())
{
try {
mp.setDataSource(this,
Uri.parse(songdetails.get(position).Path));
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
} catch (Exception e) {
}
try {
mp.prepare();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
setupHandler();
return START_STICKY;
}
private void setupHandler() {
handler.removeCallbacks(sendUpdatesToUI);
handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
}
private Runnable sendUpdatesToUI = new Runnable() {
public void run() {
// // Log.d(TAG, "entered sendUpdatesToUI");
LogMediaPosition();
handler.postDelayed(this, 1000); // 2 seconds
}
};
private void LogMediaPosition() {
// // Log.d(TAG, "entered LogMediaPosition");
if (mp.isPlaying()) {
mediaPosition = mp.getCurrentPosition();
// if (mediaPosition < 1) {
// Toast.makeText(this, "Buffering...", Toast.LENGTH_SHORT).show();
// }
mediaMax = mp.getDuration();
// seekIntent.putExtra("time", new Date().toLocaleString());
seekIntent.putExtra("counter", String.valueOf(mediaPosition));
seekIntent.putExtra("mediamax", String.valueOf(mediaMax));
seekIntent.putExtra("song_ended", String.valueOf(songEnded));
sendBroadcast(seekIntent);
}
}
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 (mp.isPlaying()) {
handler.removeCallbacks(sendUpdatesToUI);
mp.seekTo(seekPos);
setupHandler();
}
}
BroadcastReceiver headsetReceiver = new BroadcastReceiver() {
private boolean headsetConnected = false;
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
// Log.v(TAG, "ACTION_HEADSET_PLUG Intent received");
if (intent.hasExtra("state")) {
if (headsetConnected && intent.getIntExtra("state", 0) == 0) {
headsetConnected = false;
headsetSwitch = 0;
// Log.v(TAG, "State = Headset disconnected");
// headsetDisconnected();
} else if (!headsetConnected
&& intent.getIntExtra("state", 0) == 1) {
headsetConnected = true;
headsetSwitch = 1;
// Log.v(TAG, "State = Headset connected");
}
}
switch (headsetSwitch) {
case (0):
headsetDisconnected();
break;
case (1):
break;
}
}
private void headsetDisconnected() {
stopMedia();
stopSelf();
}
};
@Override
public void onDestroy() {
super.onDestroy();
if (mp != null) {
if (mp.isPlaying()) {
mp.stop();
}
mp.release();
}
if (phoneStateListener != null) {
telephonyManager.listen(phoneStateListener,
PhoneStateListener.LISTEN_NONE);
}
cancelNotification();
unregisterReceiver(broadcastReceiver);
unregisterReceiver(headsetReceiver);
handler.removeCallbacks(sendUpdatesToUI);
}
private void initNotification() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
int icon = R.drawable.ic_launcher;
CharSequence tickerText = "Tutorial: Music In Service";
long when = System.currentTimeMillis();
Notification notification = new Notification(icon, tickerText, when);
notification.flags = Notification.FLAG_ONGOING_EVENT;
Context context = getApplicationContext();
CharSequence contentTitle = "Music In Service App Tutorial";
CharSequence contentText = "Listen To Music While Performing Other Tasks";
Intent notificationIntent = new Intent(this, NowPlaying.class);
PendingIntent contentIntent = PendingIntent.getActivity(context, 0,
notificationIntent, 0);
notification.setLatestEventInfo(context, contentTitle, contentText,
contentIntent);
mNotificationManager.notify(NOTIFICATION_ID, notification);
}
// Cancel Notification
private void cancelNotification() {
String ns = Context.NOTIFICATION_SERVICE;
NotificationManager mNotificationManager = (NotificationManager) getSystemService(ns);
mNotificationManager.cancel(NOTIFICATION_ID);
}
private void resetButtonPlayStopBroadcast() {
// Log.v(TAG, "BufferCompleteSent");
bufferIntent.putExtra("buffering", "2");
sendBroadcast(bufferIntent);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCompletion(MediaPlayer mp2) {
stopMedia();
position = position + 1;
try {
// mp.setDataSource(songdetails.get(position).Path);
mp.setDataSource(this, Uri.parse(songdetails.get(position).Path));
mp.prepare();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
public void stopMedia() {
if (mp.isPlaying()) {
mp.stop();
}
mp.reset();
}
public void playMedia() {
// if (!mp.isPlaying())
{
mp.start();
}
}
public void pauseMedia() {
// Log.v(TAG, "Pause Media");
if (mp.isPlaying()) {
mp.pause();
}
}
@Override
public void onPrepared(MediaPlayer arg0) {
playMedia();
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
return false;
}
@Override
public void onSeekComplete(MediaPlayer mp2) {
if (!mp.isPlaying()){
playMedia();
Toast.makeText(this,
"SeekComplete", Toast.LENGTH_SHORT).show();
}
}
@Override
public boolean onInfo(MediaPlayer arg0, int arg1, int arg2) {
// TODO Auto-generated method stub
return false;
}
}
now error log
10-09 21:34:27.751: E/AndroidRuntime(553): FATAL EXCEPTION: main
10-09 21:34:27.751: E/AndroidRuntime(553): java.lang.RuntimeException: Error receiving broadcast Intent { act=source.justanothermusicplayer.seekprogress flg=0x10 (has extras) } in source.justanothermusicplayer.NowPlaying$1@40fa2e50
10-09 21:34:27.751: E/AndroidRuntime(553): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:737)
10-09 21:34:27.751: E/AndroidRuntime(553): at android.os.Handler.handleCallback(Handler.java:605)
10-09 21:34:27.751: E/AndroidRuntime(553): at android.os.Handler.dispatchMessage(Handler.java:92)
10-09 21:34:27.751: E/AndroidRuntime(553): at android.os.Looper.loop(Looper.java:137)
10-09 21:34:27.751: E/AndroidRuntime(553): at android.app.ActivityThread.main(ActivityThread.java:4340)
10-09 21:34:27.751: E/AndroidRuntime(553): at java.lang.reflect.Method.invokeNative(Native Method)
10-09 21:34:27.751: E/AndroidRuntime(553): at java.lang.reflect.Method.invoke(Method.java:511)
10-09 21:34:27.751: E/AndroidRuntime(553): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-09 21:34:27.751: E/AndroidRuntime(553): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-09 21:34:27.751: E/AndroidRuntime(553): at dalvik.system.NativeStart.main(Native Method)
10-09 21:34:27.751: E/AndroidRuntime(553): Caused by: java.lang.NullPointerException
10-09 21:34:27.751: E/AndroidRuntime(553): at source.justanothermusicplayer.NowPlaying.updateUI(NowPlaying.java:196)
10-09 21:34:27.751: E/AndroidRuntime(553): at source.justanothermusicplayer.NowPlaying.access$0(NowPlaying.java:189)
10-09 21:34:27.751: E/AndroidRuntime(553): at source.justanothermusicplayer.NowPlaying$1.onReceive(NowPlaying.java:185)
10-09 21:34:27.751: E/AndroidRuntime(553): at android.app.LoadedApk$ReceiverDispatcher$Args.run(LoadedApk.java:728)
10-09 21:34:27.751: E/AndroidRuntime(553): ... 9 more
回答1:
try this..
u have specified global seekMax 2 times
return statement of onStartCommand
always
return START_NOT_STICKY;
only
Personally, for a music player, I argue that START_NOT_STICKY
is the right answer. If your service is stopped for whatever reason, the user should be in charge of starting it up again.
来源:https://stackoverflow.com/questions/19276340/androidmusic-player-unable-to-start-service-with-null-point-exception