12

I am checking if the alarm has already been set by the AlarmManager using this answer.

Following is my code snippet.

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

However, alarmUp is always being set as true. That is, whether I set the alarm or not, whenever I restart my app, it tell me that alarmUp is true (I am checking it by making a Toast).

Please help where I am going wrong.

Community
  • 1
  • 1
Kevin Richards
  • 570
  • 1
  • 6
  • 23

2 Answers2

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();
}
David Wasser
  • 93,459
  • 16
  • 209
  • 274
0

Since API 21 you can use

public AlarmManager.AlarmClockInfo getNextAlarmClock ()

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


Now, the code that you are trying to use:

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

Bassically you are asking for a previus and existent intent called AlarmReceiver. But his AlarmReceiver refers to your own BroadcastReceiver.

As you can see in this line of the answer that you posted before:

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

They use "MY_UNIQUE_ACTION" to see if the intent exists.

Also in this site you can see a tutorial using that:

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


Unless you are able to access the android-system AlarmReceiver and see if the intent exists, you will not be able to ask for a 'generic' scheduled alarm. Is that what you are trying to do? If it's the case, are you sure that in case that you don't have any scheduled alarm the android-system AlarmReceiver intent was not created by the system anyway? Seems we don't have control to those components like we like to.


An working example: 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
            }
    }
}

And 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);
    }
}
mayo
  • 3,845
  • 1
  • 32
  • 42
  • Is there no way to may it work of API earlier than 21? All I want to know is if my app has already set an alarm. – Kevin Richards Jun 13 '15 at 14:22
  • mmm, so if you setted an alarm using your own BroadcastReceiver you should be able to read that register. Here is another link with another example : http://blog.mokrzycki.io/2015/01/working-example-of-setting-alarm-with-repeating-stuff-checking-if-alarm-was-set-with-pendingintent/ – mayo Jun 13 '15 at 14:27
  • I have done the same thing as mentioned in #2 in your link. And that is exactly what is not working as mentioned in my question. – Kevin Richards Jun 13 '15 at 14:31
  • Did you added the lines in your manifest? What if you change the name of your receiver and check if for the first time you also get null on getBroadcast? – mayo Jun 13 '15 at 14:37
  • Yes, I did. I don't see how changing the name would be relevant? No, when the app first starts, the alarm is not up. – Kevin Richards Jun 13 '15 at 14:50
  • mm, so when your alarmUp is true,, after cancell the intent? (I'm starting to code here :) ) – mayo Jun 13 '15 at 14:56
  • Ok, here I have an example where you get the alarm system, enable an alarm, check the status, disable an alarm and check the status,, seems to be working.. http://we.tl/hUm7eignb9 – mayo Jun 13 '15 at 15:06