2016-11-25 4 views
0

Следуя docs, мне удалось настроить будильник с помощью AlarmManager, который прекрасно работает, как только я не выключу экран телефона.AlarmManager: Ожидание намерения удалено при выключении экрана

Это выход adb shell dumpsys alarm когда экран находится на:

Batch{1304da7 num=1 start=190708622 end=190708622 flgs=0x1}: 
    RTC_WAKEUP #0: Alarm{f642254 type 0 when 1480059825231 alarm.poc.app} 
     tag=*walarm*:alarm.poc.app.ACTION 
     type=0 whenElapsed=+5m49s424ms when=2016-11-25 02:43:45 
     window=0 repeatInterval=0 count=0 flags=0x1 
     operation=PendingIntent{f78d3a6: PendingIntentRecord{f52e1e7 alarm.poc.app broadcastIntent}} 

Через пару секунд после того, как я поворачиваю экран с моей тревоги исчезает из вывода команд и никогда не вызывается (он работает с экрана на).

Поэтому у меня есть следующие вопросы:

  • Какие другие приложения сделать, чтобы сохранить сигналы в живых? Я могу видеть на выходе adb shell dumpsys alarm газильон других аварийных сигналов, которые не удаляются, даже если я удалю все последние приложения. Я вижу там сигналы тревоги Whatsapp, Google и множество других случайных приложений.
  • Возможно, у всех этих приложений есть функция переднего плана? Я спрашиваю об этом, потому что мне удалось «обойти» проблему, создав неприятную переднюю службу, которая каждые 5 секунд записывает что-то в журнал. Похоже, что работающий сервис предотвращает проблему, но он абсолютно уродлив, и я думаю, что это не очень хорошая идея, чтобы процессор бодрствовал все время.

Это, как я установка сигнализации:

AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);  
Intent intent = new Intent(AlarmReceiver.MY_ACTION); 
intent.putExtra("text", editText.getText().toString()); 
PendingIntent pending = PendingIntent.getBroadcast(this, 42, 
    intent, PendingIntent.FLAG_UPDATE_CURRENT); 
// also tried with getBroadcast(this, 0, intent, 0) 
manager.setExact(AlarmManager.RTC_WAKEUP, millis, pending); 

У меня есть WakefulBroadcastReceiver (не вызывается с выключенным экраном):

public void onReceive(Context context, Intent receivedIntent) { 
    if (MY_ACTION.equals(receivedIntent.getAction())) { 
    System.out.println("good!!!"); 
    String text = receivedIntent.getStringExtra("text"); 
    Intent intentService = new Intent(context, TestService.class); 
    intentService.putExtra("text", text); 
    startWakefulService(context, intentService); 
    System.out.println("service started"); 
    } 
} 

И манифеста:

... 
<uses-permission android:name="android.permission.WAKE_LOCK"/> 
... 
    <service android:name="alarm.poc.app.TestService" 
     android:exported="false"/> 

    <receiver android:name="alarm.poc.app.AlarmReceiver" 
      android:process=":remote"> 
    <intent-filter> 
     <action android:name="alarm.poc.app.ACTION"/> 
    </intent-filter> 
    </receiver> 
... 

Я тестирую на телефоне зефира, minSdkVersion 19 и targetSdkVe rsion 24

ответ

1

Я нашел ответ на свой вопрос.

Дело в том, что я тестирую на телефоне Huawei, и те, у которых есть функция «Защищенные приложения», которая убивает все приложения, когда экран отключается, кроме тех, которые настроены для защиты.

Причина, по которой в выводе dumpsys существует так много других приложений, заключается в том, что Huawei по умолчанию поставляется с некоторыми популярными приложениями, уже «защищенными».

Единственное, что я нашел, это обнаружение телефонов Huawei и попросить пользователя защитить приложение. Этот ответ охватывает такой подход:

"Protected Apps" setting on Huawei phones, and how to handle it

1

Вы должны использовать WakeLocker разбудить устройство, когда сигнал принимается. Создайте новый класс с именем WakeLocker с этим исходным кодом:

package your.packagename; 

import android.content.Context; import android.os.PowerManager; 

public abstract class WakeLocker { 

    private static PowerManager.WakeLock wakeLock; 

    public static void acquire(Context ctx) { 
    if (wakeLock != null) wakeLock.release(); 

    PowerManager pm = (PowerManager) ctx.getSystemService(Context.POWER_SERVICE); 
    wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | 
      PowerManager.ACQUIRE_CAUSES_WAKEUP | 
      PowerManager.ON_AFTER_RELEASE, MainActivity.APP_TAG); 
    wakeLock.acquire(); 
    } 

    public static void release() { 
    if (wakeLock != null) wakeLock.release(); wakeLock = null; 
    } 
} 

и в вызове приемника WakeLocker.acquire(context); как 1-й вещи. Дополнительно: было бы аккуратно позвонить WakeLocker.release();, как только ваш будильник выполнит свою работу.

Также требуется разрешение: <uses-permission android:name="android.permission.WAKE_LOCK" />

Смежные вопросы