Ben
Ben

Reputation: 362

How do you start an Activity with AlarmManager in Android?

I've poured through a dozen tutorials and forum answers about this problem, but still haven't been able to get some working code together. I'll try to keep the question straightforward:

How do you use AlarmManager (in the Android API) to start an Activity at a given time? Any solution to this problem will do.

My latest attempt to achieve this is below.

(Imports omitted. I expect MyActivity to start 3 seconds after the program is opened, which it doesn't. There are no error messages to speak of.)

public class AndroidTest2Activity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        Context context = this;//.getApplicationContext();

        AlarmManager manager = (AlarmManager) getSystemService(Context.ALARM_SERVICE); // CORRECT
        Intent intent = new Intent(context, myReceiver.class); // CORRECT
        PendingIntent pending = PendingIntent.getBroadcast( context, 0, intent, 0 ); // CORRECT
        manager.set( AlarmManager.RTC, System.currentTimeMillis() + 3000, pending ); // CORRECT

        setContentView(R.layout.main);
    }
}

public class myReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        Intent i=new Intent(context, myActivity.class);
        i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        context.startActivity(i);
    }
}

public class myActivity extends Activity {
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        Log.d("", "Elusive success");
        setContentView(R.layout.main);
    }
}

Any advice would be appreciated.

Please note: I've got myReceiver in the manifest already

Upvotes: 15

Views: 25258

Answers (8)

Ben
Ben

Reputation: 362

I had this problem too long ago to know which answer is correct, but thank you to everyone for their responses. I'm self-answering so the question isn't still open.

Upvotes: 0

moein shojaei
moein shojaei

Reputation: 55

Main Problem : if you close completely you're app and expect to start you're activity after 3 seconds, you wrong. because when you close you're app , you're app cant receive broadcast, for solve this problem use services instead of broadcasts.

Point: when you're service would ran ,you cant start your activity if your app wouldn't in foreground.

Solution: I think when your service started you can again set Alarmmanager to start your activity with PendingIntent for just now.

Remember :

  1. When you create your intent for pass it to pendingIntent add the FLAG_ACTIVITY_NEW_TASK to it.
  2. For this PendingIntent use PendingIntent.getActivity() method and for the first PendingIntent use PendingIntent.getService() method.

I hope this help you.

Upvotes: 1

Amir Dadgari
Amir Dadgari

Reputation: 551

In my experience you can achieve this without broadcast receiver, just use PendingIntent.getActivity() instead of getbroadcast()

private void setReminder(){

AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
            Calendar startTime = Calendar.getInstance();
            startTime.add(Calendar.MINUTE, 1);
            Intent intent = new Intent(ReminderActivity.this, ReminderActivity.class);
            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            PendingIntent pendingIntent = PendingIntent.getActivity(ReminderActivity.this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT);
            alarmManager.set(AlarmManager.RTC, startTime.getTimeInMillis(), pendingIntent);   
}

I've tested this code on android O but I'm not sure about other android versions please inform me if this doesn't work on any other android version.

Upvotes: 1

user5815655
user5815655

Reputation: 11

you are not sending any broadcast for the receiver to receiver and further more it lokks like u want a splash screen or something like that for that purpose u can start a new thread wait for some sec then start ur activity in that and for that time period u can do what ever u want on the UI thread ...

Upvotes: 0

Muhammad Sohail iqbal
Muhammad Sohail iqbal

Reputation: 63

add this in your android mainifest file and it will hopefully work

<activity android:name=".MyReceiver" />
        <receiver android:name=".MyReceiver"> </receiver>

Upvotes: 1

Dean Panayotov
Dean Panayotov

Reputation: 332

In case someone else stumbles upon this - here's some working code (Tested on 2.3.3 emulator):

public final void setAlarm(int seconds) {
    // create the pending intent
    Intent intent = new Intent(MainActivity.this, AlarmReceiver.class);
    // intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    pendingIntent = PendingIntent.getBroadcast(MainActivity.this, 0,
            intent, 0);
    // get the alarm manager, and scedule an alarm that calls the receiver
    ((AlarmManager) getSystemService(ALARM_SERVICE)).set(
            AlarmManager.RTC, System.currentTimeMillis() + seconds
                    * 1000, pendingIntent);
    Toast.makeText(MainActivity.this, "Timer set to " + seconds + " seconds.",
            Toast.LENGTH_SHORT).show();
}

public static class AlarmReceiver extends BroadcastReceiver {
    public void onReceive(Context context, Intent intent) {
        Log.d("-", "Receiver3");
    }
}

AndroidManifest.xml:

    <receiver android:name="com.example.test.MainActivity$AlarmReceiver" >
    </receiver>

Issues with BenLambell's code :

  • EITHER:
    • Move the receiver to it's own .java file or
    • make the inner class static - so it can be accessed from outside
  • Receiver is not declared correctly in the manifest:
    • if it's an inner class in MainActivity use: <receiver android:name="package.name.MainActivity$AlarmReceiver" ></receiver>
    • if it's in a separate file: <receiver android:name="package.name.AlarmReceiver" ></receiver>

If your intention is to display a dialog in the receiver's onReceive (like me): that's not allowed - only activities can start dialogs. This can be achieved with a dialog activity.

You can directly call an activity with the AlarmManager:

Intent intent = new Intent(MainActivity.this, TriggeredActivity.class);
PendingIntent pendingIntent = PendingIntent.getActivity(MainActivity.this, 0, intent, PendingIntent.FLAG_ONE_SHOT);
((AlarmManager) getSystemService(ALARM_SERVICE)).set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + seconds * 1000, pendingIntent);

Upvotes: 8

CommonsWare
CommonsWare

Reputation: 1007624

How do you use AlarmManager (in the Android API) to start an Activity at a given time?

Supply a PendingIntent to the set() call that identifies the activity to start up. Or, do what you're doing, which should work just fine.

This sample project is a bit elaborate, because it's 19 tutorials deep into one of my books, but if you look at classes like EditPreferences, OnBootReceiver, and OnAlarmReceiver, you will see the same basic recipe that you're using above. In this case, I could have just used a getActivity() PendingIntent, but the tutorial after this one gives the user a choice of launching an activity or displaying a Notification, so a BroadcastReceiver makes more sense.

Look for warnings in addition to errors in LogCat. Most likely, your receiver or activity is not in your manifest.

Note that popping up an activity out of the middle of nowhere is generally not a good idea. Quoting myself from the book in question:

Displaying the lunchtime alarm via a full-screen activity certainly works, and if the user is looking at the screen, it will get their attention. However, it is also rather disruptive if they happen to be using the phone right that instant. For example, if they are typing a text message while driving, your alarm activity popping up out of nowhere might distract them enough to cause an accident. So, in the interest of public safety, we should give the user an option to have a more subtle way to remind them to have lunch.

Upvotes: 4

jainal
jainal

Reputation: 3021

According to Java convention class name begin with Capital letter.So change your

"myReceiver" to "MyReceiver" and  "myActivity" to "MyActivity".

Then add your receiver in the manifest file like the below.

<application 
------------
<receiver android:name="MyReceiver"></receiver>
---------------------
</application>

Upvotes: 0

Related Questions