Android AlarmManager 会在每次应用启动时发送通知,而不是只发送一次

Android AlarmManager send notification every time app starts instead of only once

我的应用使用 AlarmManager 启动 BroadcastReceiverBroadcastReceiver 向用户生成提醒通知。

这是启动闹钟的 MainActivity

public class MainActivity extends ActionBarActivity {

    private PendingIntent pendingIntent;
    private AlarmManager alarmManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        // Set the alarm to start at approximately 2:00 p.m.
        Calendar calendar = Calendar.getInstance();
        calendar.setTimeInMillis(System.currentTimeMillis());
        int curHr = calendar.get(Calendar.HOUR_OF_DAY);

// Checking whether current hour is over 14
        if (curHr >= 14)
        {
            // Since current hour is over 14, setting the date to the next day
            calendar.add(Calendar.DATE, 1);
        }

        calendar.set(Calendar.HOUR_OF_DAY, 14);
// Schedule alarm manager

        Intent myIntent = new Intent(MainActivity.this, MyBroadcastReceiver.class);
        pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, myIntent, 0);

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

        // With setInexactRepeating(), you have to use one of the AlarmManager interval
        // constants--in this case, AlarmManager.INTERVAL_DAY.
        alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
                AlarmManager.INTERVAL_DAY, pendingIntent);


    }

这是生成通知的BroadcastReceiver

public class MyBroadcastReceiver extends BroadcastReceiver {

    @Override
    public void onReceive(Context context, Intent intent)
    {
        PowerManager pm = (PowerManager) context.getSystemService(Context.POWER_SERVICE);

        PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "tag");

        //Acquire the lock
        wl.acquire();

        Log.v("ADebugTag", "It work!");

        int mId = 0;
        //Show the notification here.
        NotificationCompat.Builder mBuilder =
                new NotificationCompat.Builder(context)
                        .setSmallIcon(R.drawable.ic_action_edit)
                        .setContentTitle("Diario Scolastico")
                        .setContentText("You have homeworks for tomorrow!")
                        .setAutoCancel(true)
                        .setDefaults(-1);

// Creates an explicit intent for an Activity in your app
        Intent resultIntent = new Intent(context, MainActivity.class);

// The stack builder object will contain an artificial back stack for the
// started Activity.
// This ensures that navigating backward from the Activity leads out of
// your application to the Home screen.
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the back stack for the Intent (but not the Intent itself)
        stackBuilder.addParentStack(MainActivity.class);
// Adds the Intent that starts the Activity to the top of the stack
        stackBuilder.addNextIntent(resultIntent);
        PendingIntent resultPendingIntent =
                stackBuilder.getPendingIntent(
                        0,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);

        NotificationManager mNotificationManager =
                (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
// mId allows you to update the notification later on.
        mNotificationManager.notify(mId, mBuilder.build());

        //Release the lock
        wl.release();
    }
}

清单权限:

<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.INTERNET" />

<uses-permission android:name="android.permission.VIBRATE" />

<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

如您所见,闹钟必须在下午 14 点开始,但我每次启动应用程序时都会收到通知。 我的代码有问题吗?

我使用Scheduling Repeating Alarms每天同一时间设置闹钟,但不能正常工作

问题是您将时间设置为当天。因此,如果您在 14:00 之后打开您的应用程序,您的警报管理器将立即启动。

您需要检查当天的时间是否14:00,如果是则需要将日期更改为第二天:

Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
int curHr = calendar.get(Calendar.HOUR_OF_DAY);

// Checking whether current hour is over 14
if (curHr >= 14)
{
   // Since current hour is over 14, setting the date to the next day
   calendar.add(Calendar.DATE, 1);
}

calendar.set(Calendar.HOUR_OF_DAY, 14);
// Schedule alarm manager