AlarmManager birkaç cihazda çalışmıyor


85

Uygulamam AlarmManager kullanıyor ve 4 yıldan beri çalışıyor. Ancak bazı cihazlarda başarısız olmaya başladığını fark ettim.

Kodun doğru olduğundan oldukça eminim (WakefulBroadcastReceiver kullanıyorum ve Doze özellikli cihazlar için ExactAndAllowWhileIdle kullanıyorum) çünkü Nexus cihazlarda mükemmel çalışıyor, ancak bazı üreticilerin cihazlarında (Huawei, Xiaomi ...) başarısız oluyor.

Örneğin Huawei cihazları, uygulamaları öldüren bir tür pil yöneticisine sahiptir ve bir uygulama öldürüldüğünde, programlanan alarmlar iptal edilir. Bu nedenle, Huawei pil yöneticisinde bir uygulamayı "korumalı" olarak ayarlamak sorunu çözer.

Ancak son zamanlarda daha fazla cihazla çalışmadığını fark ettim: Xiaomi, Samsung (belki de yeni "Smart Manager" ile ilgili?) ... Görünüşe göre bu davranış bir standart haline geliyor: arka plan uygulamalarını öldürmek.

Bunun hakkında bir şey bilen var mı? Alarmın çalıştırılmasını sağlamanın herhangi bir yolu var mı?

DÜZENLEME: Bu soruna farklı üreticiler tarafından eklenen "pil tasarrufu" neden olur. Daha fazla bilgi burada: https://dontkillmyapp.com/


8
Üreticiler, güç tüketimi için uygulamaları suçluyor ve daha az çekirdekli CPU'ya kıyasla daha fazla pil tüketen Octa çekirdeklerini pazarlamaya devam ediyorlar. Sadece bir çekirdek eklemenin telefonlarını hızlandıracağını mı düşünüyorlar?
FrozenFire

1
@AviLevinshtein Belki sorunuzu yanlış anladım. Aktivitemde alarmları oluşturuyorum. Ardından, alarm çaldığında, bir yayın alıcısı çalıştırılır ve son olarak bir WakefulIntentService (@commonsware'den bir sınıf) yürütülür.
Sergio Viudes

2
@JFValdes Hala bir çözüm arıyorum. AlarmManager, Vanilla Android'e sahip cihazlarda mükemmel çalışıyor. Sorun şu ki, üreticiler Android özelliklerini "geliştirmeye" çalışıyorlar ve AlarmManager'ı bozdular ... Üreticiler, standart Doze modunu kullanıyorlarsa kendi "pil koruyucularını" uygulamamalı, AlarmManager mükemmel şekilde çalışacaktır ... çözüm için ...
Sergio Viudes

1
Henüz bir çözüm var mı? Hatırlatıcılar gibi diğer uygulamalar bunu nasıl yapıyor? Alarmlar için olan, hatırlatıcılar için değil setAlarm'dan başka bir seçenek daha olmalı
kv1dr

1
@SergioViudes, izleme için Xiomi cihazlarında da aynı sorunla karşılaşıyorum. ve aşağıdaki ayarları yaparak 4 cihazdan 3'ünde uygulamamı pil tasarrufu kısıtlamasından uzak tutarsam -> Pile git -> Güç -> Uygulama pil tasarrufu -> uygulamanız Şimdi seçin Kısıtlama yok (Arka plan ayarları için) ve ardından Arka plan konumu için İzin ver seçeneği
Imran Khan Saifi

Yanıtlar:


17

Birkaç haftadır çözmeye çalışıyorum. Ben hiçbir şey bulamadım. Huawei bir süre sonra tüm alarmları kapatır. Uygulamayı pil tasarrufundaki korumalı uygulamaya koyarsam yardımcı olmaz. Ancak uygulamamın paket adını alarm, saat veya takvim gibi kelimeleri içerecek şekilde değiştirirsem, diğer cihazlarda olduğu gibi kesinlikle normal çalışır. Google'ın bu saçmalık için nasıl sertifika verebileceğini anlamıyorum. OEM'in çekirdek platformu bu şekilde değiştirmemesi gerektiğini düşünüyorum. Kullanıcı kullanmadığında bir süre sonra uygulamayı öldüren kendi meyilli koruyucusuna sahip olduklarını anlıyorum. Ancak bu öldürme alarmları, korumalı uygulamalarda da var.

Ayrıca setAlarmClock () alarmları kesin zamanlamaya yardımcı olur. Ancak bunu widget güncellemesi gibi düşünenler için kullanmak mümkün değil.

Güncelleme: Paket adı anahtar kelimelerine göre koruma, mevcut Huawei cihazlarında zaten çalışmıyor, 2017'de doğruydu.


Benim gibi, ben de deniyorum ama bu sorunu bazı markalar Xiaomi, Oppo, Huawei üzerinde çözmenin hiçbir yolu yok. Bazen pilden tasarruf etmek için arka plan sürecini ve alarmı durdururlar.
Andi Susilo

1
Huawei telefonum var, paket adını alarm / takvim olarak değiştirmek hiçbir şey yapmıyor. Bunu atlamanın tek yolu uygulamanızı telefon yöneticisinden korumalı uygulama listesine ekleyin
Ashish Pardhiye

9

Sorun Smart Manager'dır. Samsung, bazı uygulamaların arka planda çalışmasını zaman zaman devre dışı bırakan bir pil yöneticisine sahiptir. Uygulamaya geri dönerken "devam ettirmeyi" denedi, ancak uygulamayı tamamen devre dışı bırakır veya her 5 dakikada bir devam edebilir (Samsung'un sahip olma şekline bağlı olarak).

