无法检查警报是否已由 AlarmManager 设置

Unable to check if alarm has been set by AlarmManager

我正在检查 AlarmManager 是否已经使用 this answer 设置了警报。

以下是我的代码片段。

boolean alarmUp = (PendingIntent.getBroadcast(MainActivity.this, 0,
    new Intent(MainActivity.this, AlarmReceiver.class), PendingIntent.FLAG_NO_CREATE) != null);
if (alarmUp) {
    // alarm is set; do some stuff
}

Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
final PendingIntent pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);

AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
manager.setInexactRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), 10 * 1000, pendingIntent);

但是,alarmUp 始终被设置为 true。也就是说,无论我是否设置闹钟,每当我重新启动我的应用程序时,它都会告诉我 alarmUp 是真的(我通过制作 Toast 来检查它)。

请帮助我哪里出错了。

因为 API 21 你可以使用

public AlarmManager.AlarmClockInfo getNextAlarmClock ()

http://developer.android.com/reference/android/app/AlarmManager.html#getNextAlarmClock()


现在,您尝试使用的代码:

(PendingIntent.getBroadcast(MainActivity.this, 0,
    new Intent(MainActivity.this, AlarmReceiver.class), PendingIntent.FLAG_NO_CREATE) != null);

基本上,您要求的是一个名为 AlarmReceiver 的 previus 和现有 intent。但是他的AlarmReceiver是指你自己的BroadcastReceiver。

正如您在之前发布的答案的这一行中所见:

boolean alarmUp = (PendingIntent.getBroadcast(context, 0, 
    new Intent("com.my.package.MY_UNIQUE_ACTION"), 
    PendingIntent.FLAG_NO_CREATE) != null);

他们使用 "MY_UNIQUE_ACTION" 来查看意图是否存在。

您还可以在此站点中看到使用它的教程:

http://justcallmebrian.com/2010/04/27/using-alarmmanager-to-schedule-activities-on-android/


除非您能够访问 android-系统 AlarmReceiver 并查看意图是否存在,否则您将无法请求 'generic' 预定警报。那是你想要做的吗?如果是这种情况,您确定如果您没有任何预定的警报,系统无论如何都不会创建 android-系统 AlarmReceiver 意图吗? 似乎我们无法像我们喜欢的那样控制那些组件。


一个工作示例: Manifest.xml:

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.blablabla.testa" >
<uses-permission android:name="android.permission.WAKE_LOCK" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/app_name" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>

        <receiver
            android:name=".MySuperReceiver"
            android:label="MySuperReceiverName" />

    </activity>
</application>

MySuperReceiver.java

package com.blablabla.testa;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;

import java.util.Calendar;

public class MySuperReceiver extends BroadcastReceiver {
    public static final String TAG = MySuperReceiver.class.getSimpleName();
    public static final String ACTION_ALARM_RECEIVER = "ACTION_ALARM_RECEIVER";
    private Calendar c = Calendar.getInstance();

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent != null)
            if (ACTION_ALARM_RECEIVER.equals(intent.getAction())) {
                Log.d(TAG, new Exception().getStackTrace()[0].getMethodName() + " " + c.getTime());
                //do something here
            }
    }
}

和MainActivity.java:

package com.blablabla.testa;

import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;


public class MainActivity extends ActionBarActivity {

    public static final String TAG = "TEST APP:";

    AlarmManager alarmManager;


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

        GetAlarmService();
        CreateAlarm();
        CheckForAlarm();
        CancelAlarms();
        CheckForAlarm();
    }

    private void GetAlarmService()
    {
        alarmManager = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
        Log.d(TAG, " GET Alarm Service ! ");
    }
    private void CreateAlarm()
    {
        long aroundInterval = 1*60*1000; 

        Intent intent = new Intent(getApplicationContext(), MySuperReceiver.class);
        intent.setAction(MySuperReceiver.ACTION_ALARM_RECEIVER);//my custom string action name

        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//used unique ID as 1001
        alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis(), aroundInterval, pendingIntent);//first start will start asap

        Log.d(TAG, " CREATE Alarm ! ");
    }

    private void CancelAlarms()
    {
        Intent intent = new Intent(getApplicationContext(), MySuperReceiver.class);//the same as up
        intent.setAction(MySuperReceiver.ACTION_ALARM_RECEIVER);//the same as up
        PendingIntent pendingIntent = PendingIntent.getBroadcast(getApplicationContext(), 1001, intent, PendingIntent.FLAG_CANCEL_CURRENT);//the same as up
        alarmManager.cancel(pendingIntent);//important
        pendingIntent.cancel();//important

        Log.d(TAG, " Cancel Alarm ! ");
    }

    private void CheckForAlarm()
    {
        //checking if alarm is working with pendingIntent #3
        Intent intent = new Intent(getApplicationContext()  , MySuperReceiver.class);//the same as up
        intent.setAction(MySuperReceiver.ACTION_ALARM_RECEIVER);//the same as up
        boolean isWorking = (PendingIntent.getBroadcast(getApplicationContext() , 1001, intent, PendingIntent.FLAG_NO_CREATE) != null);//just changed the flag
        Log.d("TAG: TEST APP:  ", "alarm is " + (isWorking ? "" : "not") + " working...");

    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

为了使此检查生效,您需要绝对确保 PendingIntent 仅在设置警报时存在。您可以做两件事来确保这一点:

1) 测试您的代码时,请确保卸载您的应用程序,然后在测试之前重新安装您的应用程序。卸载您的应用程序将删除您的应用程序可能已创建但仍处于待处理状态的任何 PendingIntent

2) 取消闹钟时,请确保同时取消PendingIntent。您可以使用

Intent alarmIntent = new Intent(MainActivity.this, AlarmReceiver.class);
final PendingIntent pendingIntent = 
          PendingIntent.getBroadcast(MainActivity.this, 0, alarmIntent,
          PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null) {
    pendingIntent.cancel();
}