如果服务 运行,如何在晚上 8 点停止服务?

How to stop a service at 8 pm if its running?

我有一项服务可以捕获用户的位置并使用改造更新数据库。我想在每天晚上 8 点自动停止服务,如果它 运行 并且还更新用户在晚上 8 点打出的数据库。

我希望服务手动启动,但希望服务在未手动停止时自动停止。

这是我的服务class

public class LiveLocationService extends Service {
    private static final String TAG = LiveLocationService.class.getSimpleName();
    Retrofit retrofitClient;
    CompositeDisposable compositeDisposable = new CompositeDisposable();
    MyService myService;
    String empCode, year, month, date;
    FusedLocationProviderClient client;
    LocationCallback locationCallback;

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        retrofitClient = RetrofitClient.getInstance();
        myService = retrofitClient.create(MyService.class);

        empCode = intent.getStringExtra("empCode");
        year = intent.getStringExtra("year");
        month = intent.getStringExtra("month");
        date = intent.getStringExtra("date");
        return super.onStartCommand(intent, flags, startId);
    }

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

    @RequiresApi(api = Build.VERSION_CODES.O)
    @Override
    public void onCreate() {
        super.onCreate();
        if (isOnline()) {
            buildNotification();
            requestLocationUpdates();
        } else {
            Log.e("MSER", "Please connect to the internet.");
        }
    }

    private void buildNotification() {
        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) {
            String NOTIFICATION_CHANNEL_ID = "com.deepankmehta.managementservices";
            String channelName = "My Background Service";
            NotificationChannel chan = null;
            chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, NotificationManager.IMPORTANCE_HIGH);
            chan.setLightColor(Color.BLUE);
            chan.setLockscreenVisibility(Notification.VISIBILITY_PRIVATE);
            NotificationManager manager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
            assert manager != null;
            manager.createNotificationChannel(chan);

            PendingIntent intent = PendingIntent.getActivity(this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);

            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
            Notification notification = notificationBuilder.setOngoing(true)
                    .setSmallIcon(R.drawable.mser)
                    .setContentTitle("xxxx")
                    .setContentText("xxxx is tracking your location.")
                    .setPriority(NotificationManager.IMPORTANCE_HIGH)
                    .setCategory(Notification.CATEGORY_SERVICE)
                    .setContentIntent(intent)
                    .build();
            startForeground(2, notification);
        } else {
            PendingIntent broadcastIntent = PendingIntent.getActivity(
                    this, 0, new Intent(this, MainActivity.class), PendingIntent.FLAG_UPDATE_CURRENT);
            // Create the persistent notification
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
                    .setContentTitle(getString(R.string.app_name))
                    .setContentText("xxxx is tracking your location.")
                    .setOngoing(true)
                    .setContentIntent(broadcastIntent)
                    .setSmallIcon(R.drawable.mser);
            startForeground(1, builder.build());
        }

    }

    private void requestLocationUpdates() {
        if (isOnline()) {
            LocationRequest request = new LocationRequest();
            request.setInterval(10000);
            request.setFastestInterval(5000);
            request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
            client = LocationServices.getFusedLocationProviderClient(this);
            int permission = ContextCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_FINE_LOCATION);
            if (permission == PackageManager.PERMISSION_GRANTED) {
                locationCallback = new LocationCallback() {
                    @Override
                    public void onLocationResult(LocationResult locationResult) {
                        Location location = locationResult.getLastLocation();
                        if (location != null) {
                            Log.d(TAG, "location update " + location);
                            double lat = location.getLatitude();
                            double lon = location.getLongitude();
                            final String time = new SimpleDateFormat("HH:mm", Locale.getDefault()).format(new Date());
                            compositeDisposable.add(myService.userLocation(empCode, year, month, date, time, lat, lon)
                                    .subscribeOn(Schedulers.io())
                                    .observeOn(AndroidSchedulers.mainThread())
                                    .subscribe(new Consumer< String >() {
                                        @Override
                                        public void accept(String s) throws Exception {
                                            Log.e("data", s);
                                            if (s.equals("\"done\"")) {
                                                Log.e("status", "location punched");
                                            }
                                        }
                                    }));
                        } else {
                            Log.d("MSER", "location update, no location found. ");
                        }
                    }
                };
                client.requestLocationUpdates(request, locationCallback, null);
            } else {
                Log.e("MSER", "Please enable location.");
            }
        } else {
            Log.e("MSER", "Please connect to the internet.");
        }
    }


    @Override
    public void onDestroy() {
        super.onDestroy();
        client.removeLocationUpdates(locationCallback);
        stopForeground(true);
        stopSelf();
    }

    protected boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting()) {
            return true;
        } else {
            return false;
        }
    }
}

这里是首页activityclass启动服务和停止服务的方法。当用户分别点击进入和退出按钮时,将调用这些方法。

 private void startTrackerService() {
        final String date = new SimpleDateFormat("yyyy-MM-dd", Locale.getDefault()).format(new Date());
        final String year = date.substring(0, 4);
        final String month = date.substring(5, 7);
        final String dateToday = date.substring(8, 10);

        Intent intent = new Intent(this, LiveLocationService.class);
        intent.putExtra("empCode", empCode);
        intent.putExtra("year", year);
        intent.putExtra("month", month);
        intent.putExtra("date", dateToday);
        startService(intent);
    }

    private void stopTrackerService() {
        stopService(new Intent(this, LiveLocationService.class));
    }

您可以使用AlarmManager来安排此类任务, 在特定时间注册AlaramManger,检查服务是否为运行,如果是运行则停止服务。

这里是具体时间AlaramManager注册的例子

AlarmManager alarmManager = (AlarmManager) getActivityContext()
                .getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(getActivityContext(), AutoStopReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(getActivityContext(),
                0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,
                stopServieTime, pendingIntent);

这里是接收器 Class,

public class AutoStopReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent) {
          //TODO Stop service from here
    }

在AndroidMenifest.xml

中注册接收器
<receiver android:name=".AutoStopReceiver" />