我尝试每天上午10点发送通知。当应用程序在后台运行时,代码运行良好,但当应用程序终止/终止时,代码不起作用。
以下是我正在做的事情,
在清单中:
<receiver
android:name=".ReminderBroadcast"
android:exported="true"
android:enabled="true"/>
我的BroadcastReceiver:
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.setInexatRepeating((,但由于系统繁忙,它无法正常工作,我找到了另一种方法来完成这项工作。为此,使用alarmMgr.set((将唤醒设备以触发一次性(非重复(警报。但当它触发设备时,请给出下一个日期和时间。当应用程序终止/终止工作时,它可以正常工作。我正在描述这两种方法,只需遵循您想要的
源代码
方法1
通知Utils.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
)
}
}
报警接收器.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" />
主活动.kt
val alarmUtils = AlarmUtils(this)
alarmUtils.initRepeatingAlarm()
方法2
通知Utils.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)
}
报警接收器.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" />
主活动.kt
val calendar = Calendar.getInstance()
val alarmUtils = AlarmUtils(this)
alarmUtils.initRepeatingAlarm(calendar)
重新启动设备
如果你想让警报器在重新启动设备后工作,你应该做以下事情。
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>