Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/kotlin/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android中带有通知的AlarmManager不显示任何通知_Android_Kotlin_Android Notifications_Alarmmanager - Fatal编程技术网

Android中带有通知的AlarmManager不显示任何通知

Android中带有通知的AlarmManager不显示任何通知,android,kotlin,android-notifications,alarmmanager,Android,Kotlin,Android Notifications,Alarmmanager,我尝试为我的应用程序创建每日通知。为了测试应用程序,我将通知的间隔设置为15分钟。不幸的是,没有显示任何通知。无论是在应用程序运行时还是关闭时。我试图用这些解决方案激励自己: https://stackoverflow.com/questions/33055129/how-to-show-a-notification-everyday-at-a-certain-time-even-when-the-app-is-close https://developer.android.com/codela

我尝试为我的应用程序创建每日通知。为了测试应用程序,我将通知的间隔设置为15分钟。不幸的是,没有显示任何通知。无论是在应用程序运行时还是关闭时。我试图用这些解决方案激励自己:

https://stackoverflow.com/questions/33055129/how-to-show-a-notification-everyday-at-a-certain-time-even-when-the-app-is-close

https://developer.android.com/codelabs/android-training-alarm-manager#0

https://github.com/google-developer-training/android-fundamentals-apps-v2/tree/master/StandUp (上一链接的存储库)

我将uses权限和receiver添加到清单文件中

manifest.xml

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.ovu">

    <uses-permission android:name = "android.permission.VIBRATE" />
    <uses-permission android:name="com.android.alarm.permission.SET_ALARM"/>
    <!-- Permission to start Alarm on device reboot -->
    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

    <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
          ...
        </activity>

        <receiver android:name= ".DailyNotificationReceiver">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

    </application>

</manifest>

在此活动中,AlarmManager实例应设置为每日重复

活动通知

class ActivityNotification : AppCompatActivity() {

    companion object {
        // Notification ID.
        private const val NOTIFICATION_ID = 0

        // Notification channel ID.
        private const val PRIMARY_CHANNEL_ID = "primary_notification_channel"
    }

    private lateinit var mNotificationManager: NotificationManager

    private fun notifyUser(){

        val notifyIntent = Intent(this, DailyNotificationReceiver::class.java)

        val notifyPendingIntent = PendingIntent.getBroadcast(this, NOTIFICATION_ID, notifyIntent,
                PendingIntent.FLAG_UPDATE_CURRENT)

        val alarmManager = getSystemService(Context.ALARM_SERVICE) as AlarmManager

        val repeatInterval = AlarmManager.INTERVAL_FIFTEEN_MINUTES

        val triggerTime = (SystemClock.elapsedRealtime()
                + repeatInterval)

        alarmManager.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                triggerTime, repeatInterval,
                notifyPendingIntent)

        // Create the notification channel.
        createNotificationChannel();

        Toast.makeText(this, "Alarm's set", Toast.LENGTH_LONG).show()
    }

    private fun createNotificationChannel() {

        // Create a notification manager object.
        mNotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager

        // Notification channels are only available in OREO and higher.
        // So, add a check on SDK version.
        if (Build.VERSION.SDK_INT >=
                Build.VERSION_CODES.O) {

            // Create the NotificationChannel with all the parameters.
            val notificationChannel = NotificationChannel(PRIMARY_CHANNEL_ID,
                    "Stand up notification",
                    NotificationManager.IMPORTANCE_HIGH)
            notificationChannel.enableLights(true)
            notificationChannel.lightColor = Color.RED
            notificationChannel.enableVibration(true)
            notificationChannel.description = "Notifies every 15 minutes to " +
                    "stand up and walk"
            mNotificationManager.createNotificationChannel(notificationChannel)
        }
    }
     override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_notification)
        editTextNotificationHour = findViewById(R.id.editTextChangedNotification)
        mNotificationManager = getSystemService(NOTIFICATION_SERVICE) as NotificationManager
    }

  fun changeNotificationHour(view: View){
        notifyUser()
        val intent = Intent(this, ProfileActivity::class.java)
        startActivity(intent)
        finish()
    }



