服务onStartCommand被称为一次活动结束 [英] Service onStartCommand being called once activity ends

查看:147
本文介绍了服务onStartCommand被称为一次活动结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我开始我的服务,当我点击播放按钮来播放一首歌曲,并与它捆绑的MP3歌曲和接受,在onStartCommand。问题是,当我的活动,启动仪式结束,我的服务onStartCommand再次调用。当它收到这个包是不存在,因为该活动也没有启动它这一次。正因为如此我得到一个IllegalStateException时preparing我的媒体播放器。我不绑定我的服务。

为什么当我的活动结束onStartCommand被调用?

启动服务:

 意向书I =新意图(SongList.this,MyService.class);
i.putExtra(songURL,user.songurlz);
i.putExtra(SONGNAME,songplay_name);
startService(ⅰ);

服务类:

 公共类的MyService扩展服务{    静态的MediaPlayer媒体播放器;
    静态INT pauseplay;
    静态NotificationManager notificationManagerPlay;
    静态的CharSequence tickerText;
    静态通知notification4; //通知变量(播放歌曲)
    TelephonyManager telephonyManager;
    PhoneStateListener监听;
    静态的通知的通知;
    静态NotificationManager mNotificationManager;
    串songurl;
    串SONGNAME;    @覆盖
    公众的IBinder onBind(意向意图){
        // TODO自动生成方法存根
        返回null;
    }    @覆盖
    公共无效的onCreate(){
        super.onCreate();
        媒体播放器=新的MediaPlayer();
        pauseplay = 1;
        MainMenu.serviceRunning = 1;
        telephonyManager =(TelephonyManager)getSystemService(
                Context.TELEPHONY_SERVICE);
        //创建一个新PhoneStateListener
        听众=新PhoneStateListener(){            @覆盖
            公共无效onCallStateChanged(INT状态,弦乐incomingNumber){
                开关(州){
                案例TelephonyManager.CALL_STATE_IDLE:
                    打破;
                案例TelephonyManager.CALL_STATE_OFFHOOK:
                    打破;
                案例TelephonyManager.CALL_STATE_RINGING:
                    如果(mediaPlayer.isPlaying()==真&放大器;&安培;!MEDIAPLAYER = NULL){
                        pauseSong();
                    }
                    打破;
                }
            }
        };
        //注册监听机智的电话经理
        telephonyManager.listen(监听器,PhoneStateListener.LISTEN_CALL_STATE);
    }    公众诠释onStartCommand(意向意图,诠释标志诠释startId){
        super.onStartCommand(意向,旗帜,startId);
        如果(意向!= NULL){
            捆绑包= intent.getExtras();
            //使用名称检索数据
            songurl = bundle.getString(songURL);
            捆绑bundle2中= intent.getExtras();
            //使用名称检索数据
            SONGNAME = bundle2.getString(SONGNAME);
        }
        吐司面包= Toast.makeText(getApplicationContext(),正在播放
                + SONGNAME,Toast.LENGTH_LONG);
        toast.show();
        //配置意图
        意图playIntent =新意图(MyService.this,SongList.class);
        最终的PendingIntent的PendingIntent = PendingIntent.getActivity(
                MyService.this,0,playIntent,0);
        通知=新的通知(R.drawable.playicon缓冲......
                System.currentTimeMillis的());
        notification.contentView =新RemoteViews(getPackageName()
                R.layout.custom_notification2);
        notification.contentIntent =的PendingIntent;
        如果(SongList.bitmap!= NULL){
            notification.contentView.setImageViewBitmap(R.id.notifimage,
                    SongList.bitmap);
        }其他{
            notification.contentView.setImageViewResource(R.id.notifimage,
                    R.drawable.icon);
        }
        notification.contentView
                .setTextViewText(R.id.notiftitle,正在播放);
        notification.contentView.setTextViewText(R.id.notiftext,SONGNAME);
        notification.flags = notification.flags
                | Notification.FLAG_ONGOING_EVENT;
        mNotificationManager =(NotificationManager)getApplicationContext()
                .getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(4,通知);
        mediaPlayer.reset();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        尝试{
            mediaPlayer.setDataSource(songurl);
        }赶上(抛出:IllegalArgumentException五){
            e.printStackTrace();
        }赶上(IllegalStateException异常五){
            e.printStackTrace();
        }赶上(IOException异常五){
            e.printStackTrace();
        }
        //通过MediaPlayer的setOnErrorListener注册错误监听器
        mediaPlayer.setOnErrorListener(新OnErrorListener(){            @覆盖
            公共布尔的onError(MediaPlayer的熔点,诠释了什么,整型附加){
                Log.e(MEDIAPLAYER错误,什么+什么额外
                        +额外);
                mediaPlayer.reset();
                mNotificationManager.cancel(4);
                返回false;
            }
        });
        。媒体播放器prepareAsync();
        mediaPlayer.setOn preparedListener(新MediaPlayer.On preparedListener(){            @覆盖
            在prepared(MediaPlayer的MP)公共无效{
                mediaPlayer.start();
            }
        });
        媒体播放器
                .setOnCompletionListener(新MediaPlayer.OnCompletionListener(){                    公共无效onCompletion(MediaPlayer的MP){
                        stopSelf();
                    }
                });
        返回START_STICKY;
    }    @覆盖
    公共无效的onDestroy(){
        MainMenu.serviceRunning = 0;
        mNotificationManager.cancel(4);
    }    公共静态无效pauseSong(){
        如果(mediaPlayer.isPlaying()==真){
            mediaPlayer.pause();
            mNotificationManager.cancel(4);
            pauseplay = 0;
        }
    }    公共静态无效playSong(){
        如果(pauseplay == 0){
            mNotificationManager.notify(4,通知);
            mediaPlayer.start();
            pauseplay = 1;
        }
    }
}


