【问题标题】:AlarmManager setInexactRepeating not working on Android 10AlarmManager setInexactRepeating 在 Android 10 上不起作用
【发布时间】:2020-11-06 08:34:02
【问题描述】:

自从android 10启动以来,我的应用程序中的警报出现问题,我有以下sn-p,我用AlarmManager测试以查看我编写的警报是否被执行。 当我使用setAlarmClock时,闹钟在设定的时间运行,但是当我尝试使用setInexactRepeating(或setRepeating)时,android忽略了闹钟,它根本不运行。

class MainActivity : AppCompatActivity() {

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)
    val am = getSystemService(Context.ALARM_SERVICE) as AlarmManager
    val timeToTrigger = System.currentTimeMillis() + 10 * 1000
    val intervalo: Long = 60 * 1000
    val intent = Intent(this, AlarmReceiver::class.java)
    val pending = PendingIntent.getBroadcast(this, 1, intent, PendingIntent.FLAG_UPDATE_CURRENT)
    
    //am.setAlarmClock(AlarmManager.AlarmClockInfo(timeToTrigger , null), pending)

    am.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP, SystemClock.elapsedRealtime() + intervalo,intervalo,pending)
  }
}

这是我的Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.lb.alarm_clock_sample">

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission
    android:name="android.permission.WRITE_SETTINGS"
    android:maxSdkVersion="19" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission
    android:name="android.permission.READ_PHONE_STATE"
    android:maxSdkVersion="22" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="com.android.alarm.permission.SET_ALARM" />

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".AlarmsListActivity" />

    <receiver android:name=".AlarmReceiver" />

 </application>

 </manifest>

提前致谢

编辑

根据@Crispert 的说法,使用android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS 可以帮助警报不被忽略。 在清单中添加以下权限:

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

然后在活动中,创建一个函数让用户选择是否希望应用程序在后台工作:

@RequiresApi(Build.VERSION_CODES.M)
private fun ignoreBatteryOptimization() {
    val intent = Intent()
    val packN = packageName
    val pm = getSystemService(Context.POWER_SERVICE) as PowerManager
    if (!pm.isIgnoringBatteryOptimizations(packN)) {
        intent.action = Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
        intent.data = Uri.parse("package:$packN")
        startActivity(intent)
    }
}

如果用户同意忽略电池优化,则在后台执行,警报工作没有任何问题(根据我一直在做的测试,到目前为止我没有问题)。 谢谢。

【问题讨论】:

    标签: android alarmmanager android-10.0


    【解决方案1】:

    尝试添加

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

    到应用清单并要求用户使用以下方式授予权限 this code

    总的来说,过去几个版本的 android 中的警报(以及一般的后台执行)已被故意限制和限制,并且几乎没有应用程序可以解决这个问题。传统的方法是考虑使用替代机制(它们有自己的缺点)来延迟执行:JobScheduler 或前台服务。 JobScheduler /jobs 将消除执行的精确性和确定性(它们的目的是节省能源),而前台服务具有侵入性并且更节能。

    如果您不依赖 google play 进行分发,您可以尝试通过为您的应用使用较低的 targetSdkVersion(可能不超过 24)来推迟不可避免的情况,以尝试强制操作系统执行您的警报。但是请注意,在具有 8/Oreo 和更新版本的设备上,应用待机存储桶和其他 OEM 电池节省机制实际上会在没有用户与您的应用交互的情况下根据任意标准暂停您的应用(因此警报将被忽略)。

    还要考虑检查 BroadcastReceiver 是否根本没有被调用,或者它试图做的事情是否由于操作系统限制而无法完成。您可能会发现触发了警报但应用程序被禁止运行代码-例如不再允许后台代码(服务,广播)启动活动。

    【讨论】:

    • 谢谢,按以下方式应用您提到的内容,将&lt;uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/&gt; 添加到清单中,并根据这篇文章使用代码启用它[stackoverflow.com/questions/51813961/…,毕竟,警报有效,编辑应用我提到的更改的问题。
    【解决方案2】:

    @Crispert 的回答很有趣,但唯一的问题是它需要用户许可才能运行/安排警报。

    我将为您提供我在我的一个应用程序中使用的解决方案,并且不需要任何特定权限,因为它使用默认情况下忽略任何电池优化的警报管理器方法。

    在此处查看此链接: https://stackoverflow.com/a/64558739/9213980

    编辑:我想补充一点,这确实不是一个重复的警报,但是,它可以通过广播接收器的每次触发来简单轻松地重新安排。

    虽然有一些小的限制,但在我的情况下,这些限制并不重要,它完全符合我的需要。您可以通过此链接在官方文档中阅读更多详细信息 https://developer.android.com/reference/kotlin/android/app/AlarmManager#setexactandallowwhileidle

    【讨论】:

      猜你喜欢
      • 2014-03-21
      • 2015-03-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多