Создать синхронизированное уведомление (например, о событиях) в Android - PullRequest
5 голосов
/ 06 января 2012

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

Для этой цели следует обратить внимание на классы AlarmManager, NotificationManager und Notification.Builder, верно?

Так как мне заранее создать синхронизированное уведомление? Мой код (пока) это:

Добавьте это в AndroidManifest для регистрации приемника вещания:

<receiver android:name="AlarmNotificationReceiver"></receiver>

Создайте новый файл класса, который обрабатывает получаемый им сигнал тревоги:

public class AlarmNotificationReceiver extends BroadcastReceiver {

    public void onReceive(Context context, Intent intent) {
        Bundle extras = intent.getExtras();
        if (extras != null) {
            String additionalData = extras.getString("displayText");
            // show the notification now
            NotificationManager mNotificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
            Notification mNotification = new Notification(R.drawable.ic_launcher, context.getString(R.string.app_name), System.currentTimeMillis());
            PendingIntent pi = PendingIntent.getActivity(context, 0, new Intent(context, MainActivity.class), 0); // open MainActivity if the user selects this notification
            mNotification.setLatestEventInfo(context, context.getString(R.string.app_name), additionalData, pi);
            mNotification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.DEFAULT_SOUND;
            mNotificationManager.notify(1, mNotification);
        }
    }

}

Используйте этот код (например, в MainActivity), чтобы установить будильник на 3 секунды:

    Intent i = new Intent(this, AlarmNotificationReceiver.class);
    i.putExtra("displayText", "sample text");
    PendingIntent pi = PendingIntent.getBroadcast(this.getApplicationContext(), 234324246, i, 0);
    AlarmManager mAlarm = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
    mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+3*1000, pi);

Что мне нужно изменить, чтобы сделать эту работу? Спасибо!

Две проблемы:

  1. Текст уведомления не изменяется при изменении его в коде. Это только изменяется, когда я изменяю requestCode в PendingIntent.getBroadcast (...). О чем этот код запроса? Это может быть случайное значение или 0?
  2. После перезагрузки телефона «запланированное» уведомление или сигнал тревоги исчезли. Но теперь я видел, что это нормальное поведение, верно? Как я могу обойти это?

Ответы [ 2 ]

4 голосов
/ 09 января 2012

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

Итак, вам понадобится широковещательный приемник, чтобы перехватить намерение BOOT_COMPLETED:

public class BootReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        // get your stored alarms from your database
        // reregister them with the alarm manager
    }
}

Чтобы получить намерение BOOT_COMPLETED, вы должны указать в своем манифесте следующее разрешение:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

И BootReceiver также должен быть зарегистрирован в вашем манифесте со следующим фильтром намерений:

    <receiver android:enabled="true" android:name=".receiver.BootReceiver"
    android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
        <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED" />
                <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

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

1 голос
/ 06 января 2012

Лично я бы сделал это без широковещательного приемника.Я бы заставил AlarmManager запустить отдельное действие, а не получателя.Тогда эта новая активность может сделать уведомление для вас.Я не уверен, что это лучший способ, но он кажется мне менее сложным.

Редактировать: Сервис, вероятно, был бы еще лучше, чем Деятельность

В вашей основной деятельности:

Intent i = new Intent(getBaseContext(), NotificationService.class);
PendingIntent pi = PendingIntent.getService(getBaseContext(), 0, i, 0);
AlarmManager mAlarm = (AlarmManager) Context.getSystemService(Context.ALARM_SERVICE);
mAlarm.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+10*60*1000, pi);

Ваш сервис:

public class NotificationService extends Service {

public int onStartCommand(Intent intent, int flags, int startId) {   

//Create the notification here

return START_NOT_STICKY;
}

Ваш манифест:

<service android:name="com.android.yourpath.NotificationService"></service>
...