Bu, Samsung Manager olmadığı için android'in stok sürümlerinde çalışacaktır. Ayrıca, SM'yi etkinleştirmek için bazı özelliklere sahip (rom'a bağlı olarak) özel android sürümünü de yükleyebilirsiniz.


Deliriyorum çünkü test edecek Samsung cihazım yok. Yalnızca uygulamamın kullanıcılarının bana ne söylediğini biliyorum. Sorunun, AlarmManager'ın uygulama öldüğü için çalışmaması olduğunu biliyor musunuz? Veya sorun şu ki, bu yönetici yüzünden alarm çaldığında cihaz uyanamıyor mu?
Sergio Viudes

@SergioViudes Son zamanlarda birçok şirket kendi şirketlerini uyguluyor. LG'nin Samsung'a benzer çalışan bir tane olması gibi, telefonunuzda olabilir mi? Sorun alarm değil, alarm uygulaması tamamen devre dışı kaldığı bir duruma itiliyor. Smart Manager, ihtiyacınız olmayan rastgele bir uygulama olduğunu düşünüyor. Bazı uygulamaların bunu geçebileceğini fark ettim, belki bazı uygulamalar akıllı yönetici tarafından kabul ediliyor.
SA

1
@SergioViudes Test etmem gereken bir samsung var ve bundan alabileceğiniz pek bir şey olmadığını söyleyebilirim. Akıllı yönetici uygulamanızı optimize ettiğinde, herhangi bir hata veya başka bir şey olmaz, sadece zorla durdurmaya benzer şekilde ölür. Hala son uygulamalar listesinde
Tim

Teşekkürler Tim. Uygulamaları "Akıllı" Yönetici'den hariç tutmak zorunda kalmadan bu sorunu çözmek harika olur.
Sergio Viudes

xiaomi (miui), vivo ve htc gibi cihazlar, "güvenilir" uygulamalar listesinde kendilerinin belirlediği bir uygulama olmadığı sürece (whatsapp, truecaller vb. varsayılan olarak güvenilirdir) bir dizi izni varsayılan olarak yanlış olarak ayarlar. ). Bu kodlayıcıların kabusu haline geliyor
desidigitalnomad

4