解决方案

  

为什么当我的活动结束onStartCommand被调用?


无论您呼叫 startService()当你的活动结束(知道是什么意思),或Android正在重新启动您由于某种原因服务由于您使用 START_STICKY

个人,对于一个音乐播放器,我认为 START_NOT_STICKY 是正确的答案。如果您的服务已停止出于某种原因,用户应负责再次启动起来。

I start my service when I click the play button to play a song and bundle the song mp3 with it and receive that in the onStartCommand. The problem is that when my activity that starts the service ends, my service calls onStartCommand again. When it goes to receive that bundle it's not there because the activity did not start it this time. Because of this I'm getting an illegalstateexception when preparing my mediaplayer. I am not binding my service.

Why does the onStartCommand get called when my activity ends?

Starting the service:

Intent i = new Intent(SongList.this,MyService.class);
i.putExtra("songURL", user.songurlz);
i.putExtra("songNAME", songplay_name);
startService(i);

The service class:

public class MyService extends Service {

    static MediaPlayer mediaPlayer;
    static int pauseplay;
    static NotificationManager notificationManagerPlay;
    static CharSequence tickerText;
    static Notification notification4;//Notification variable(for song playing)
    TelephonyManager telephonyManager;
    PhoneStateListener listener;
    static Notification notification;
    static NotificationManager mNotificationManager;
    String songurl;
    String songname;

    @Override
    public IBinder onBind(Intent intent) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mediaPlayer = new MediaPlayer();
        pauseplay = 1;
        MainMenu.serviceRunning = 1;
        telephonyManager = (TelephonyManager) getSystemService(
                Context.TELEPHONY_SERVICE);
        // Create a new PhoneStateListener
        listener = new PhoneStateListener() {

            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                switch (state) {
                case TelephonyManager.CALL_STATE_IDLE:
                    break;
                case TelephonyManager.CALL_STATE_OFFHOOK:
                    break;
                case TelephonyManager.CALL_STATE_RINGING:
                    if (mediaPlayer.isPlaying() == true && mediaPlayer != null){
                        pauseSong();
                    }
                    break;
                }
            }
        };
        // Register the listener wit the telephony manager
        telephonyManager.listen(listener, PhoneStateListener.LISTEN_CALL_STATE);
    }

    public int onStartCommand(Intent intent, int flags, int startId) {
        super.onStartCommand(intent, flags, startId);
        if (intent != null) {
            Bundle bundle = intent.getExtras();
            //Retrieve your data using the name
            songurl = bundle.getString("songURL");
            Bundle bundle2 = intent.getExtras();
            //Retrieve your data using the name
            songname = bundle2.getString("songNAME");
        }
        Toast toast = Toast.makeText(getApplicationContext(), "Now Playing: "
                + songname, Toast.LENGTH_LONG);
        toast.show();
        // configure the intent
        Intent playIntent = new Intent(MyService.this, SongList.class);
        final PendingIntent pendingIntent = PendingIntent.getActivity(
                MyService.this, 0, playIntent, 0);
        notification = new Notification(R.drawable.playicon, "Buffering...",
                System.currentTimeMillis());
        notification.contentView = new RemoteViews(getPackageName(),
                R.layout.custom_notification2);
        notification.contentIntent = pendingIntent;
        if (SongList.bitmap != null) {
            notification.contentView.setImageViewBitmap(R.id.notifimage,
                    SongList.bitmap);
        } else {
            notification.contentView.setImageViewResource(R.id.notifimage,
                    R.drawable.icon);
        }
        notification.contentView
                .setTextViewText(R.id.notiftitle, "Now Playing");
        notification.contentView.setTextViewText(R.id.notiftext, songname);
        notification.flags = notification.flags
                | Notification.FLAG_ONGOING_EVENT;
        mNotificationManager = (NotificationManager) getApplicationContext()
                .getSystemService(Context.NOTIFICATION_SERVICE);
        mNotificationManager.notify(4, notification);
        mediaPlayer.reset();
        mediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
        try {
            mediaPlayer.setDataSource(songurl);
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (IllegalStateException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        // register an error listener via MediaPlayer's setOnErrorListener
        mediaPlayer.setOnErrorListener(new OnErrorListener() {

            @Override
            public boolean onError(MediaPlayer mp, int what, int extra) {
                Log.e("MEDIAPLAYER ERRORS", "what: " + what + "  extra: "
                        + extra);
                mediaPlayer.reset();
                mNotificationManager.cancel(4);
                return false;
            }
        });
        mediaPlayer.prepareAsync();
        mediaPlayer.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {

            @Override
            public void onPrepared(MediaPlayer mp) {
                mediaPlayer.start();
            }
        });
        mediaPlayer
                .setOnCompletionListener(new MediaPlayer.OnCompletionListener(){

                    public void onCompletion(MediaPlayer mp) {
                        stopSelf();
                    }
                });
        return START_STICKY;
    }

    @Override
    public void onDestroy() {
        MainMenu.serviceRunning = 0;
        mNotificationManager.cancel(4);
    }

    public static void pauseSong() {
        if (mediaPlayer.isPlaying() == true) {
            mediaPlayer.pause();
            mNotificationManager.cancel(4);
            pauseplay = 0;
        }
    }

    public static void playSong() {
        if (pauseplay == 0) {
            mNotificationManager.notify(4, notification);
            mediaPlayer.start();
            pauseplay = 1;
        }
    }
}

解决方案

Why does the onStartCommand get called when my activity ends?

Either you are calling startService() when your "activity ends" (whatever that means), or Android is restarting your service for some reason due to your use of START_STICKY.

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.

这篇关于服务onStartCommand被称为一次活动结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