0

I have a need to set a daily alarm. I have read the many questions/solutions here and followed what I felt would work. I can see that my alarms are being set (thanks to this post). I see the Alarms set and get rescheduled for repeat 24hrs later but my receiver does not get called. so I have to assume the problem is in my implementation of the AlarmReceiver.

My Manifest file looks like this:

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

<application
    android:allowBackup="true"
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >

     <activity
        android:name="com.TLD.testclock.TestClock"
        android:configChanges="orientation|keyboardHidden|screenSize"
        android:label="@string/app_name"
        android:theme="@style/FullscreenTheme" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

      <receiver android:name="com.TLD.testclock.AlarmReceiver"
         android:enabled="true"
         android:exported="true" 
         android:permission="android.permission.WAKE_LOCK" /> 

My setAlarm Code:

alarmMgr = (AlarmManager) context.getSystemService(ALARM_SERVICE);
Intent intent = new Intent(TestClock.this, AlarmReceiver.class);
intent.putExtra("AlarmId", mAlarm.alarmId);
pendingIntent = PendingIntent.getActivity(TestClock.this,
            mAlarm.alarmId, intent, pendingIntent.FLAG_UPDATE_CURRENT);

// Set the alarm
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP,
            alarmCalendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY,
            pendingIntent);

The receiver Activity:

public class AlarmReceiver extends Activity {
private MediaPlayer mPlayer;
private WakeLock mWakeLock;

@Override
@SuppressWarnings("deprecation")
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Log.v("AlarmReceiver", "Alarm finished?");

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "my wakelock");
    mWakeLock.acquire();
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(
            WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_FULLSCREEN
                    | WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED
                    | WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);

    setContentView(R.layout.alarm_alert);
    // intent.getExtra("AlarmId", mAlarm.alarmId);
    Button stopalarm = (Button) findViewById(R.id.dismiss);

    stopalarm.setOnClickListener(new View.OnClickListener() {...

The system alarm dump shows:

RTC_WAKEUP #3: Alarm{40bc13f8 type 0 com.TLD.testclock} 

type=0 when=+6h39m58s976ms repeatInterval=86400000 count=1    

operation=PendingIntent{40b5f218: PendingIntentRecord{40bc13c0 com.TLD.testclock startActivity}}

Broadcast ref count: 0   

Alarm Stats:

com.TLD.testclock  27ms running,
2 wakeups    2 alarms: flg=0x4 cmp=com.TLD.testclock/.AlarmReceiver

I've been at this for days, but the dump tool finally proved the alarms were truly set. Does an alarm receiver have to be a broadcast receiver? I saw an alarm receiver work here so I thought I would follow the example. I get no errors, but it isn't working for me. Can anyone see what I'm doing wrong?

Community
  • 1
  • 1
bob
  • 688
  • 8
  • 15

1 Answers1

0

Check the AlarmManager documentation. The AlarmManager.set() method explicitly states that it will send the Intent as a broadcast. You have your manifest setup with a receiver tag, but the class specified is an Activity rather than a BroadcastReceiver. Also, when you created your PendingIntent for registration with AlarmManager, you're creating an Intent for an Activity rather than a BroadcastReceiver. If you really need an Activity to pop up when the Alarm triggers, just have your BroadcastReceiver fire an explicit Intent for your internal Activity to show the user to alarm happened.

Larry Schiefer
  • 15,687
  • 2
  • 27
  • 33
  • Thanks. I can't figure out why the youtube (20:00 mark) example works as an activity since you point out that AlarmManager.set seems to require a broadcast. I've been pulled away from this project and will try your solution by next week and report back. – bob Feb 20 '14 at 11:54
  • The AlarmManager may be smart enough to figure out that the PendingIntent is targeted at an Activity rather than a Broadcast, but it is certainly not the documented way. From the video and the log capture you provide, it appears as though it should work. In this case, the problem is because your manifest file does not declare AlarmReceiver as an Activity, but rather as a BroadcastReceiver. Change it to be an Activity with no IntentFilter. That will make the Activity non-exported, which is fine for your purposes. The PendingIntent executes with the permissions and scope of your application. – Larry Schiefer Feb 20 '14 at 14:49
  • It took me a while to get back to this but I changed the AlarmReceiver to an activity in the manifest file. This appears to have fixed it. Thanks for the help Larry. – bob Feb 24 '14 at 15:53