How do you start an Activity with AlarmManager in

2019-01-14 18:34发布

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

6条回答
三岁会撩人
2楼-- · 2019-01-14 19:12

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.

查看更多
走好不送
3楼-- · 2019-01-14 19:15

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.

查看更多
够拽才男人
4楼-- · 2019-01-14 19:22

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 ...

查看更多
戒情不戒烟
5楼-- · 2019-01-14 19:27

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

<activity android:name=".MyReceiver" />
        <receiver android:name=".MyReceiver"> </receiver>
查看更多
等我变得足够好
6楼-- · 2019-01-14 19:27

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>
查看更多
劳资没心,怎么记你
7楼-- · 2019-01-14 19:35

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);
查看更多
登录 后发表回答