Soru java.lang.SecurityException:! @ poo 10790 uid 10206 kayıtlı birçok alarm (500)


Alarm Yöneticisi'ni kullanarak Zamanlama alarmı sırasında bu hatayı alıyorum

am.setExact(AlarmManager.RTC_WAKEUP, timeMillis, pendingIntent);

Hata aşağıdaki gibidir

java.lang.SecurityException: !@Too many alarms (500) registered from pid 10790 uid 10206
at android.os.Parcel.readException(Parcel.java:1540)
at android.os.Parcel.readException(Parcel.java:1493)
at android.app.IAlarmManager$Stub$Proxy.set(IAlarmManager.java:206)
at android.app.AlarmManager.setImpl(AlarmManager.java:428)
at android.app.AlarmManager.setExact(AlarmManager.java:376)

Neden bu hata geliyor ve nasıl düzeltebiliyoruz.


30
2018-03-30 11:25


Menşei


"Neden bu hata geliyor" - muhtemelen 500 alarmı kaydetmeyi denediniz. "bunu nasıl düzeltebiliriz" - 500'den fazla alarm kaydetme. Ne zaman, neden, veya bu kod satırını nasıl kullandığınızı bilmediğimizden, size daha spesifik tavsiyeler vermemiz zordur. - CommonsWare
javapapers.com/android/android-alarm-clock-tutorial  örnek ile gitmek .. size yardımcı olabilir - Sukhwant Singh Grewal
Bunun ortaya çıkması da bir neden olabilir Firebase'de bilinen sorun 10.0.0 tarihinde düzeltildi - Richard Le Mesurier


Cevaplar:


Yorumun ne anlama geldiğinden farklı olarak, bu sizin hatanız olmayabilir. Bu, üretim kodunda Mart ayı ortasında bir yerde gerçekleşmeye başlamıştı, bu sadece Samsung'un sadece kısa bir süre önce kullanıma sunulmaya başlandığı Lollipop ile gerçekleşiyor.

Güncelleştirme: Bu sorun, elimizdeki telefonlardan birinde oldu.

@goncalossilva gibi sorunun kullanımı nedeniyle olduğunu söyledi FLAG_CANCEL_CURRENTGörünüşe göre, Samsung, alarm miktarı konusunda 500'lük bir başlık getiriyor ve başka bir tedarikçi bu limite sahip değil.

bir oluştururken PendingIntent ile FLAG_CANCEL_CURRENT Bekleyen niyetini iptal edecektir (belli ki) alarmı iptal etmeyecektir (ayrıca bariz), daha sonra alarmı yeni bekleyen niyetle iptal ederseniz alarmı iptal etmeyecektir ( Intent.filterEquals olmalı true). Söz konusu niyet, eski niyet alarmı iptal edildiği için eski alarmın ateşlenmeyeceği anlamına geliyor, bu yüzden hatalar ile anahtarlama yapmaktan korkmuyoruz. FLAG_UPDATE_CURRENT.

değiştirdikten sonra cihazı yeniden başlatma gereği FLAG_UPDATE_CURRENTYeniden başlatmanız gerekmez, alarmlardan birinin yeni bir alarm için yeni bir yuvaya sahip olmasını sağlamak için ateş etmesini beklemeniz gerekir.

Sorunu çoğaltmak için bu kodu deneyebilir, ardından FLAG_UPDATE_CURRENT ne olduğunu görmek için. sen de koşmalısın "adb shell dumpsys alarm" oluşturulan tüm alarmları görmek için

    AlarmManager alarmManager = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE);

    for (int i = 0; i<1000; i++)
    {
        Intent intent = new Intent("FOOFOOFOO");
        PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        alarmManager.cancel(pendingIntent);

        long firstTime = SystemClock.elapsedRealtime() + 1000;
        alarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, firstTime, pendingIntent);
    } 

40
2018-04-13 16:33



Teşekkürler, düzeltmek için bir fikrin var mı? - Manpreet Patil
Bu durum bizim için de üretime geçiyor ve son zamanlarda başlıyor, bizim tarafımızda herhangi bir değişiklik yapmadan. Lollipop'ta sadece Samsung cihazları ve çoğunlukla (>% 95). - goncalossilva
kullanma adb shell dumpsys alarm Uygulamamızın tüm alarmları sızdırdığını öğrendim, bundan önce görünmüyordu. FLAG_CANCEL_CURRENT öğesinin FLAG_UPDATE_CURRENT olarak değiştirilmesi ve PendingIntents öğesinin aynı olduğundan (bunların oluşturulmasını ortak bir yöntemle ayıklamaktan) emin olmak bizim için çözdü. - Sampo
Bu fırsatı, geliştiricilerin hayatlarını daha kolay ve basit hale getirmek için Samsung'a teşekkür etmek istiyorum. Teşekkür ederim! - fahmy
Bununla ilgili bir haber var mı? Ayrıca bu sorun var ama ben her zaman UPDATE_CURRENT kullanıyorum ve kullandım. - chrisonline


Bu sorunu sadece Lollipop çalıştıran Samsung cihazlarında karşılaşan kullanıcılar için kullanıyorsunuzdur. FLAG_CANCEL_CURRENT seninki ile PendingIntents. Çevirmek FLAG_UPDATE_CURRENT (gerekirse başka düzenlemeler yapmak) ve sorun giderilmelidir.

