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

标签 java android service retrofit

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

我希望该服务手动启动,但希望该服务在不手动停止的情况下自动停止。

这是我的服务等级

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;
        }
    }
}

这是家庭 Activity 类启动服务和停止服务的方法。当用户分别单击打卡和打卡按钮时,将调用这些方法。

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

这是接收器类,

public class AutoStopReceiver extends BroadcastReceiver {

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

在AndroidMenifest.xml中注册接收器

<receiver android:name=".AutoStopReceiver" />

关于java - 如果服务正在运行,如何在晚上 8 点停止该服务?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60716792/

相关文章:

java - 将 NumberPicker 值添加到数据库

java - IntentService 中的 RegisterReceiver,跟踪 SmsManager

android - 将 GPS 坐标从 Android 发送到服务器

android - SharedPreferences 未在发布版本中实例化

.net - 将数据传递给自定义 Windows 服务

C# - 是否可以让单个 .exe 充当应用程序(单击时)或服务(由 Windows 运行时)

java - Java 中的一维条码扫描器(使用来自捕获设备的图像)实现

java - 我可以在一个 Spring Integration 流程中使用 2 个聚合器吗?

android - 为什么不推荐使用 onAttach(Activity Activity )?

android - 如何在 Android Wear 中永久运行服务