首页 > 解决方案 > 我希望我的服务每天工作一次,但它却工作多次

问题描述

我想创建一个应用程序,它每天在特定时间将整数值减 1。为此,我使用了一个据说在上午 12 点被激活的 BroadcastReceiver。从 BroadcastReceiver,我正在调用一个服务,该服务创建一个后台线程来修改数据库(MySQL 数据库)中的值,然后关闭该服务。问题是这些值每天会减少 1 次,而不是只减少一次。这是代码:

显现

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

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

主要的

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(广播接收器)

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

}

我的服务(服务)

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)我是否需要创建一个后台线程来运行此任务,或者它会自动在后台线程上执行,因为应用程序很可能会被杀死?

太感谢了!

标签: androidservicebroadcastreceiveralarmmanager

解决方案


推荐阅读