Android服务自动停止,无需调用stopService()

时间:2015-02-01 08:14:30

标签: android android-service android-music-player

我已经制作了一个Android服务来播放音乐,当我关闭我的应用程序然后它继续播放歌曲几分钟然后自动停止甚至没有调用destroy方法。我无法理解为什么会这样。 以下是我的服务类的代码。

public class MusicService extends Service implements MediaPlayer.OnSeekCompleteListener, MediaPlayer.OnPreparedListener, MediaPlayer.OnCompletionListener,
        MediaPlayer.OnInfoListener, MediaPlayer.OnErrorListener, MediaPlayer.OnBufferingUpdateListener {

    private MediaPlayer player;

    private int songPosition;
    private IBinder iBinder = new LocalBinder();

    private PhoneStateListener phoneStateListener;
    private TelephonyManager telephonyManager;
    private boolean isPaused = false;

    private ArrayList<Song> songsList;
    private boolean isRepeat = false;
    private boolean isShuffle = false;

    private Intent broadcastIntent;
    public static final String BROADCAST_INTENT = "music.akumar.com.musicplayer.seekbarintent";
    private Handler handler = new Handler();

    public class LocalBinder extends Binder {
        public MusicService getService() {
            return MusicService.this;
        }
    }
    @Override
    public void onCreate() {
        broadcastIntent = new Intent(BROADCAST_INTENT);

        player = new MediaPlayer();

        player.setOnBufferingUpdateListener(this);
        player.setOnCompletionListener(this);
        player.setOnSeekCompleteListener(this);
        player.setOnPreparedListener(this);
        player.setOnInfoListener(this);
        player.setOnErrorListener(this);
        player.setLooping(true);

        player.reset();
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        telephonyManager = (TelephonyManager)getSystemService(TELEPHONY_SERVICE);
        phoneStateListener = new PhoneStateListener() {
            @Override
            public void onCallStateChanged(int state, String incomingNumber) {
                switch(state) {
                    case TelephonyManager.CALL_STATE_OFFHOOK:

                    case TelephonyManager.CALL_STATE_RINGING:
                        if (player.isPlaying()) {
                            pauseMedia();
                            isPaused = true;
                        }
                        break;
                    case TelephonyManager.CALL_STATE_IDLE:
                        if (player != null) {
                            if (isPaused) {
                                playMedia();
                                isPaused = false;
                            }
                        }
                        break;

                }
            }
        };

        telephonyManager.listen(phoneStateListener, PhoneStateListener.LISTEN_CALL_STATE);
        return START_STICKY;
    }

    public void playMedia() {
        if (player != null && !player.isPlaying()) {
            player.start();
        }
    }
    public void pauseMedia() {
        if (player != null && player.isPlaying()) {
            player.pause();
        }
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if (player.isPlaying()) {
            player.stop();
        }
        player.release();
    }

    @Override
    public IBinder onBind(Intent intent) {
        return iBinder;
    }

    public void playSong(Song song) {
        player.reset();
        try {
            player.setDataSource(getApplicationContext(), Uri.parse(song.getPath()));
            player.prepare();
            playMedia();
            setHandler();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    private void setHandler() {
        handler.removeCallbacks(sendUpdatesToUI);
        handler.postDelayed(sendUpdatesToUI, 500);
    }

    private Runnable sendUpdatesToUI = new Runnable() {
        @Override
        public void run() {
            logMediaPosition();
            handler.postDelayed(this, 500);
        }
    };
    private void logMediaPosition() {

    }
    public void playNext() {

    }

    public void playPrev() {

    }

    public boolean isPlaying() {
        return player.isPlaying();
    }

    public int getSongPosition() {
        return songPosition;
    }

    public void setSongPosition(int songPosition) {
        this.songPosition = songPosition;
    }

    public ArrayList<Song> getSongsList() {
        return songsList;
    }

    public void setSongsList(ArrayList<Song> songsList) {
        this.songsList = songsList;
    }

    public boolean isRepeat() {
        return isRepeat;
    }

    public void setRepeat(boolean isRepeat) {
        this.isRepeat = isRepeat;
    }

    public boolean isShuffle() {
        return isShuffle;
    }

    public void setShuffle(boolean isShuffle) {
        this.isShuffle = isShuffle;
    }

    public void addSongToList(Song song) {
        songsList.add(song);
    }

    public Song getCurrentSong() {
        return songsList.get(songPosition);
    }



    @Override
    public void onCompletion(MediaPlayer mediaPlayer) {

    }

    @Override
    public boolean onError(MediaPlayer mediaPlayer, int i, int i2) {

        return false;
    }

    @Override
    public boolean onInfo(MediaPlayer mediaPlayer, int i, int i2) {
        return false;
    }

    @Override
    public void onPrepared(MediaPlayer mediaPlayer) {

    }

    @Override
    public void onSeekComplete(MediaPlayer mediaPlayer) {

    }

}

低于我的活动类的代码。

public class MusicPlayer extends FragmentActivity implements View.OnClickListener, SeekBar.OnSeekBarChangeListener {
    private boolean mBound = false;
    private MusicService musicService;
    private ArrayList<Song> songsList = new ArrayList<Song>();

    private boolean isRepeat = false;
    private boolean isShuffle = false;
    private int position;

    private ImageButton btnPlay;
    private ImageButton btnPlayNext;
    private ImageButton btnPlayPrev;
    private ImageButton btnRepeat;
    private ImageButton btnShuffle;
    private ImageButton btnFavorite;
    private TextView currentSongView;
    private SeekBar seekBar;
    private TextView songCurrentDurationLabel;
    private TextView songTotalDurationLabel;
    private ViewPager viewPager;

    private BroadcastReceiver broadcastReceiver;
    private boolean mBroadcastIsRegistered;

    ServiceConnection serviceConnection = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName componentName, IBinder iBinder) {
            mBound = true;
            MusicService.LocalBinder localBinder = (MusicService.LocalBinder)iBinder;
            musicService = localBinder.getService();

            musicService.setSongsList(songsList);
            musicService.setSongPosition(0);
            musicService.playSong(0);
            btnPlay.setImageResource(R.drawable.btn_pause);

            registerReceiver(broadcastReceiver, new IntentFilter(MusicService.BROADCAST_INTENT));
            mBroadcastIsRegistered = true;
        }

        @Override
        public void onServiceDisconnected(ComponentName componentName) {
            mBound = false;
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_music_player);
        songsList = prepareListOfSongsAndAlbumMap();

        currentSongView = (TextView)findViewById(R.id.currentSongView);
        btnPlay = (ImageButton)findViewById(R.id.btnPlay);
        btnPlayNext = (ImageButton)findViewById(R.id.btnNext);
        btnPlayPrev = (ImageButton)findViewById(R.id.btnPrevious);
        btnRepeat = (ImageButton)findViewById(R.id.btnRepeat);
        btnShuffle = (ImageButton)findViewById(R.id.btnShuffle);
        btnFavorite = (ImageButton)findViewById(R.id.btnFavourite);
        seekBar = (SeekBar)findViewById(R.id.SeekBar01);
        songCurrentDurationLabel = (TextView)findViewById(R.id.songCurrentDurationLabel);
        songTotalDurationLabel = (TextView)findViewById(R.id.songTotalDurationLabel);
        viewPager = (ViewPager)findViewById(R.id.viewPagerMusicPlayer);

        position = 0;

        btnPlay.setOnClickListener(this);
        btnPlayNext.setOnClickListener(this);
        btnPlayPrev.setOnClickListener(this);
        btnRepeat.setOnClickListener(this);
        btnShuffle.setOnClickListener(this);
        btnFavorite.setOnClickListener(this);
        seekBar.setOnSeekBarChangeListener(this);

        DataTransferBetweenActivity data = new DataTransferBetweenActivity(songsList, position);
        MusicPlayerTabAdapter musicPlayerTabAdapter = new MusicPlayerTabAdapter(getSupportFragmentManager(), data);
        viewPager.setAdapter(musicPlayerTabAdapter);

        broadcastReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                updateUI(intent);
            }
        };
    }

    private void updateUI(Intent serviceIntent) {

    }

    private ArrayList<Song> prepareListOfSongsAndAlbumMap() {
        Uri musicUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;

        String[] projection;
        projection = null;
        String sortOrder = null;
        String selectionMimeType = MediaStore.Audio.Media.IS_MUSIC + " !=0";

        Cursor musicCursor = getContentResolver().query(musicUri, projection, selectionMimeType, null, sortOrder);
        int count = musicCursor.getCount();
        if (musicCursor.moveToFirst()) {
            do {
                String path = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.DATA));
                String title = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.TITLE));
                String album = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM));
                String artist = musicCursor.getString(musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST));
                int artistId = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.ARTIST_ID));
                int albumId = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.ALBUM_ID));
                int trackId = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.TRACK));
                long duration = musicCursor.getInt(musicCursor.getColumnIndex(MediaStore.Audio.Media.DURATION));

                Uri sArtworkUri = Uri
                        .parse("content://media/external/audio/albumart");
                Uri albumArtUri = ContentUris.withAppendedId(sArtworkUri, albumId);

                Song song = new Song(path, title, album, artist, albumId, trackId, duration, albumArtUri.toString(), artistId);
                songsList.add(song);

            } while (musicCursor.moveToNext());
            Collections.sort(songsList, new Comparator<Song>() {
                @Override
                public int compare(Song song, Song song2) {
                    return song.getTitle().toUpperCase().compareTo(song2.getTitle().toUpperCase());
                }
            });
            musicCursor.close();
        }
        return songsList;
    }

    @Override
    protected void onStart() {
        super.onStart();
        Intent serviceIntent = new Intent(this, MusicService.class);
        startService(serviceIntent);
        bindService(serviceIntent, serviceConnection, BIND_AUTO_CREATE);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mBound) {
            unbindService(serviceConnection);
            mBound = false;
        }
    }

    @Override
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.btnPlay:

                break;

            case R.id.btnNext:

                break;

            case R.id.btnPrevious:

                break;
            case R.id.btnRepeat:

                break;
            case R.id.btnShuffle:
                break;
        }
    }

    @Override
    public void onProgressChanged(SeekBar seekBar, int i, boolean b) {

    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {

    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {

    }

    @Override
    protected void onPause() {
        if (mBroadcastIsRegistered) {
            unregisterReceiver(broadcastReceiver);
            mBroadcastIsRegistered = false;
        }
        super.onPause();
    }

    @Override
    protected void onResume() {
        if (!mBroadcastIsRegistered) {
            registerReceiver(broadcastReceiver, new IntentFilter(MusicService.BROADCAST_INTENT));
            mBroadcastIsRegistered = true;
        }
        super.onResume();
    }

    public void playSong(int position) {
        musicService.playSong(position);
        musicService.setSongPosition(position);
    }
}

我正在使用startService()方法开始我的服务,我没有在任何地方调用stopService()或stopSelf(),但我无法弄清楚为什么它会在一段时间后停止播放。

1 个答案:

答案 0 :(得分:1)

我认为你应该从你的服务中拨打startForeground()。 这是一个音乐播放器的示例项目。我可能会有所帮助

FakePlayer