简体   繁体   中英

setRepeating of AlarmManager is only triggering for the first time and not repeating

I am trying to implement an alarm manager that will be called every day to update a database. I started by trying the set Function of the alarmManager and it worked to trigger the alarm at a certain time. Then I moved on to try and use setRepeating to trigger the alarm on a daily basis. The setRepeating function which is done to Repeat every minute just for testing is only working the first time and is not doing the function repeatedly.

Here is my BroadcastReceiver:

package com.example.bleh.myapplication;

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.example.bleh.myapplication.DB.AppDatabase;
import com.example.bleh.myapplication.DB.Plan;
import com.example.bleh.myapplication.DB.User;
import com.example.bleh.myapplication.Utils1.FormulaUtils;
import com.github.lzyzsd.circleprogress.DonutProgress;

public class AlarmReceiver extends BroadcastReceiver {

    private static final String DEBUG_TAG = "AlarmReceiver";
    public AppDatabase mydb;
    Plan plan;

    @Override
    public void onReceive(Context context, Intent intent) {
        Toast.makeText(context, "Alarm worked.", Toast.LENGTH_LONG).show();
        mydb = AppDatabase.getInstance(context);
        final long planid = intent.getExtras().getLong("planid");
        final long userid = intent.getExtras().getLong("uid");
        final String requirements = intent.getExtras().getString("requirements");
        Log.wtf("PlanId: ",planid+"");
        Log.wtf("UserId: ",userid+"");
        Log.wtf("Requirements",requirements);
        plan = mydb.getPlanDao(context).getPlanById((int) planid);
        final User user = mydb.getUserDao(context).getUserById((int) userid);
        plan.setCurrentWeight(FormulaUtils.reCalculateWeight(plan.getCurrentWeight(), Double.parseDouble(requirements)));
        plan.setBmr(Double.parseDouble(FormulaUtils.calculateBmr(user.getSex(), plan.getCurrentWeight(), user.getHeight(), user.getBirthDay())));
        plan.setNbOfDays(plan.getNbOfDays() - 1);
        mydb.getPlanDao(context).update(plan);
        String requirement = FormulaUtils.CalulcateDailyRequirements(plan.getWorkoutPerWeek(), plan.getBmr());
        String day = plan.getNbOfDays() + "";
        float progress = 0F;

        // Start feature2 activity with updated data
        Intent updateFeature2Intent = new Intent(context, feature2.class);
        updateFeature2Intent.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP | Intent.FLAG_ACTIVITY_CLEAR_TOP); // Add this flag
        updateFeature2Intent.putExtra("requirement", requirement);
        updateFeature2Intent.putExtra("day", day);
        updateFeature2Intent.putExtra("progress", progress);
        context.startActivity(updateFeature2Intent);
    }

}

Here is my Feature Activity:

package com.example.bleh.myapplication;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.graphics.Color;
import android.net.Uri;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.TimePicker;
import android.widget.Toast;

import com.example.bleh.myapplication.DB.AppDatabase;
import com.example.bleh.myapplication.DB.Exercise;
import com.example.bleh.myapplication.DB.Food;
import com.example.bleh.myapplication.DB.Plan;
import com.example.bleh.myapplication.DB.User;
import com.example.bleh.myapplication.Utils1.FormulaUtils;
import com.github.lzyzsd.circleprogress.DonutProgress;

import java.text.DecimalFormat;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

public class feature2 extends AppCompatActivity {

    public AppDatabase mydb;
    TextView BMR,requirements,days;
    Button addfood,addex,nextday;
    LinearLayout mainLayout;
    Button Meas,Bluetooth;
    DonutProgress donutProgress;
    Plan plan;

    // Add this method
    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);

        // Get data from intent
        String requirement = intent.getStringExtra("requirement");
        String day = intent.getStringExtra("day");
        float progress = intent.getFloatExtra("progress", 0F);

        // Update UI
        TextView requirements = findViewById(R.id.requirements);
        TextView Days = findViewById(R.id.days);
        DonutProgress dailyProgress = findViewById(R.id.donut_progress);

        requirements.setText(requirement);
        Days.setText(day);
        dailyProgress.setProgress(progress);
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_feature2);
        Intent intent = getIntent();
        requirements = findViewById(R.id.requirements);
        donutProgress = findViewById(R.id.donut_progress);
        days = findViewById(R.id.days);
        final long planid = intent.getExtras().getLong("planid");
        final long userid = intent.getExtras().getLong("uid");
        mydb = AppDatabase.getInstance(feature2.this);
        plan = mydb.getPlanDao(feature2.this).getPlanById((int) planid);
        try {
            requirements.setText(FormulaUtils.CalulcateDailyRequirements(plan.getWorkoutPerWeek(), plan.getBmr()));
        }
        catch (Exception ex)
        {
            Log.wtf("There is no plan","!");
        }
        Intent intent1 = new Intent(this, AlarmReceiver.class);
        intent1.putExtra("uid", userid);
        intent1.putExtra("planid", planid);
        intent1.putExtra("requirements",requirements.getText().toString());
        Calendar updateTime = Calendar.getInstance();
        updateTime.setTimeZone(TimeZone.getTimeZone("GMT"));
        updateTime.set(Calendar.HOUR_OF_DAY, 8);
        updateTime.set(Calendar.MINUTE, 3);
        updateTime.set(Calendar.SECOND,0);
        Date milliseconds = updateTime.getTime();
        long millis = milliseconds.getTime();
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0,
                intent1, PendingIntent.FLAG_ONE_SHOT);
        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        alarmManager.setRepeating(AlarmManager.RTC, millis ,60000, pendingIntent);
        Toast.makeText(this, "Alarm set", Toast.LENGTH_LONG).show();
    }
}

Here is my Manifest Part:

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

I had encountered this problem earlier with my app
Repeating alarms will not trigger for api > 23 if phone is in idle state. Refer Schedue Repeating alarms
Doze mode also blocks the alarm.

What you can do is to use and for and use your own logic to repeat the alarm. for 并使用您自己的逻辑来重复警报。

if (Build.VERSION.SDK_INT >= 23) {
      alarmManager.setExactAndAllowWhileIdle(RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
} else {
      alarmManager.setExact(RTC_WAKEUP, calendar.getTimeInMillis(), alarmIntent);
}



In your case set the alarm again in the AlarmReceiver for next day.

I'd recommend you to read about Doze mode and this topic . Also you can use this lib by Evernote. It helps to handle scheduling of background tasks.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM