Я получаю ошибки / исключения на своем сервисе, которые я использую для потоковой передачи shoutcast.
Я хотел бы показать ошибку в потоке пользовательского интерфейса, если генерируется какое-либо исключение, например, если музыкальный поток не работает.
Как это можно сделать, вот мой текущий код.
Класс пользовательского интерфейса:
private OnClickListener btnStopListener = new OnClickListener() {
public void onClick(View v) {
if (MyService.isRunning()) {
doUnbindService();
stopService(new Intent(MainActivity.this, MyService.class));
btnStop.setBackgroundResource(R.drawable.player_play);
barLoader.setVisibility(View.GONE);
} else {
Intent intent = new Intent(MainActivity.this, MyService.class);
intent.putExtra("streamUrl", strLinkUrl);
startService(intent);
doBindService();
}
}
};
void doBindService() {
bindService(new Intent(this, MyService.class), mConnection,
Context.BIND_AUTO_CREATE);
mIsBound = true;
}
void doUnbindService() {
if (mIsBound) {
// If we have received the service, and hence registered with it,
// then now is the time to unregister.
if (mService != null) {
try {
Message msg = Message.obtain(null,
MyService.MSG_UNREGISTER_CLIENT);
msg.replyTo = mMessenger;
mService.send(msg);
} catch (RemoteException e) {
// There is nothing special we need to do if the service has
// crashed.
}
}
// Detach our existing connection.
unbindService(mConnection);
mIsBound = false;
}
}
Класс обслуживания:
public class MyService extends Service implements
OnPreparedListener, OnErrorListener {
public String txtBTitle, txtBChannel, txtBDescription, txtBTitleNow, txtBImageUrl, txtBLinkUrl; частный NotificationManager nm;
private static boolean isRunning = false;
private Timer timer1 = new Timer();
String strTitle,strArtist;
MediaPlayer mediaPlayer = new MediaPlayer();
ArrayList<Messenger> mClients = new ArrayList<Messenger>(); // Keeps track of all current registered clients.
int mValue = 0; // Holds last value set by a client.
static final int MSG_REGISTER_CLIENT = 1;
static final int MSG_UNREGISTER_CLIENT = 2;
static final int MSG_SET_INT_VALUE = 3;
static final int MSG_SET_STRING_VALUE = 4;
String strUrl;
final Messenger mMessenger = new Messenger(new IncomingHandler()); // Target we publish for clients to send messages to IncomingHandler.
@Override
public IBinder onBind(Intent intent) {
return mMessenger.getBinder();
}
class IncomingHandler extends Handler { // Handler of incoming messages from clients.
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_REGISTER_CLIENT:
mClients.add(msg.replyTo);
break;
case MSG_UNREGISTER_CLIENT:
mClients.remove(msg.replyTo);
break;
case MSG_SET_INT_VALUE:
// incrementby = msg.arg1;
break;
default:
super.handleMessage(msg);
}
}
}
private void sendMessageToUI(int intvaluetosend) {
for (int i=mClients.size()-1; i>=0; i--) {
try {
// Send data as an Integer
mClients.get(i).send(Message.obtain(null, MSG_SET_INT_VALUE, intvaluetosend, 0));
//Send data as a String
Bundle b = new Bundle();
b.putString("str1",strTitle+"\n"+strArtist);
b.putString("strUrl", strUrl);
Message msg = Message.obtain(null, MSG_SET_STRING_VALUE);
msg.setData(b);
mClients.get(i).send(msg);
} catch (RemoteException e) {
// The client is dead. Remove it from the list; we are going through the list from back to front so this is safe to do inside the loop.
mClients.remove(i);
}
}
}
@Override
public void onCreate() {
super.onCreate();
Log.i("MyService", "Service Started.");
showNotification();
isRunning = true;
}
private void showNotification() {
nm = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
// In this sample, we'll use the same text for the ticker and the expanded notification
CharSequence text = getText(R.string.service_started);
// Set the icon, scrolling text and timestamp
Notification notification = new Notification(R.drawable.icon, text, System.currentTimeMillis());
// The PendingIntent to launch our activity if the user selects this notification
PendingIntent contentIntent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class).putExtra("fromWhere", "fromService"), 0);
// Set the info for the views that show in the notification panel.
notification.setLatestEventInfo(this, getText(R.string.service_label), text, contentIntent);
// Send the notification.
// We use a layout id because it is a unique number. We use it later to cancel.
nm.notify(R.string.service_started, notification);
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
strUrl = intent.getExtras().getString("streamUrl");
Log.i("ZealDeveloper", strUrl);
if(!mediaPlayer.isPlaying()){
mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
try {
mediaPlayer.setDataSource(strUrl);
mediaPlayer.setOnPreparedListener(this);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mediaPlayer.prepareAsync(); // might take long! (for buffering, etc)
// mediaPlayer.start();
}
timer1.scheduleAtFixedRate(new TimerTask(){ public void run() {onMetaParser();}
}, 0, 100000L);
Log.i("MyService", "Received start id " + startId + ": " + intent);
return START_STICKY; // run until explicitly stopped.
}
public static boolean isRunning()
{
return isRunning;
}
//Meta Parser
private void onMetaParser() {
// TODO Auto-generated method stub
URL url;
try {
url = new URL(strUrl);
IcyStreamMeta icy = new IcyStreamMeta(url);
try{
strTitle = icy.getTitle();
}
catch (NullPointerException e) {
strTitle="";
}
try{
strArtist = icy.getArtist();
}
catch (NullPointerException e) {
strArtist = "";
}
System.out.println("Title : " + strTitle + strUrl);
System.gc();
// txtTitleNow.setText(T);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Override
public void onDestroy() {
super.onDestroy();
if (mediaPlayer.isPlaying()) {
mediaPlayer.release();
}
if (timer1 != null) {timer1.cancel();
Log.i("ZealDeveloper", "Timer 1 Cancled");}
nm.cancel(R.string.service_started); // Cancel the persistent notification.
Log.i("MyService", "Service Stopped.");
isRunning = false;
try {
timer1.cancel();
mediaPlayer.release();
mediaPlayer = null;
} catch (Exception e) {
e.printStackTrace();
}
}
@Override
public void onPrepared(MediaPlayer mp) {
// TODO Auto-generated method stub
mp.start();
sendMessageToUI(0);
}
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
// TODO Auto-generated method stub
mediaPlayer.release();
timer1.cancel();
return false;}}
Трассировка стека:
01-30 11:03:32.470: W/System.err(311): java.io.FileNotFoundException: http://xxxxxstream
01-30 11:03:32.480: E/MediaPlayer(311): error (1, -1004)
01-30 11:03:32.490: W/System.err(311): at org.apache.harmony.luni.internal.net.www.protocol.http.HttpURLConnectionImpl.getInputStream(HttpURLConnectionImpl.java:1162)
01-30 11:03:32.500: W/System.err(311): at com.sikhnetRadio.test.IcyStreamMeta.retreiveMetadata(IcyStreamMeta.java:91)
01-30 11:03:32.500: W/System.err(311): at com.sikhnetRadio.test.IcyStreamMeta.refreshMeta(IcyStreamMeta.java:79)
01-30 11:03:32.500: W/System.err(311): at com.sikhnetRadio.test.IcyStreamMeta.getMetadata(IcyStreamMeta.java:72)
01-30 11:03:32.500: W/System.err(311): at com.sikhnetRadio.test.IcyStreamMeta.getTitle(IcyStreamMeta.java:60)
01-30 11:03:32.500: W/System.err(311): at com.sikhnetRadio.test.MyService.onMetaParser(MyService.java:192)
01-30 11:03:32.510: W/System.err(311): at com.sikhnetRadio.test.MyService.access$0(MyService.java:182)
01-30 11:03:32.510: W/System.err(311): at com.sikhnetRadio.test.MyService$1.run(MyService.java:163)
01-30 11:03:32.510: W/System.err(311): at java.util.Timer$TimerImpl.run(Timer.java:289)
01-30 11:03:32.610: E/MediaPlayer(311): Error (1,-1004)