如何在 Android 中使用 AlarmManager 启动 Activity?

发布于 2024-11-29 12:56:40 字数 1500 浏览 2 评论 0原文

我已经浏览了十几个关于这个问题的教程和论坛答案,但仍然无法将一些工作代码放在一起。我会尽量让问题简单明了:

如何使用 AlarmManager(在 Android API 中)在给定时间启动 Activity?任何解决这个问题的方法都可以。

我为实现这一目标所做的最新尝试如下。

(省略导入。我希望 MyActivity 在程序打开后 3 秒启动,但事实并非如此。没有任何错误消息可言。)

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

任何建议将不胜感激。

请注意:我已经在清单中找到了 myReceiver

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

叹梦 2024-12-06 12:56:40

万一其他人偶然发现了这一点 - 这里有一些工作代码(在 2.3.3 模拟器上测试):

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>

BenLambell 代码的问题:

  • 要么:
    • 将接收器移至其自己的 .java 文件或
    • 使内部类静态 - 以便可以从外部访问
  • 接收器未在清单中正确声明:
    • 如果它是 MainActivity 中的内部类,请使用:
    • 如果它位于单独的文件中:
      <接收器 android:name="package.name.AlarmReceiver" >

如果您的目的是在接收器的 onReceive 中显示对话框(像我一样):那是不允许的 - 仅限活动可以启动对话。这可以通过对话框活动来实现。

您可以直接使用 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);

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);
書生途 2024-12-06 12:56:40

如何使用 AlarmManager(在 Android API 中)在给定时间启动 Activity?

set() 调用提供一个 PendingIntent 来标识要启动的活动。或者,做你正在做的事情,这应该很好。

这个示例项目有点复杂,因为它是 19教程深入我的一本书,但如果您查看 EditPreferencesOnBootReceiverOnAlarmReceiver 等类,您就会请参阅您在上面使用的相同基本配方。在这种情况下,我可以只使用 getActivity() PendingIntent,但是本教程之后的教程让用户可以选择启动活动或显示 通知,因此 BroadcastReceiver 更有意义。

在 LogCat 中查找除错误之外的警告。最有可能的是,您的接收器或活动不在您的清单中。

请注意,突然出现一个活动通常不是一个好主意。引用我自己在相关书中的说法:

通过全屏活动显示午餐时间闹钟确实有效,
如果用户正在看屏幕,就会引起他们的注意。然而,
如果他们碰巧正确使用手机,也会造成相当大的破坏
立即的。例如,如果他们在开车时输入短信,您的
突然出现的警报活动可能会分散他们的注意力
造成事故。因此,为了公共安全,我们应该给用户一个选择
有更微妙的方式来提醒他们吃午饭。

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.

苏佲洛 2024-12-06 12:56:40

将其添加到您的 android mainifest 文件中,希望它能正常工作

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

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

<activity android:name=".MyReceiver" />
        <receiver android:name=".MyReceiver"> </receiver>
北笙凉宸 2024-12-06 12:56:40

根据我的经验,您可以在没有广播接收器的情况下实现此目的,只需使用PendingIntent.getActivity()而不是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);   
}

我已经测试了此代码在 android O 上,但我不确定其他 Android 版本,如果这不适用于任何其他 Android 版本,请通知我。

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.

决绝 2024-12-06 12:56:40

主要问题:如果您完全关闭应用程序并期望在 3 秒后开始您的活动,那么您就错了。因为当你关闭你的应用程序时,你的应用程序无法接收广播,为了解决这个问题,请使用服务而不是广播。

要点:当你的服务运行时,如果您的应用程序不在前台,您将无法启动您的活动。

解决方案:我认为当您的服务启动时,您可以再次设置 Alarmmanager 以刚刚使用 PendingIntent 启动您的活动。

记住

  1. 当您创建意图并将其传递给 pendingIntent 时,请添加 FLAG_ACTIVITY_NEW_TASK 到其中。
  2. 对于此 PendingIntent 使用 PendingIntent.getActivity() 方法,对于第一个 PendingIntent 使用 PendingIntent.getService() 方法。

我希望这对你有帮助。

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.

如歌彻婉言 2024-12-06 12:56:40

根据 Java 约定,类名以大写字母开头。因此更改您的

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

然后将您的接收器添加到清单文件中,如下所示。

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

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>
亢潮 2024-12-06 12:56:40

您没有向接收器发送任何广播,而且您可能想要一个启动屏幕或类似的东西,为此您可以启动一个新线程等待几秒钟,然后在该时间段内开始您的活动你可以在 UI 线程上做任何你想做的事...

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

从﹋此江山别 2024-12-06 12:56:40

我很久以前就遇到了这个问题,不知道哪个答案是正确的,但感谢大家的回复。我正在自我回答,所以问题尚未解决。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文