无法检查AlarmManager是否设置了警报

时间:2015-06-05 16:57:22

标签: android android-intent service 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来检查它。)

请在我出错的地方帮忙。

2 个答案:

答案 0 :(得分:17)

In order for this check to work, you need to be absolutely sure that the PendingIntent only exists when the alarm is set. There are 2 things you can do to ensure that is so:

1) When testing your code, make sure that you uninstall your application and then reinstall your application before testing it. Uninstalling your app will remove any PendingIntents that your app might have created that are still pending.

2) When you cancel the alarm, make sure that you also cancel the PendingIntent. You can do this with

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

答案 1 :(得分:0)

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

Bassically你要求一个名为AlarmReceiver的普遍存在的意图。但是他的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);
    }
}