在预定的时间发送每日通知android [英] Send Daily Notification at a scheduled time android

查看:42
本文介绍了在预定的时间发送每日通知android的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我尝试每天上午 10 点发送通知.该代码在应用程序运行和在后台运行时正常工作,但在应用程序终止/终止时不起作用.

I am trying to send notification daily at 10am. The code works fine when app is running and in background, but it does not work when the app is terminated/Killed.

这是我在做的,

在清单中:

    <receiver
    android:name=".ReminderBroadcast"
    android:exported="true"
    android:enabled="true"/>

我的广播接收器:

public class ReminderBroadcast extends BroadcastReceiver
{

    @Override
    public void onReceive(Context context, Intent intent)
    {
        context.startService(new Intent(context, NotifyService.class));
    }
}

我在 onCreate 中的服务:

 NotificationCompat.Builder builder = new NotificationCompat.Builder(getApplicationContext(), "notifyHackhshieldPP")
            .setSmallIcon(R.drawable.logopp)
            .setContentTitle("Hello")
            .setContentText("Notification Test")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT);

    NotificationManagerCompat notificationManager = NotificationManagerCompat.from(getApplicationContext());
    notificationManager.notify(200, builder.build());

然后调用它:

   private void setnotificationSendService()
    {
        AlarmManager am = (AlarmManager) getSystemService(Context.ALARM_SERVICE);

        //creating a new intent specifying the broadcast receiver
        Intent i = new Intent(this, ReminderBroadcast.class);

        //creating a pending intent using the intent
        PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, 0);

        //setting the repeating alarm that will be fired every day
        Calendar alarmStartTime = Calendar.getInstance();
        alarmStartTime.set(Calendar.HOUR_OF_DAY, 20);
        alarmStartTime.set(Calendar.MINUTE, 5);
        alarmStartTime.set(Calendar.SECOND, 0);
        am.setRepeating(AlarmManager.RTC_WAKEUP, (alarmStartTime.getTimeInMillis()), AlarmManager.INTERVAL_DAY, pi);
    }

推荐答案

2021 年 8 月 30 日,星期一

根据官方文档,可以使用alarmMgr.setInexactRepeating() 但是由于由于系统繁忙,它无法正常工作,我找到了另一种方法来完成这项工作.为此目的使用 alarmMgr.set() 这将唤醒设备以触发一次性(非重复)警报.但是当它触发设备时,给它下一个日期和时间.当应用程序终止时它可以正常工作/Killedwork 我正在描述这两种方法,只需按照您想要的方法

Monday, August 30, 2021

According to official documents, you can use alarmMgr.setInexactRepeating() but due to the system being busy it does not work properly I found another way to do this work. Use alarmMgr.set() for this purpose this will Wake up the device to fire a one-time (non-repeating) alarm. But when it triggers the device give it next date and time. It works properly when the app is terminated/Killedwork I am describing both methods just follow which one you want

源代码

NotificationUtils.kt

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat

class NotificationUtils(context:Context) {

    private var mContext = context
    private lateinit var notificationBuilder: NotificationCompat.Builder
    val notificationManager = NotificationManagerCompat.from(mContext)
    private val CHANNEL_ID = "My_Notification_Channel"


    init {
        createNotificationChannel()
        initNotificationBuilder()
    }


    fun launchNotification(){
        with(NotificationManagerCompat.from(mContext)) {
            // notificationId is a unique int for each notification that you must define
            notificationManager.notify(0, notificationBuilder.build())
        }
    }