Modern Android cihazların çoğu, otomatik olarak pilden nasıl tasarruf edileceğini anlamaya çalışan ve sonuç olarak belirli 3. taraf uygulamalarını öldürebilen bir uygulama veya mekanizma ile birlikte gelir. Bu, planlanan görevlerin ve işlerin kaldırılmasına neden olabilir (örn. Alarmların kapanmaması, push bildiriminin çalışmaması vb.). Çoğu durumda bu, Android'in pil tasarrufu mekanizmalarından tamamen bağımsız olarak gerçekleşir, benim durumumda bazı cihaz modellerini tespit ettiğimde daha fazla pil optimizasyonu yapamadım, kullanıcıyı uygulamamı beyaz listeye almak için başlangıç ​​yöneticisine yönlendiriyorum

Bu bağlantıda her model için https://android-arsenal.com/details/1/6771 çağırmanız gereken niyeti buldunuz.


2

5.0'dan az cihaz için AlarmManager'ı ve 5.0+ cihaz için JobScheduler'ı kullanın. JobScheduler'ın üretici hilekarlıklarından etkilenmeyeceğini kesin olarak söyleyemem, ancak Android'in insanları AlarmManager'dan JobScheduler'a taşımaya çalıştığı düşünüldüğünde, bu benim için çok daha az olası görünüyor.

DÜZENLEME: Google, WorkManager adlı bu soruna birinci taraf bir çözüm buldu . Birden çok planlama çerçevesini özetler ve cihaz için en uygun olanı kullanır.


2
Ne yazık ki, AlarmManager sınıfının aksine, JobScheduler kullanılırken zamanlama kesin değildir. Uygulamamda zamanlama kesin olmalıdır :(
Sergio Viudes

Denedim ve bazı optimizatörler (en azından samsung), ekran kapandığında JobScheduler'daki tüm bekleyen görevleri kapattı. Yani o da kırılmış. Bu 5.0'da gerçekleşir. 6.0'a güncelledikten sonra iyi çalışıyor, sanırım bunu düzelttiler. Henüz diğer üreticilerle test edemedim.
2016

Tam zamanlama için bir arka plan hizmeti veya planlanmış bir hizmet kullanamazsınız. Bir ön plan hizmeti deneyebilirsiniz, ancak bu, kullanıcı için kalıcı bir bildirim oluşturur (muhtemelen istenmeyen) ve bazı telefonlarda, ön plan hizmetini otomatik olarak yok edecek yerleşik görev sonlandırıcılar bulunur. WorkManager en iyi çözümdür, ancak maalesef size kesin zamanlamaları vermeyecektir.
Tom

1

Ayrıca alarmları ayarlayan bir uygulamam var. Çözüm, api> = 21'de AlarmManager.setAlarmClock () kullanmaktır . Bu, doze afaik'ten etkilenmez ve sistem tepsisine bir alarm saati simgesi koyma avantajına sahiptir.


Cevabınız için teşekkürler. Çalar saat simgesini kaldırmanın bir yolu var mı?
Sergio Viudes

Maalesef setAlarmClock bazen çalışmıyor. Düşük hafızalı Oreo cihazında test ettim.
Boris Salimov

1

Bu geç olabilir ama umarım birine yardımcı olur.

Aynı soruna çok uzun süre takılıp kaldım. Ama şimdi bu sorunu nasıl çözeceğimi biliyorum. Bu, aynı sorunu yaşayan herkes içindir. İnsanlar AutoStart'ı etkinleştirmeniz gerektiğini söylüyor ama ben otomatik başlatmayı kullanmadan başardım.

Öncelikle, WakeFullBroadcastaReceiver artık kullanımdan kaldırıldı ve BroadcastReceiver'ı kullanmalısınız. İkinci olarak, BackgroundService yerine ForegroudService'i kullanmanız gerekir.

Size aşağıdaki örneği vereceğim:

IntentService.class

public class NotificationService extends IntentService {


//In order to send notification when the app is close
//we use a foreground service, background service doesn't do the work.



public NotificationService() {
    super("NotificationService");
}

@Override
public void onCreate() {
    super.onCreate();

}

@Override
public int onStartCommand(@Nullable Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);

    //There is no difference in the result between start_sticky or start_not_sticky at the moment
    return START_NOT_STICKY;
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {

    //TODO check if the app is in foreground or not, we can use activity lifecyclecallbacks for this

    startForegroundServiceT();
    sendNotification(intent);
    stopSelf();
}


/***
 * you have to show the notification to the user when running foreground service
 * otherwise it will throw an exception
 */
private void startForegroundServiceT(){

    if (Build.VERSION.SDK_INT >= 26) {
        String CHANNEL_ID = "my_channel_01";
        NotificationChannel channel = new NotificationChannel(CHANNEL_ID,
                "Channel human readable title",
                NotificationManager.IMPORTANCE_DEFAULT);

        ((NotificationManager) 
   getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);

        Notification notification = new Notification.Builder(this, CHANNEL_ID)
                .setContentTitle("")
                .setContentText("").build();

        startForeground(1, notification);
    }
}

private void sendNotification(Intent intent){

    //Send notification
    //Use notification channle for android O+
}
}

BroadcastReceiver.class içinde ön plan hizmetini başlatın

public class AlarmReceiver extends BroadcastReceiver {


@Override
public void onReceive(Context context, Intent intent) {


    Intent service = new Intent(context, NotificationService.class);
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
        context.startForegroundService(service);
    } else {
        context.startService(service);
    }

}
}