Tamamen asılsız tahminim, Samsung’un bazı "optimizasyonlar" yapmasıdır. FLAG_CANCEL_CURRENT iptal edilenleri kaldırmazlar PendingIntent hemen silme için işaretleyin ve sonra çok seyrek yapın (ya da hiç değil).

Düzenle

Bu sorunun oluştuğu cihazların kırılmış durumda olduğunu ( PendingIntents?) yeniden başlatılıncaya veya uygulama yeniden yüklenene kadar.


4
2018-04-17 15:16



FLAG_UPDATE_CURRENT kullanıyorum ve ayrıca gerçekleşir. - Zenco
@Zenco, kullanıcılarınızı uygulamanızı yeniden yükledi veya telefonlarını yeniden açtı mı? Bu değişiklikten sonra bizim için hile yapmak gibi görünüyordu. - goncalossilva
Tamam teşekkürler. Hayır, uygulamayı yeniden yüklemediler veya cihazı yeniden başlatmamışlar. Şimdi yeniden başlatma olmadan başka bir geçici çözüm olarak bir try catch bloğu kullanıyorum;) - Zenco
Ben aynı görüyorum ama FLAG_UPDATE_CURRENT kullanırken bile. Alarmları boşaltan bir nexus cihazında herhangi bir zamanda 2'den fazla olmamakla birlikte, kaza anında samsung cihazlarda 500 var. Şu anda kullandığım gibi "window" parametresini kullanmama durumunda bir kullanıcı ile araştırmaya çalışıyorum 300 ms'de bir alarm ve 1000 ms'de bir diğeri için temizlemeyen 1000 ms alarmı. - Andrew


Asla alarm ayarlarken kullandığınız PendingIntents ile FLAG_CANCEL_CURRENT kullanın. Alarmı başka bir zaman için yeniden planlamak isterseniz, herhangi bir bayrağa ihtiyacınız olmaz; Sadece sıfır işaretli bir PendingIntent oluşturun ve sonra bir alarmı ayarlamak için kullanın (): Bu, mevcut alarmı dolaylı olarak iptal eder ve sonra yeni belirtilen zaman için ayarlar. Ancak yeni PendingIntent'i oluştururken FLAG_CANCEL_CURRENT kullandıysanız, Alarm Yöneticisi'nin şimdi iptal edilen PendingIntent ile aynı olduğunu fark etme yeteneğini bozar ve eski olanla birlikte takılıp kalan, teslim edilemeyen, bellek alan ve CPU. Bu hata rafına sahip uygulamaları, sistemde yüzlerce eski alarmı görebiliyorum, fark edilebilir bir performans ve bellek kullanımı isabeti için yeterliydi.

Ekstraları mevcut alarmı yeniden ayarlamaya gerek kalmadan değiştirmek isterseniz, FLAG_UPDATE_CURRENT bunun içindir. Sadece alarmı yeniden programlamak veya iptal etmek isterseniz, bayraklar için sadece 0'ı kullanın.


2
2017-10-08 00:11





Samsung cihazlarındaki en yeni Lollipop yapısının, kayıt yapabileceğiniz alarm sayısını kısıtladığı görülüyor. Uygulamamdaki soruyu geçici olarak herhangi bir zamanda en fazla X alarmı kaydederek düzeltdim (X = 50'yi seçtim ama 499'a kadar çıkabileceğime inandığım hata mesajıyla karar veriyorum. Bunu test etmedim) ancak).

Bir hafta önce bu geçici düzeltmeyle bir sürüm yayınladım ve o zamandan beri bu kilitlenme raporunu almadım.


1
2018-05-05 13:09





Benim için değişiyor FLAG_UPDATE_CURRENT Yalnız benim pendingIntents çoklu girişler kurtulmak için yardımcı olmadı (ile izlendi adb shell dumpsys alarm > dump.txt).

Bekleyen şu niyetleri iptal etme şeklimi değiştirerek düzeltdim

PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();

için

PendingIntent pi = PendingIntent.getBroadcast(context, requestCode, intent, PendingIntent.FLAG_UPDATE_CURRENT).cancel();
alarmManager.cancel(pi);

Bunun için gerekliydi .getBroadcast() ve .getService(). İlginç bir şekilde .getActivity() değildi. Ne yazık ki bunun neden böyle olduğuna dair bir fikrim yok.

Tüm Android 5.0.1 ile bir Samsung Galaxy S4 üzerinde. Belki bu da başka birine yardımcı olur.


1
2018-06-02 12:45



Bir PendingIntent örneğindeki cancel () çağrısı, FLAG_CANCEL_CURRENT kullanılarak aynıdır. Bu yüzden eski alarmları hala sızdırıyordunuz. - ctate


Bayrağı kullanarak düzelttim: PendingIntent.FLAG_UPDATE_CURRENT

PendingIntent pendingIntent = PendingIntent.getService(
    MainActivity.this, 200, intent, PendingIntent.FLAG_UPDATE_CURRENT
);

am.setExact(AlarmManager.ELAPSED_REALTIME, realtime + 2000, pendingIntent);

Android 5.0.1'de çalışan bir Galaxy S4'e test ettim.


-1
2018-05-27 22:17