有状态的长期生活android服务

时间:2017-12-06 20:45:43

标签: android

我正在尝试实现类似scrobbler(应用程序检索当前播放的歌曲元数据并将其写入我的服务器上的数据库)。

所以我有这样的服务

public class ListenerService extends Service {

    private static final int SCROBBLE_TIME_PERIOD = 30000;

    private Song currentSong;
    private Date startListeningTime;

    public ListenerService() {
    }

    @Override
    public void onCreate() {
        super.onCreate();
        IntentFilter filter = new IntentFilter();
        //Google Android player
        filter.addAction("com.android.music.playstatechanged");
        filter.addAction("com.android.music.playbackcomplete");
        filter.addAction("com.android.music.metachanged");

        registerReceiver(mReceiver, filter);
    }

    private BroadcastReceiver mReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            Song song = new Song(intent.getStringExtra("artist"), intent.getStringExtra("album"),
                    intent.getStringExtra("track"));

            if (!currentSong.equals(song)) {
                currentSong = song;
                startListeningTime = new Date();
            }
        }
    };

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (new Date().getTime() - startListeningTime.getTime() >= SCROBBLE_TIME_PERIOD) {
            ///... write song to db
            currentSong = null;
        }
        return super.onStartCommand(intent, flags, startId);
    }

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

}

onCreate()方法中,我注册了接收器。 reciver只是更新当前播放的歌曲变量并设置开始播放的时间。

我想定期调用onStartCommand()方法,该方法只检查当前歌曲播放时间超过30秒并将其写入数据库。 我谷歌它,但所有的例子都显示了当我想调用现有服务的onStartCommand时,如何定期创建一个新服务(只需向它发送新的意图)。 有没有办法做到这一点?

UPD。 在另一篇文章中我读到,在android中,永远不可能使服务生活(当手机打开时)。因此,当Android终止我的服务时,我将丢失来自currentSongstartListeningTime变量的信息。我应该将这类信息存储在其他地方(在哪里?),或者有一些工作方法可以防止服务被强制关闭?

1 个答案:

答案 0 :(得分:0)

您可以根据onStartCommand中的返回值选择服务类型。
如果您返回START_NOT_STICKY,则只要服务被终止,就不会再次创建服务。
如果您返回START_STICKY,则每当服务被终止时,它将再次从OS创建。但要小心,在这种情况下意图将为空 如果您返回START_REDELIVER_INTENT,则无论何时服务被终止,都将使用之前创建的服务创建它 查看此链接以了解有关后台服务的更多信息 https://developer.android.com/reference/android/app/Service.html

Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        if (new Date().getTime() - startListeningTime.getTime() >= SCROBBLE_TIME_PERIOD) {
            ///... write song to db
            currentSong = null;
        }
        return START_STICKY;//if you write START_STICKY service will always stay at background.
    }
  

UPD。在另一篇文章中我读到,在android中,永远不可能使服务生活(当手机打开时)。所以当android杀死我的服务时,我将丢失来自currentSong和startListeningTime变量的信息。我应该将这种信息存储在其他地方(在哪里?),或者有一些工作方法可以阻止服务强行关闭?   

您可以将所有信息存储到内部存储或数据库中。如果只存储基本类型(或者可以使用GSON将复杂类型存储到其中),则可以使用SharedPreferences。

在此应用程序中,如果您有定期作业,则可以使用Alarm Manager,并在30秒内启动服务。
每次运行startService方法时都会调用OnStartCommand。所以你不是在创建新服务,而是向它发送意图。