警报通知立即触发。安卓系统 [英] Alarm Notification fires instantly. Android
本文介绍了警报通知立即触发。安卓系统的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我正在研究一种在固定时间向用户发送通知的提醒。
I am working on a Reminder that sends notification on fixed time to the user.
警报立即响起...
我尝试过 stackoverflow
的大多数建议,但仍然遇到相同的问题
I tried most of the suggestions over stackoverflow
, but still having same issue
请帮助我解决此问题。
服务器数据
user_reminder": [
{
"id": "75",
"name": "Morning Snacks",
"time": "11:00:00",
"days": "1,2,3,4,5,6,7",
"user_id": "14"
},
{
"id": "76",
"name": "Lunch",
"time": "13:00:00",
"days": "1,2,3,4,5,6,7",
"user_id": "14"
},
......
]
我的代码
for (int i = 0; i < reminderList.size(); i++)
{
String time = reminderList.get(i).getTime(); // "time": "11:00:00"
String strSpit[] = time.split(":");
String strDays[] = reminderList.get(i).getDays().split(","); //"days": "1,2,3,4,5,6,7"
Date date = new Date();
Calendar calNow = Calendar.getInstance();
calNow.setTime(date);
Calendar calAlarm = Calendar.getInstance();
calAlarm.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strSpit[0]));
calAlarm.set(Calendar.MINUTE, Integer.parseInt(strSpit[1]));
for (int j = 0; j < strDays.length; j++)
{
calAlarm.set(Calendar.DAY_OF_WEEK, viewFunctions.getDayInt(strDays[j]));
if (calAlarm.before(calNow))
{
//if its in the past increment
calAlarm.add(Calendar.DATE, 1);
}
notifyIntent.putExtra(Constants.REMINDER_NAME, reminderList.get(i).getName());
pendingIntent = PendingIntent.getBroadcast(this, 0, notifyIntent, PendingIntent.FLAG_ONE_SHOT);
alarmManager.set(AlarmManager.RTC_WAKEUP, calAlarm.getTimeInMillis() , pendingIntent);
}
}
}
获取天数:解决日期编号
public int getDayInt(String strDay)
{
int dayNumber = 0;
if (strDay.equals("1"))
{
dayNumber = Calendar.MONDAY;
} ......
return dayNumber;
}
屏幕截图
推荐答案
最后,我找到了一种方法为此,将 PendingIntent requestCode
存储在数据库(使用的ROOM)中,然后通过检索所有 requestCode
取消所有警报来自 DB
Finally I found a way to do that by storing PendingIntent requestCode
in database (used ROOM) , then cancelling all the alarm by retrieving all the requestCode
from DB
AlarmIdPojo
@Entity
public class AlarmIdPojo {
@PrimaryKey(autoGenerate = true)
public int id;
private int requestCode;
public AlarmIdPojo() {
}
public int getRequestCode() {
return requestCode;
}
public void setRequestCode(int requestCode) {
this.requestCode = requestCode;
}
}
AlarmIdDAO
@Dao
public interface AlarmIdDAO {
@Query("select * from AlarmIdPojo")
List<AlarmIdPojo> getAllRequestCode();
@Query("delete from AlarmIdPojo")
public void deleteAllRequestCode();
@Insert(onConflict = REPLACE)
void addRequestCode(AlarmIdPojo pojo);
}
AppDatabase
@Database(entities = {AlarmIdPojo.class}, version = 1)
public abstract class AppDatabase extends RoomDatabase {
public abstract AlarmIdDAO requestIdPojo();
@Override
protected SupportSQLiteOpenHelper createOpenHelper(DatabaseConfiguration config) {
return null;
}
@Override
protected InvalidationTracker createInvalidationTracker() {
return null;
}
}
callReminder
private void callReminder() {
// java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
// because of this Exception , we are doing this in AsyncTask
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
List<AlarmIdPojo> idList = appDatabase.requestIdPojo().getAllRequestCode();
Intent notifyIntent = new Intent(MainActivity.this, MyReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent;
for (int i = 0; i < idList.size(); i++) {
int requestId = idList.get(i).getRequestCode();
pendingIntent = PendingIntent.getBroadcast(MainActivity.this, requestId, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
// Cancel alarms
try {
alarmManager.cancel(pendingIntent);
} catch (Exception e) {
Log.e(TAG, "AlarmManager update was not canceled. " + e.toString());
}
}
appDatabase.requestIdPojo().deleteAllRequestCode();
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
// Once every request code is deleted , then once again call setReminderNotification() for fresh data.
setReminderNotification();
}
}.execute();
}
setReminderNotification
private void setReminderNotification() {
Intent notifyIntent = new Intent(this, MyReceiver.class);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent;
// Taking existing offline reminder data from sharePreference
Type type = new TypeToken<List<UserReminderPojo>>() {
}.getType();
List<UserReminderPojo> reminderList = new Gson().fromJson(sharedPrefUtils.getString(sharedPrefUtils.DEFAULT_REMINDERS), type);
for (int i = 0; i < reminderList.size(); i++) {
String time = reminderList.get(i).getTime();
String strSpit[] = time.split(":");
String strDays[] = reminderList.get(i).getDays().split(",");
Calendar todayWithTime = Calendar.getInstance();
todayWithTime.set(Calendar.SECOND, 0);
todayWithTime.set(Calendar.MILLISECOND, 0);
for (int j = 0; j < strDays.length; j++) {
Calendar alarm = Calendar.getInstance();
alarm.set(Calendar.SECOND, 0);
alarm.set(Calendar.MILLISECOND, 0);
alarm.set(Calendar.HOUR_OF_DAY, Integer.parseInt(strSpit[0]));
alarm.set(Calendar.MINUTE, Integer.parseInt(strSpit[1]));
alarm.set(Calendar.DAY_OF_WEEK, viewFunctions.getDayInt(strDays[j]));
int randomPendingIntentId = generateRandomId();
notifyIntent.putExtra(Constants.REMINDER_NAME, reminderList.get(i).getName());
notifyIntent.putExtra(Constants.ID, randomPendingIntentId); // passing it , so that we can cancel this PendingIntent with this Id, once notification is shown.This is done to prevent past time alarm firing
notifyIntent.putExtra(Constants.REMINDER_DAY, viewFunctions.getDayInt(strDays[j]));
pendingIntent = PendingIntent.getBroadcast(this, randomPendingIntentId, notifyIntent, PendingIntent.FLAG_UPDATE_CURRENT);
if (alarm.before(todayWithTime)) {
alarm.add(Calendar.DATE, 7);
}
alarmManager.set(AlarmManager.RTC_WAKEUP, alarm.getTimeInMillis(), pendingIntent);
insertToDB(randomPendingIntentId);
}
}
}
insertToDB
// Saving to DB. keeping track of PendingIntent unique id.
private void insertToDB(int randomPendingIntentId) {
alarmIdPojo = new AlarmIdPojo();
alarmIdPojo.setRequestCode(randomPendingIntentId);
// java.lang.IllegalStateException: Cannot access database on the main thread since it may potentially lock the UI for a long period of time.
// because of this Exception , we are doing this in AsyncTask
new AsyncTask<Void, Void, Void>() {
@Override
protected Void doInBackground(Void... voids) {
appDatabase.requestIdPojo().addRequestCode(alarmIdPojo);
return null;
}
}.execute();
}
这篇关于警报通知立即触发。安卓系统的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文