Как начать активность с AlarmManager в Android? - PullRequest
9 голосов
/ 13 августа 2011

Я пролистал дюжину учебных пособий и ответов на форумах по этой проблеме, но все еще не смог собрать какой-то рабочий код.Я постараюсь уточнить вопрос:

Как вы используете AlarmManager (в API Android), чтобы запустить действие в определенный момент времени?Любое решение этой проблемы подойдет.

Моя последняя попытка добиться этого приведена ниже.

(Импорт пропущен. Я ожидаю, что 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 в манифесте

Ответы [ 6 ]

6 голосов
/ 07 февраля 2014

В случае, если кто-то еще наткнется на это - вот некоторый рабочий код (протестирован на эмуляторе 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, используйте: <receiver android:name="package.name.MainActivity$AlarmReceiver" ></receiver>
    • если это в отдельном файле: <receiver android:name="package.name.AlarmReceiver" ></receiver>

Если вы хотите отобразить диалог в 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);
4 голосов
/ 13 августа 2011

Как вы используете AlarmManager (в Android API), чтобы запустить действие в определенный момент времени?

Введите PendingIntent для вызова set(), который идентифицирует действие для запуска. Или делай то, что делаешь, и это должно работать нормально.

Этот пример проекта немного сложен, потому что он содержит 19 уроков в одной из моих книг, но если вы посмотрите на классы, такие как EditPreferences, OnBootReceiver и OnAlarmReceiver, вы увидеть тот же базовый рецепт, который вы используете выше. В этом случае я мог бы просто использовать getActivity() PendingIntent, но после этого урока пользователь может выбрать запуск действия или отображение Notification, так что BroadcastReceiver имеет больше смысла.

Ищите предупреждения в дополнение к ошибкам в LogCat. Скорее всего, ваш получатель или деятельность не в вашем манифесте.

Заметьте, что выскочить из ниоткуда действия, как правило, не очень хорошая идея. Цитирую себя из рассматриваемой книги:

Отображение будильника во время обеда в полноэкранном режиме, безусловно, работает, и если пользователь смотрит на экран, он привлечет их внимание. Тем не мение, это также довольно разрушительно, если они используют телефон правильно, что мгновенный. Например, если они печатают текстовое сообщение во время вождения, ваш тревожная активность, появляющаяся из ниоткуда, может отвлечь их достаточно, чтобы вызвать несчастный случай. Таким образом, в интересах общественной безопасности, мы должны дать пользователю возможность есть более тонкий способ напомнить им, чтобы они пообедали.

1 голос
/ 13 июля 2018

По моему опыту, вы можете достичь этого без широковещательного приемника , просто используйте 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.

1 голос
/ 28 февраля 2015

добавьте это в свой основной файл Android, и, надеюсь, оно будет работать

<activity android:name=".MyReceiver" />
        <receiver android:name=".MyReceiver"> </receiver>
0 голосов
/ 20 января 2016

вы не отправляете никакой трансляции для получателя получателю и, более того, это выглядит так, как будто вы хотите заставку или что-то в этом роде, вы можете запустить новый поток, подождать несколько секунд, а затем начать свою деятельность в этом и дляэтот период времени вы можете делать то, что вы хотите в потоке пользовательского интерфейса ...

0 голосов
/ 13 августа 2011

В соответствии с соглашением Java имя класса начинается с заглавной буквы. Измените

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

Затем добавьте получателя в файл манифеста, как показано ниже.

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