Ve setAlarms şöyle:

 public static void setAlarm(Context context, int requestCode, int hour, int minute){


    AlarmManager alarmManager =( AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context//same activity should be used when canceling the alarm
            , AlarmReceiver.class);
    intent.setAction("android.intent.action.NOTIFY");

    //setting FLAG_CANCEL_CURRENT makes some problems. and doest allow the cancelAlarm to work properly
    PendingIntent pendingIntent = PendingIntent.getBroadcast(context, 1001, intent, 0);

    Calendar time = getTime(hour, minute);

    //set Alarm for different API levels
    if (Build.VERSION.SDK_INT >= 23){
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pendingIntent);
    }
    else{
        alarmManager.set(AlarmManager.RTC_WAKEUP,time.getTimeInMillis(),pendingIntent);
    }

O zaman alıcıyı ve ön hizmet hizmetini manifestte bildirmelisiniz.

       <receiver android:name=".AlarmReceiver"
        android:enabled="true"
        android:exported="true">
        <intent-filter>
            <action android:name="android.intent.action.NOTIFY">

            </action>
        </intent-filter>
    </receiver>
    <service
        android:name=".NotificationService"
        android:enabled="true"
        android:exported="true"></service>

Umarım bu birisine yardımcı olur.


ama kimse olumlu oy vermiyor mu? @ keivan.k
gumuruh

0

Günümüzde yeni telefonların çoğu, anlattığınız aynı şeyi yapan bir tür pil / güç tasarrufu yöneticisi ile birlikte gelir. duboosterları ve temiz ustaları saymaz.

Uygulama / oyun mağazası girişinize, bu uygulamanın düzgün çalışması için pil yöneticisi uygulamanızın dışında bırakılması gerektiğini belirten bir sorumluluk reddi beyanı veya SSS eklemeniz gerektiğini düşünüyorum.


Bunu yapmanın başka bir yolu olmalı ... Kullanıcılar feragatnameyi okumaz. Samsung telefonlarının uygulamaların AlarmManager'ı kullanmasına izin vermediğini düşünemiyorum ...
Sergio Viudes

Alarmlar "zamanında" devreye girmeyecek, ancak sonunda başlayacaklar
Gavriel

Bu (ne yazık ki) en yararlı cevap diyorum. Keşke daha iyi bir çözüm olsaydı, ancak donanım üreticileri mükemmel çalışan vanilya Android'e zarar veriyor.
2016,

