【问题标题】:Android alarmManager.setAlarmClock Crash Android 7Android alarmManager.setAlarmClock 崩溃 Android 7
【发布时间】:2019-09-13 06:40:01
【问题描述】:

在我设置闹钟的函数中调用alarmmanager.setAlarmClock 时出现崩溃(仅限Android 7)。我不知道这里有什么问题。以及如何解决这个问题 崩溃。

这是调用alarmManager.setAlarmClock时崩溃的函数

fun setBeforeAlert(
        context: Context,
        offset: Long,
        beforeMin: Int,
        pendingIntent: PendingIntent
    ) {
        if (offset - beforeMin * 60 * 1000 > 0) {
            val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                val alarmClockInfo = AlarmManager.AlarmClockInfo((System.currentTimeMillis() + offset) - beforeMin * 60 * 1000, pendingIntent)
                alarmManager.setAlarmClock(alarmClockInfo, pendingIntent)
            }
            else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
                alarmManager.setExact(AlarmManager.RTC_WAKEUP, (System.currentTimeMillis() + offset) - beforeMin * 60 * 1000, pendingIntent)
            }
            else {
                alarmManager.set(AlarmManager.RTC_WAKEUP, (System.currentTimeMillis() + offset) - beforeMin * 60 * 1000, pendingIntent)
            }
        }
    }

这是我传递给上述函数的未决意图:

val intent = Intent(context, AlertAlarm::class.java)
        intent.putExtra(Constants.key_alert_alarm_code, reqCode)
        intent.putExtra(Constants.key_alert_type, type)
        intent.putExtra(Constants.key_alert_min, min)
        val pi = PendingIntent.getBroadcast(context, reqCode, intent, PendingIntent.FLAG_UPDATE_CURRENT)

这是我得到的崩溃报告:

java.lang.NullPointerException: Attempt to invoke virtual method 'int com.android.server.AlarmManagerService$Batch.size()' on a null object reference
at android.app.ActivityThread.handleReceiver(ActivityThread.java:3377)
at android.app.ActivityThread.-wrap18(ActivityThread.java)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1800)
at android.os.Handler.dispatchMessage(Handler.java:110)
at android.os.Looper.loop(Looper.java:232)
at android.app.ActivityThread.main(ActivityThread.java:6802)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1103)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'int com.android.server.AlarmManagerService$Batch.size()' on a null object reference
at android.os.Parcel.readException(Parcel.java:1714)
at android.os.Parcel.readException(Parcel.java:1661)
at android.app.IAlarmManager$Stub$Proxy.set(IAlarmManager.java:246)
at android.app.AlarmManager.setImpl(AlarmManager.java:680)
at android.app.AlarmManager.setAlarmClock(AlarmManager.java:601)
at com.mypackage.util.AlarmUtils.setBeforeAlert(AlarmUtils.kt:42)
at com.com.mypackage.util.AzanUtils.setBeforeAlertAlarms(AzanUtils.kt:358)
at com.com.mypackage.util.AzanUtils.setAlarms(AzanUtils.kt:160)

【问题讨论】:

  • 您可以使用工作管理器代替警报管理器。 Work Manage 根据当前应用要求使用警报管理器或作业调度器。

标签: java android kotlin


【解决方案1】:

我们在 OPPO 设备(Android 7)上也遇到了同样的崩溃。如果您查看AlarmManagerService.Batch.class 中的size() 方法,它绝不应该为空。我假设一些制造商已经改变了导致问题的IAlarmManager (AlarmManagerService) 的实现。你对此无能为力。

【讨论】:

  • 我们真的不能解决这个问题吗?我们不能尝试捕获并在崩溃时重试吗?
  • 所以我用私人乐趣 exclude() = Build.VERSION.SDK_INT == Build.VERSION_CODES.N_MR1 && "CPH1727" == Build.MODEL :) 隔离该设备
【解决方案2】:

确保您的alarmManager 不为空,如下所示。

val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
if (alarmManager != null){
  // do your stuff here.
}

【讨论】:

  • 有没有可能返回null,错误?为什么?
  • alarmmanager 不为空。如果我们从下到上查看崩溃报告,您可以在以下位置看到它的崩溃:android.app .IAlarmManager$Stub$Proxy.set(IAlarmManager.java:246)
  • 如果alarmmanager为null,android会在另一行抛出npe,ndroid.app.AlarmManager.setAlarmClock(AlarmManager.java:601)
【解决方案3】:

您需要确保alarmManager 不为空,即系统允许您使用AlarmService。添加一个简单的空检查并使强制转换可以为空。

    val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
    if (alarmManager != null){
        // set alarm using setExact or setAlarmClock
    } else {
        //  failed to get alarm service, show error
    }

【讨论】:

  • alarmmanager 不为空。如果我们从下到上查看崩溃报告,您可以在以下位置看到其崩溃:android.app .IAlarmManager$Stub$Proxy.set(IAlarmManager.java:246)
  • 可以为空。在某些情况下,os 不允许您的应用程序使用 AlarmService,它会返回 null 到 getSystemService(Context.ALARM_SERVICE) 调用。您需要添加检查以确保您获得警报管理器的实例然后使用它。
  • 如果alarmmanager为null,android会在另一行抛出npe,ndroid.app.AlarmManager.setAlarmClock(AlarmManager.java:601)
猜你喜欢
  • 1970-01-01
  • 2017-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-07
  • 2012-07-07
  • 2012-12-27
  • 2012-06-05
相关资源
最近更新 更多