Я хочу, чтобы мой сервис работал один раз в день, но вместо этого он работает несколько раз - PullRequest
0 голосов
/ 15 октября 2018

Я хочу создать приложение, в котором оно уменьшает целочисленное значение на 1 каждый день в определенное время.Для этого я использую BroadcastReceiver, который предположительно активируется в 12 часов утра.А из BroadcastReceiver я вызываю службу, которая создает фоновый поток для изменения значения в базе данных (база данных MySQL), а затем закрывает службу. Проблема в том, что значения уменьшаются на 1 несколько раз в день, а не только один раз. Вот код:

Манифест

<receiver
    android:name=".myAlarm"
    android:enabled="true"
    android:exported="true"></receiver>

<service android:name=".myService"
    android:enabled="true"
    android:exported="true" />

Main

Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, 23);
        calendar.set(Calendar.MINUTE, 59);
        calendar.set(Calendar.SECOND, 0);

        AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
        Intent intent = new Intent(Main.this, myAlarm.class);

        PendingIntent pendingIntent = PendingIntent.getBroadcast(this.context, 0, intent, 0);

        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT && Build.VERSION.SDK_INT >=  Build.VERSION_CODES.DONUT) {
            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                    AlarmManager.INTERVAL_DAY, pendingIntent);
        }
        else if(Build.VERSION.SDK_INT >=  Build.VERSION_CODES.KITKAT)
        {
            alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                     AlarmManager.INTERVAL_DAY, pendingIntent);
        }

MyAlram (BroadcastReceiver)

public class myAlarm extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {

            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                context.startForegroundService(new Intent(context.getApplicationContext(), myService.class));
            } else {
                context.startService(new Intent(context.getApplicationContext(), myService.class));
            }
    }

}

myService (Сервис)

public class myService extends Service{

    private DBWorkers mydb;
    private Thread backgroundThread;
    private Context context;
    private Boolean isRunning = false;

    /**
     * Called by the system when the service is first created.  Do not call this method directly.
     */
    @Override
    public void onCreate() {
        super.onCreate();
        this.context = this;
        this.backgroundThread = new Thread(myTask);

        if (Build.VERSION.SDK_INT >= 26) {
            String CHANNEL_ID = "my_channel_01";
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);

            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

            Notification notification = new NotificationCompat.Builder(this)
                    .setContentTitle("")
                    .setContentText("").build();

            startForeground(1, notification);
        }
    }

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

    private Runnable myTask = new Runnable() {
        @Override
        public void run() {

            mydb = new DBWorkers(context);

            ArrayList<Worker> myList = new ArrayList<>(mydb.getAllWorkersService());
            ArrayList<Worker> newList = new ArrayList<>();

            //visa and work are the values I need to decrement daily
            for(Worker item : myList){
                int work = item.getWork(), visa = item.getVisa();

                if(visa > 0)
                {
                    visa = visa - 1;
                }
                else if(visa < 0)
                {
                    visa = 0;
                }

                if(work > 0)
                {
                    work = work - 1;
                }
                else if(work < 0)
                {
                    work = 0;
                }

                if(item.getVisa() != visa || item.getWork() != work){
                    newList.add(new Worker(item.getName(), visa, work, item.getId()));
                }
            }

            mydb.updateAllWorkers(newList);

            stopSelf();
        }
    };


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {


        if (!isRunning){
            isRunning = true;
            backgroundThread.start();
        }

        return START_STICKY;
    }

    /**
     * Called by the system to notify a Service that it is no longer used and is being removed.  The
     * service should clean up any resources it holds (threads, registered
     * receivers, etc) at this point.  Upon return, there will be no more calls
     * in to this Service object and it is effectively dead.  Do not call this method directly.
     */
    @Override
    public void onDestroy() {
        super.onDestroy();
    }
}

У меня также есть несколько других вопросов:

1) Мне лучше использовать IntentService, а не обычный сервис?и почему?

2) Я не знаю, что происходит в приведенном ниже коде.Я скопировал и вставил его из ответа в Интернете, потому что мой код не работал на моем телефоне, и я думаю, что это потому, что ОС моего телефона 8.0, и это было предложенное решение.Я был бы очень признателен за вашу помощь, объяснив ее мне.

String CHANNEL_ID = "my_channel_01";
            NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                    "Channel human readable title",
                    NotificationManager.IMPORTANCE_DEFAULT);

            ((NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

            Notification notification = new NotificationCompat.Builder(this)
                    .setContentTitle("")
                    .setContentText("").build();

            startForeground(1, notification);

3) Нужно ли создавать фоновый поток для выполнения этой задачи или он будет автоматически выполняться нафоновый поток, поскольку приложение, скорее всего, будет убито?

Большое вам спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...