0

AlarmManager'ı kullanmayı bir süre önce bıraktım ... daha iyi ve daha kararlı bir alternatif

  1. bir hizmet oluştur
  2. BOOT_COMPLETED için bir BroadcastReceiver kaydettirin
  3. hizmetini alıcıdan ateşle
  4. hizmetinizin içinde her X dakikada bir döngü oluşturan yeni bir İşleyici başlatın ( Android - postDelayed () çağrısını kullanarak düzenli aralıklarla bir yöntem çalıştırma )
  5. görevi yürütme zamanının gelip gelmediğini kontrol edin: şimdi - yürütme süresi> 0 ( Java'da iki tarih arasındaki farkın süresi nasıl bulunur? )
  6. eğer öyleyse .. görevi yürütün ve işleyiciyi durdurun

evet .. bu bir acı..ama ne olursa olsun iş bitirilsin


3
Öneriniz için teşekkürler, ancak bu yaklaşımdan kaçınmak isterim çünkü AlarmManager'ı kullanmak RAM veya herhangi bir kaynak tüketmez. Ve uygulamanız öldürülürse, hizmet durur, değil mi?
Sergio Viudes

Bu yaklaşımın BOOLETPROOF olduğunu söylemedim, ama en azından farklı api sürümlerinden oluşuyor :)
ymz

1
Güvenilir bir şekilde çalışmak için bu çözümün muhtemelen uyandırma kilitleri de kullanması gerekir ve bu çok büyük miktarlarda pil tüketir.
Paweł Nadolski

Sanırım bu konuda haklısınız .. tek soru şudur: en kötüsü ne olur - güvenilmez kod mu kötü performans mı? her neyse, kişisel olarak bazı durumlarda uygun olabilecek alternatif kilit yolları olduğunu düşünüyorum (örneğin: stackoverflow.com/questions/5346694/… )
ymz

ancak, ana mekanizma - Broadcas alıcısı - denmiyor \
Noor Hossain

0

BOOT_COMPLETED için dinliyor musunuz? Bir cihaz yeniden başlatıldığında alarmları yeniden ayarlamanız gerekir.


Evet. Dediğim gibi, alarmlar şu ana kadar 2012'den beri çalışıyordu. Cihaz yeniden başlatıldığında BOOT_COMPLETED yayın alıcısında alarmları yeniden programlıyorum.
Sergio Viudes

1
Uygulamanızın yeniden çalışması için yeniden başlatmayı zorunlu kılmak yarım çözüm bile değil
Tim

1
@TimCastelijns, söylediğim hiç de bu değil. Cihaz yeniden başlatılırsa, alarm yöneticisiyle ayarlanan tüm alarmlar yeniden ayarlanmalıdır.
Tyler Pfaff

@TylerPfaff evet ancak cihazın yeniden başlatılması bu sorudaki sorunla ilgili değil
Tim

0

Bu cihazlar Android'in hangi sürümünü çalıştırıyor?

API 23'ten itibaren, işletim sistemi bir süre kullanılmadığında düşük güçte bekleme moduna geçecek ve bu modda alarmlar gönderilmeyecektir. Uygulamaların açıkça "Bu alarmın pil kullanımına bakılmaksızın şu anda kapanmasına ihtiyacım var" demesinin bir yolu vardır, ancak; yeni AlarmManager yöntemleri setAndAllowWhileIdle()ve olarak adlandırılır setExactAndAllowWhileIdle().

Açıklamanızdan, belirli OEM'lerin cihazlarındaki sorunlarınızın özel nedeni bu olmayabilir, ancak bu, Alarm Yöneticisi'ni kullanan tüm geliştiricilerin bilmesi gereken bir şeydir.