如果你们能帮我找到解决方案,我将非常高兴。

首先,让我们先在清单中启用BroadcastReceiver,将代码更改为:

<receiver 
  android:name= ".DailyNotificationReceiver"
  android:enabled="true"
  android:exported="true">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
  </intent-filter>
</receiver>
可以通过以下方式处理通知:

  • 创建单独的
    通知

  • 处理所有通知事项,如创建频道,并在收到警报时将其发送到
    BroadcastReceiver

为了使问题更具可读性,我省略了将此活动中的代码粘贴到问题中。在此活动中,用户可以更改每日通知的时间。我刚刚按照您的建议将代码添加到清单文件和活动中。我在模拟器上运行该应用程序,令人惊讶的是它工作正常。我试着在我的手机上调试它(小米红米),但它不起作用。我检查了应用程序的权限,并授予了通知权限。你知道这是什么原因吗?你有没有用我写的方法安排闹钟?(设置ExactAndAllowHileidle和设置AlarmClock)?是的。我的bootReceiver也有问题。它抛出一个异常“包中未找到组件”。它只显示一次通知。启动接收器应该像其他广播接收器一样创建。我的代码只是为了以编程方式启用它。你应该只收到一次。你们需要做的就是从广播接收器重新安排时间。你不使用重复报警的原因是,Android的节电功能可以延迟这些报警。如果你不关心确切的执行,那么你应该替换方法,否则就在每次接收时重新安排它。明天我会研究在小米上接收它,然而,在我的应用程序中,这在我测试过的每一台设备上都有效:小米、Moto等等。。。
<receiver 
  android:name= ".DailyNotificationReceiver"
  android:enabled="true"
  android:exported="true">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
  </intent-filter>
</receiver>
class InternetDaysLeftAlarm @Inject constructor(
    @ApplicationContext val context: Context
) {
    /**
     * Function is used to schedule one-time Alarm that will trigger on specific time.
     *
     * @param hourOfDay -> parameter defines what o'clock should the alarm be triggered at. (24-hour)
     *      default value is:
     * @see INTERNET_DAYS_LEFT_ALARM_DEFAULT_TRIGGER_HOUR
     */
    fun scheduleAlarm(hourOfDay: Int = INTERNET_DAYS_LEFT_ALARM_DEFAULT_TRIGGER_HOUR) {
        val alarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        val intent = Intent(context, InternetDaysLeftReceiver::class.java)
        intent.action = INTENT_ACTION_INTERNET_DAYS_LEFT_ALARM
        val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, 0)

        val msUntilTriggerHour: Long = TimeUnit.MINUTES.toMillis(minutesUntilOClock(hourOfDay))

        // Calculating and adding jitter in order to ease load on server
        val jitter: Long = TimeUnit.MINUTES.toMillis(Random.nextInt(0, 420).toLong())

        val alarmTimeAtUTC: Long = System.currentTimeMillis() + msUntilTriggerHour + jitter

        // Enabling BootReceiver
        val bootReceiver = ComponentName(context, BootReceiver::class.java)
        context.packageManager.setComponentEnabledSetting(
            bootReceiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
        )

        /**
         * Schedules the Alarm based on Android Version.
         *
         * As per AlarmManager documentation to guarantee Alarm execution at specified time we use following methods:
         *
         * @see AlarmManager.setExactAndAllowWhileIdle -> Android.M [API 23] and above.
         * @see AlarmManager.setAlarmClock -> Everything below Android M.
         */

        if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
            alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTimeAtUTC, pendingIntent)
        } else {
            alarmManager.setAlarmClock(AlarmManager.AlarmClockInfo(alarmTimeAtUTC, pendingIntent), pendingIntent)
        }
    }