    private fun createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Channel Name"
            val descriptionText = "Channel Description"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
            }
            // Register the channel with the system
            val notifiManager: NotificationManager =
                mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notifiManager.createNotificationChannel(channel)
        }
    }


    private fun initNotificationBuilder() {

        // Create an explicit intent for an Activity in your app
        val sampleIntent = Intent(mContext, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(mContext, 0, sampleIntent, 0)

        /***
         * Notice that the NotificationCompat.Builder constructor requires that you provide a channel ID.
         * This is required for compatibility with Android 8.0 (API level 26) and higher,
         * but is ignored by older versions.
         */
        notificationBuilder = NotificationCompat.Builder(mContext, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("Notification Title")
            .setContentText("Notification Body Text, Notification Body Text")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            // Automatically removes the notification when the user taps it.
            .setAutoCancel(true)
    }

}

AlarmUtils.kt

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import java.util.*

class AlarmUtils(context: Context) {
    private var mContext = context
    private var alarmMgr: AlarmManager? = null
    private var alarmIntent: PendingIntent

    init {
        alarmMgr = mContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmIntent = Intent(mContext, AlarmReceiver::class.java).let { mIntent ->
        // if you want more than one notification use different requestCode
        // every notification need different requestCode
            PendingIntent.getBroadcast(mContext, 100, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
        }
    }

    fun initRepeatingAlarm(){
        val calendar: Calendar = Calendar.getInstance().apply {
            timeInMillis = System.currentTimeMillis()
            set(Calendar.HOUR_OF_DAY, 10)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
        }

        alarmMgr?.setInexactRepeating(
            AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis,
            AlarmManager.INTERVAL_DAY,
            alarmIntent
        )
    }

}

AlarmReceiver.kt

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent

class AlarmReceiver:BroadcastReceiver() {
    override fun onReceive(context: Context?, mIntent: Intent?) {
        val notificationUtils = NotificationUtils(context!!)
        notificationUtils.launchNotification()
    }
}

AndroidManifest.xml

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

MainActivity.kt

val alarmUtils = AlarmUtils(this)
alarmUtils.initRepeatingAlarm()

方法二

NotificationUtils.kt

import android.app.NotificationChannel
import android.app.NotificationManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.os.Build
import androidx.core.app.NotificationCompat
import androidx.core.app.NotificationManagerCompat

class NotificationUtils(context:Context) {

    private var mContext = context
    private lateinit var notificationBuilder: NotificationCompat.Builder
    val notificationManager = NotificationManagerCompat.from(mContext)
    private val CHANNEL_ID = "My_Notification_Channel"


    init {
        createNotificationChannel()
        initNotificationBuilder()
    }


    fun launchNotification(){
        with(NotificationManagerCompat.from(mContext)) {
            // notificationId is a unique int for each notification that you must define
            notificationManager.notify(0, notificationBuilder.build())
        }
    }

    private fun createNotificationChannel() {
        // Create the NotificationChannel, but only on API 26+ because
        // the NotificationChannel class is new and not in the support library
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            val name = "Channel Name"
            val descriptionText = "Channel Description"
            val importance = NotificationManager.IMPORTANCE_DEFAULT
            val channel = NotificationChannel(CHANNEL_ID, name, importance).apply {
                description = descriptionText
            }
            // Register the channel with the system
            val notifiManager: NotificationManager =
                mContext.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager
            notifiManager.createNotificationChannel(channel)
        }
    }


    private fun initNotificationBuilder() {

        // Create an explicit intent for an Activity in your app
        val sampleIntent = Intent(mContext, MainActivity::class.java).apply {
            flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
        }
        val pendingIntent: PendingIntent = PendingIntent.getActivity(mContext, 0, sampleIntent, 0)

        /***
         * Notice that the NotificationCompat.Builder constructor requires that you provide a channel ID.
         * This is required for compatibility with Android 8.0 (API level 26) and higher,
         * but is ignored by older versions.
         */
        notificationBuilder = NotificationCompat.Builder(mContext, CHANNEL_ID)
            .setSmallIcon(R.drawable.notification_icon)
            .setContentTitle("Notification Title")
            .setContentText("Notification Body Text, Notification Body Text")
            .setPriority(NotificationCompat.PRIORITY_DEFAULT)
            // Set the intent that will fire when the user taps the notification
            .setContentIntent(pendingIntent)
            // Automatically removes the notification when the user taps it.
            .setAutoCancel(true)
    }

}

AlarmUtils.kt

import android.app.AlarmManager
import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import java.util.*

class AlarmUtils(context: Context) {
    private var mContext = context
    private var alarmMgr: AlarmManager? = null
    private var alarmIntent: PendingIntent

    init {
        alarmMgr = mContext.getSystemService(Context.ALARM_SERVICE) as AlarmManager
        alarmIntent = Intent(mContext, AlarmReceiver::class.java).let { mIntent ->
        // if you want more than one notification use different requestCode
        // every notification need different requestCode
            PendingIntent.getBroadcast(mContext, 100, mIntent, PendingIntent.FLAG_UPDATE_CURRENT)
        }
    }

    fun initRepeatingAlarm(calendar: Calendar){
        calendar.apply {
            set(Calendar.HOUR_OF_DAY, 10)
            set(Calendar.MINUTE, 0)
            set(Calendar.SECOND, 0)
        }

        alarmMgr?.set(  AlarmManager.RTC_WAKEUP,
            calendar.timeInMillis,
            alarmIntent)
    }

AlarmReceiver.kt

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import java.util.*

    class AlarmReceiver:BroadcastReceiver() {
        override fun onReceive(context: Context?, mIntent: Intent?) {
            val notificationUtils = NotificationUtils(context!!)
            notificationUtils.launchNotification()
    
            val calendar = Calendar.getInstance()
            calendar.add(Calendar.DAY_OF_YEAR, 1)
            val daysNextCalendar = calendar
            val alarmUtils = AlarmUtils(context)
            alarmUtils.initRepeatingAlarm(daysNextCalendar)
        }
    }

AndroidManifest.xml

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

MainActivity.kt

  val calendar = Calendar.getInstance()
  val alarmUtils = AlarmUtils(this)
  alarmUtils.initRepeatingAlarm(calendar)

重启设备

如果你想让闹钟在重启设备后工作,你应该做以下事情.

Reboot Device

If you want the alarm should work after rebooting the device you should do the following thing.

AlarmBootReceiver.kt

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import java.util.*

class AlarmBootReceiver : BroadcastReceiver(){

    override fun onReceive(context: Context, intent: Intent) {
        if (intent.action == "android.intent.action.BOOT_COMPLETED") {
            val calendar = Calendar.getInstance()
            val alarmUtils = AlarmUtils(context)
            alarmUtils.initRepeatingAlarm(calendar)
        }
    }

}

AndroidManifest.xml

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

<receiver android:name=".AlarmBootReceiver"
            android:enabled="true"
            android:exported="true">
            <intent-filter>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
        </receiver>

这篇关于在预定的时间发送每日通知android的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