Son olarak, Alarm Yöneticisinin birçok kullanımı, İş Planlayıcı mekanizmaları kullanılarak daha iyi ele alınır. Geriye dönük uyumluluk için Play Services "GCM Network Manager", işlevsellik açısından Job Scheduler'a çok yakındır - Android'in daha yeni sürümlerinde dahili olarak Job Scheduler'ı kullanır - ve sınıfın adına rağmen mutlaka ağ oluşturma ile ilgili değildir.


Smart Manager bulunan Samsung cihazları Lollipop çalıştırıyor. Zaten Marshmallow cihazları için setExactAndAllowWhileIdle kullanıyorum. JobScheduler ve GCM'ye bir göz atacağım. Her neyse, sorun alarmın çalmaması mı, yoksa alarm çaldığında o cihazın uyanmaması mı bilmiyorum.
Sergio Viudes

0

Uygulamayı öldürmenin alarm yöneticisinin uygulamanızı uyandırmasını engelleyeceğini sanmıyorum.

Yalnızca "durmaya zorladığınızda" veya uygulamayı devre dışı bıraktığınızda, alarm yöneticisinden geri aramaları almadığınızda.

Temel neden başka bir şey olabilir.

Ayrıca M ... setExactAndAllowWhileIdle kısma yaparken ... yani her 2 dakikada bir alarm programlarsanız tetiklenmeyecektir. .. 15 dakika penceresi olması gerekiyor. .


1
Cevabınız için teşekkürler. Ancak, değilse, Smart Manager'da "pil optimizasyonu" devre dışı bırakıldığında uygulama neden mükemmel çalışıyor?
Sergio Viudes

uygulamayı köklü cihazda mı çalıştırıyorsunuz ... evet ise uygulama yöneticisi de uygulamayı devre dışı bırakabilir ..
rupesh jain

Hayır, onu köklü bir cihazda çalıştırmıyorum.
Sergio Viudes

@rupeshjain "yani, her 2 dakikada bir alarm planlıyorsanız tetiklenmeyecektir. .. 15 dakikalık pencere olması gerekir." bu tamamen doğru değil, eğer doğruysa gerçek bir problem. SetExactAndAllowWhileIdle yöntemi için Android Docs içinde zamanlama için tam olarak ne kadar zaman sınırı olduğunu okuyabilirsiniz. Belirli bir uygulama için bu alarmların ne sıklıkla çalacağına ilişkin kısıtlamalar vardır. Normal sistem çalışması altında, düşük güç boşta modlarında bu süre 15 dakika önemli ölçüde daha uzun olabilirken, bu alarmları yaklaşık her dakikadan fazla göndermeyecektir.
eyadMhanna

0

Xiaomi için, uygulamanız için AutoStart'ı etkinleştirmeniz gerekebilir. Bir arka plan sürecini etkileyebilecek Android değişiklikleri listesine (genellikle telefon üreticisinden) yapmaya çalışıyorum. Yeni bir şeyiniz varsa lütfen buraya bir cevap ekleyin Android görev sonlandırıcıların listesi


0

Uygulamamızı, uygulama yöneticisindeki otomatik başlatma yöneticisinde, vivo v5 gibi bazı el cihazlarında etkinleştirmemiz gerekiyor,

In vivo v5'te, bu menüyü iManager -> Uygulama Yöneticisi -> Otomatik Başlatma Yöneticisi'nde bulabiliriz. Uygulamamızı buradan etkinleştirin.

Ardından, alarm / alarm yöneticiniz, uygulama kapatılırsa veya kapatılırsa alarmı tetikleyecektir.


0

Bir cevap arıyordum ve birkaç saat sonra şunu buldum:

https://stackoverflow.com/a/35220476/3174791

Özgeçmişte, uygulamanızın 'Korumalı uygulamalar' tarafından öldürülüp öldürülmediğini bilmenin bir yolu vardır ve bu yalnızca Huawei cihazlarında çalışır. diğer cihazlar (Samsung, Sony, Xiaomi vb.) için herhangi bir çözüm olup olmadığını bana bildirin.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.