【问题标题】:Alarm Manager does not work in background on Android 6.0警报管理器在 Android 6.0 上无法在后台运行
【发布时间】:2015-12-20 07:05:02
【问题描述】:

这是我的Activity 代码,

Long time = new GregorianCalendar().getTimeInMillis()+20000;//Setting alarm after 20 sec
Intent intentAlarm = new Intent("alarm");
intentAlarm.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intentAlarm.putExtra("req_code",10);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,10, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);

这些是我在我的应用中拥有的所有权限,

  <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="com.myapp.pack.permission.SET_ALARM"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

这是我的BroadcastReceiver 代码,

@Override
public void onReceive(Context context, Intent intent) {
        SharedPreferences sharedPreferences =
        context.getSharedPreferences( "mydata", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean("elligible",true);
        editor.apply();

    }

我已经在清单中注册了我的BroadcastReceiver

 <receiver android:name="com.myapp.pack.AlarmReciever" android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="alarm" />
        </intent-filter>
    </receiver>

上面的代码在后台成功地在pre-MarshMallow设备上执行BroadcastReceiver,但是在MarshMallow设备上,BroadcastReceiver没有被执行。有谁知道这里会发生什么?谢谢。

【问题讨论】:

    标签: android android-intent android-broadcast android-alarms android-broadcastreceiver


    【解决方案1】:

    您可以尝试一些方法,当它们协同使用时,应该能够切断所有空闲/待机/打盹模式(无论操作系统版本如何)。 p>

    1. 使用WakefulBroadcastReceiver 而不是普通的BroadcastReceiver。确保包含WAKE_LOCK 权限以正确使用它。

    2. 使用setExactAndAllowWhileIdle() 方法(API 23 及更高版本)为接收者安排Intent

    if(Build.VERSION.SDK_INT < 23){
        if(Build.VERSION.SDK_INT >= 19){
            setExact(...);
        }
        else{
            set(...);
        }
    }
    else{
        setExactAndAllowWhileIdle(...);
    }
    

    参考资料:

    1. Alarm manager for background services.

    2. A flowchart for background work, alarms, and your Android app.

    【讨论】:

    • 那么,如果我使用setExactAndAllowWhileIdle(),我是否必须将我的应用的最低 sdk 版本更改为 23?
    • setExact() 仅适用于 API 19。因此,您还需要在 sn-p 的条件下对else if 进行检查。
    • setExactAndAllowWhileIdle() 并不能始终如一地提供期望输出……在金立、小米、三星等多种设备中……在某些设备中,它不会在完美的时间触发,在其他设备中不火……
    • @himCream:您能否更详细地描述您的问题,最好是在一个新问题中?
    • 我的问题是:我有以下代码:alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), sender);使用 WakefulBroadcastReceiver 每 30 分钟设置一次警报,但在某些设备中,有时它会错过呼叫警报,有时会在 2-3 分钟后呼叫警报……我通过日志确认它
    【解决方案2】:

    原因可以是Android 6.0 Marshmallow 中引入的Doze mode。使用setAlarmclock() 而不是set()。它是专为闹钟设计的,可以打瞌睡。您可以使用一些 adb 命令手动将手机置于打盹或应用待机模式:

    https://developer.android.com/preview/features/power-mgmt.html

    如果这不能唤醒您的应用程序,则有一个万无一失的方法setExactAndAllowWhileIdle() 旨在无论如何将手机从打盹中唤醒。在最坏的情况下,您可以使用此方法唤醒您的应用,并使用唤醒来安排下一个闹钟。

    参考: How to make Alarm Manager work when Android 6.0 in Doze mode?

    【讨论】:

    • 好的,我试试看。
    【解决方案3】:

    在我的实验中,AlarmManagerCompat + setAlarmClock 在打盹模式下稳定唤醒。我用的是小米设备,它使用 MIUI。

    AlarmManagerCompat.setAlarmClock(alarmManager, time, showIntent, pendingIntent)
    

    如果这对你有好处,请投票,干杯!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多