如何设置来自应用程序的每天一次通知
How to setup once-per-day notification from app
我有一个关于从我的应用程序设置每日数据检查(发生某些事件时发出通知)的一般性问题。
我目前的做法是:
- 我从应用程序 (onCreate) 启动服务
- 在检查是否已经存在匹配的 PendingIntent 后,我使用 AlarmManager 设置了一个警报(在这种情况下我没有
需要设置一个新闹钟)
- 服务检查来自 SharedPreferences 的数据并最终显示通知
出于测试目的,我将闹钟设置为 +1 分钟......但它并没有那样工作。也许我在概念上做错了什么?
一些代码
AndroidManifest.xml
<application
<activity
android:name=".OverviewActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="xxxxx.CheckDaysMonths" >
</service>
</application>
服务 CheckDaysMonths
public class CheckDaysMonths extends Service {
private static int ALARM_ID = 131313;
private static String DECLARED_ACTION = "xxxxx.CheckDaysMonths";
@Override
public void onCreate() {
super.onCreate();
PendingIntent alarmIntent = AlarmHelper.getPendingIntentFromAlarm(this, ALARM_ID, DECLARED_ACTION);
if(alarmIntent == null) {
if(someConditionIsMet)
sendNotification(" my notification text ");
// Set an alarm for the next time this service should run:
setAlarm();
}
stopSelf();
}
public void setAlarm() {
AlarmHelper.setAlarm(this, ALARM_ID, DECLARED_ACTION, 8);
}
public void sendNotification(String notifyText) {
Intent mainIntent = new Intent(this, OverviewActivity.class);
@SuppressWarnings("deprecation")
Notification noti = new Notification.Builder(this)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 131314, mainIntent,
PendingIntent.FLAG_UPDATE_CURRENT))
.setContentTitle("Gratuliere!")
.setContentText("Du bist seit " + notifyText + " rauchfrei!")
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker("Du bist seit " + notifyText + " rauchfrei!")
.setWhen(System.currentTimeMillis())
.getNotification();
NotificationManager notificationManager
= (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(131315, noti);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
里面主要activity(OverviewActivity.java)
编辑:将服务调用从隐式更改为显式
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_overview);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
startService(new Intent(this, CheckDaysMonths.class));
// additional stuff happening on the activity of my app goes here:
...
}
AlarmHelper.java
public class AlarmHelper {
public static PendingIntent getPendingIntentFromAlarm(Context context, int alarmId, String declaredAction) {
return (PendingIntent.getService(context, alarmId,
new Intent(declaredAction),
PendingIntent.FLAG_NO_CREATE));
}
public static void setAlarm(Context context, int alarmId, String declaredAction, int hourOfDay) {
Intent serviceIntent = new Intent(declaredAction);
PendingIntent pi = PendingIntent.getService(context, alarmId, serviceIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// How long until tomorrow to its hourOfDay?
//DateTime tomorrow = (new DateTime()).plusDays(1);
//DateTime tomorrowAtHourOfDay = new DateTime(tomorrow.getYear(), tomorrow.getMonthOfYear(), tomorrow.getDayOfMonth(), hourOfDay, 0);
DateTime tomorrowAtHourOfDay = (new DateTime()).plusHours(3);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, tomorrowAtHourOfDay.getMillis(), pi);
}
}
我通过引入另一个 "middle tier" 服务修复了它
所以现在我有
- 应用程序 GUI 启动服务 1
- 服务 1 将检查是否已经存在具有正确签名的警报 运行。如果没有,它将启动警报
- 闹钟将在凌晨 2 点响起并启动服务 2
- 服务 2 将检查数据 (SharedPreferences) 并最终发送通知。然后它会再次启动闹钟
- BOOT 的 BroadcastReceiver 启动服务 2
这个效果很好
我有一个关于从我的应用程序设置每日数据检查(发生某些事件时发出通知)的一般性问题。
我目前的做法是:
- 我从应用程序 (onCreate) 启动服务
- 在检查是否已经存在匹配的 PendingIntent 后,我使用 AlarmManager 设置了一个警报(在这种情况下我没有 需要设置一个新闹钟)
- 服务检查来自 SharedPreferences 的数据并最终显示通知
出于测试目的,我将闹钟设置为 +1 分钟......但它并没有那样工作。也许我在概念上做错了什么?
一些代码
AndroidManifest.xml
<application
<activity
android:name=".OverviewActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar"
android:configChanges="orientation"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service
android:name="xxxxx.CheckDaysMonths" >
</service>
</application>
服务 CheckDaysMonths
public class CheckDaysMonths extends Service {
private static int ALARM_ID = 131313;
private static String DECLARED_ACTION = "xxxxx.CheckDaysMonths";
@Override
public void onCreate() {
super.onCreate();
PendingIntent alarmIntent = AlarmHelper.getPendingIntentFromAlarm(this, ALARM_ID, DECLARED_ACTION);
if(alarmIntent == null) {
if(someConditionIsMet)
sendNotification(" my notification text ");
// Set an alarm for the next time this service should run:
setAlarm();
}
stopSelf();
}
public void setAlarm() {
AlarmHelper.setAlarm(this, ALARM_ID, DECLARED_ACTION, 8);
}
public void sendNotification(String notifyText) {
Intent mainIntent = new Intent(this, OverviewActivity.class);
@SuppressWarnings("deprecation")
Notification noti = new Notification.Builder(this)
.setAutoCancel(true)
.setContentIntent(PendingIntent.getActivity(this, 131314, mainIntent,
PendingIntent.FLAG_UPDATE_CURRENT))
.setContentTitle("Gratuliere!")
.setContentText("Du bist seit " + notifyText + " rauchfrei!")
.setDefaults(Notification.DEFAULT_ALL)
.setSmallIcon(R.mipmap.ic_launcher)
.setTicker("Du bist seit " + notifyText + " rauchfrei!")
.setWhen(System.currentTimeMillis())
.getNotification();
NotificationManager notificationManager
= (NotificationManager) this.getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(131315, noti);
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
}
里面主要activity(OverviewActivity.java)
编辑:将服务调用从隐式更改为显式
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_overview);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
startService(new Intent(this, CheckDaysMonths.class));
// additional stuff happening on the activity of my app goes here:
...
}
AlarmHelper.java
public class AlarmHelper {
public static PendingIntent getPendingIntentFromAlarm(Context context, int alarmId, String declaredAction) {
return (PendingIntent.getService(context, alarmId,
new Intent(declaredAction),
PendingIntent.FLAG_NO_CREATE));
}
public static void setAlarm(Context context, int alarmId, String declaredAction, int hourOfDay) {
Intent serviceIntent = new Intent(declaredAction);
PendingIntent pi = PendingIntent.getService(context, alarmId, serviceIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
// How long until tomorrow to its hourOfDay?
//DateTime tomorrow = (new DateTime()).plusDays(1);
//DateTime tomorrowAtHourOfDay = new DateTime(tomorrow.getYear(), tomorrow.getMonthOfYear(), tomorrow.getDayOfMonth(), hourOfDay, 0);
DateTime tomorrowAtHourOfDay = (new DateTime()).plusHours(3);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.set(AlarmManager.RTC_WAKEUP, tomorrowAtHourOfDay.getMillis(), pi);
}
}
我通过引入另一个 "middle tier" 服务修复了它
所以现在我有
- 应用程序 GUI 启动服务 1
- 服务 1 将检查是否已经存在具有正确签名的警报 运行。如果没有,它将启动警报
- 闹钟将在凌晨 2 点响起并启动服务 2
- 服务 2 将检查数据 (SharedPreferences) 并最终发送通知。然后它会再次启动闹钟
- BOOT 的 BroadcastReceiver 启动服务 2
这个效果很好