Android 服务自动停止而不调用 stopService()

Android Service stops automatically without calling stopService()

我已经创建了一个 android 服务来播放音乐,当我关闭我的应用程序时,它会继续播放歌曲几分钟,然后自动停止,甚至没有调用 destroy 方法。我不明白为什么会这样。 下面是我的服务代码 class.

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) {

    }

}

下面是我的 activity class.

的代码
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(),但我无法弄清楚为什么它会在一段时间后停止播放。

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

FakePlayer