2012-01-06 15 views
5

Bazı Android uygulamalarında, şu özelliği entegre etmek istiyorum: Kullanıcı, bir şeyi hatırlatmak istediğinde bir zaman tanımlayabilir. Zaman geldiğinde, uygulama şu anda kullanıcı uygulamayı kullanmadığında bile bildirim çubuğunda bir bildirim oluşturmalıdır.Android için zamanlanmış bildirim (ör. Olaylar için) oluşturma

Bu amaçla, AlarmManager, NotificationManager und Notification.Builder sınıfları bakılacak olanlar, değil mi?

Önceden zamanlanmış bir bildirim nasıl oluşturabilirim?

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

} 
:

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

aldığı Şu alarmı kolları yeni sınıf dosyası oluşturun:

yayın alıcısı kayıt AndroidManifest için altında ekleyin: Kodum (şimdiye kadar) bu

kullanımı (MainActivity örneğin) bu kod artık 3 saniye alarm ayarlamak:

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

Bu işi yapmak için neyi değiştirmem gerekiyor? Teşekkür ederim!

iki sorun vardır: Ben kodunda değiştirdiğinizde

  1. Bildirim metni değiştirmez. Yalnızca PendingIntent.getBroadcast (...) içindeki requestCode'u değiştirdiğimde değişir. Bu talep kodu nedir? Rastgele bir değer mi, yoksa 0 mı?
  2. Telefonum yeniden başlatıldıktan sonra "planlanmış" bildirimi veya alarm gitti. Ama şimdi bunun normal davranış olduğunu gördüm, doğru mu? Bunu nasıl atlatabilirim?
+1

Şimdiye kadar ne çalışmıyor? –

cevap

4
Bir Servis muhtemelen MainActivity olarak

bir Activity daha iyi hala olurdu

Bölüm 1'den emin değil, fakat 2. kısım için genel yaklaşım BOOT_COMPLETED amacını engellemek ve tüm alarmları tekrar kaydetmek için kullanmaktır. Bu ne yazık ki, alarm yöneticisi ile kaydettiğiniz her alarm için uygulamanızın db'sinde de saklamanız gerektiği anlamına gelir.

Yani, BOOT_COMPLETED niyet yolunu kesmek için bir yayın alıcısı gerekir:

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

Ve:

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 niyet elde etmek için, Manifest'inizde şu izin koymalıdır BootReceiver'ın ayrıca aşağıdaki amaç filtresine sahip bildiriminize kaydedilmesi gerekir:

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

Uygulamanız sdcard'a yüklüyse, BOOT_COMPLETED amacını asla alamaz. Ayrıca, bu uygulamanın, başlangıçta kullanıcının telefonunu yavaşlatabilen, önyüklemede kodu derhal yürütmesi açısından biraz naif olduğunu belirtmek gerekir. Öyleyse, önyükleme kararını yakaladıktan sonra birkaç dakika boyunca yürütmenizi geciktirmenizi öneririz.

+0

Teşekkür ederiz! Bunu yapmanın başka yolu yok mu? Bu biraz (çok) karmaşık geliyor. Ek bir izne ihtiyacınız var ve bu kayıt eylemlerini gerçekleştirmelisiniz. Her neyse, uygulama başına alarm sayısı sınırlı değil mi? Her uygulamanın sadece bir alarmı kaydetmesine izin verildiğini ve bundan sonra da öncekilerin üzerine yazılacağını düşünüyorum. Yoksa bu bildirim kuralı mıdır? – caw

+0

Maalesef bunu yapmanın başka yolu yok. Bildirimlerin sınırlamalarından emin değilim, ancak emin olmadan birden fazla alarmı kaydedebileceğinizi biliyorum. – danh32

+0

Burada anlattığınız şeyi yapmak zorundayım, tamam :) Bu alarmların kimliklerini saklamam gerekiyor mu? Ya da onları depolamaksızın yeni alarmlar oluşturabilir miyim? – caw

1

Kişisel olarak bir Yayın Alıcısı olmadan yaparım. AlarmManager'ı alıcıdan ziyade ayrı bir Aktivite başlatma niyetini tetiklerim. Sonra bu yeni Etkinlik sizin için bildirim yapabilir. Bunun daha iyi bir yol olup olmadığından emin değilim, ama bana göre daha az karmaşık görünüyor.

Düzenleme:

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

Servis:

public class NotificationService extends Service { 

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

//Create the notification here 

return START_NOT_STICKY; 
} 

Sizin Bildirim:

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

Teşekkür ederiz! Hizmet kullanmanın neden bir Yayın kullanmanın daha iyi olduğunu açıklayabilir misiniz? Alarmları kapsayan birkaç sayfada yayınları olan örneği buldum. – caw

+0

Bu kişisel tercih gerçekten. Benim için bir Servis daha basit bir yol gibi görünüyor, çünkü Alarmı, Yayın'ı çalıştırmak için Alarm'ı ayarlamak yerine ve ardından Eylem'i çalıştırmak için Yayın'ı almak yerine, belirli bir zamanda Servis'i çalıştırmak üzere ayarlıyorsunuz. Yayın yöntemini çalıştırmak için özel bir niyet yazmanız gerektiğini düşünüyorum. –

+0

Ah, tamam. Ancak belgeler, bir servisin uzun süren arka plan görevleri için olduğunu söylüyor. Bu yüzden bir yayın kullanmayı tercih ettiğimi düşündüm. Ve buradaki soruda (http://stackoverflow.com/questions/1026973/android-whats-the-difference-between-the-various-methods-to-get-a-context), birinin getBaseContext'i kullanmaması gerektiğini söylüyorlar();) – caw

İlgili konular