我正在尝试使用警报管理器来安排通知,以便在不久的将来向用户显示。
我的代码看起来像
自定义通知管理器,用于触发警报并在用户以某种方式“取消选择”通知时取消警报:
import org.joda.time.Duration;
import org.joda.time.LocalDateTime;
import android.app.AlarmManager;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
/**
* Singleton Class dealing with the delivery and removal of alarm services to
* schedule notifications.
*/
public class MyNotificationManager {
/** unique instance. */
private static MyNotificationManager instance;
/** notification id. */
private int notificationId;
/**
* Constructor.
*/
private MyNotificationManager() {
// hidden constructor for singleton
notificationId = 0;
}
/**
* Initializes the instance.
*/
public static void initInstance() {
if (instance == null) {
// Create the instance
instance = new MyNotificationManager();
}
}
/**
* @return the unique instance of this class.
*/
public static MyNotificationManager getInstance() {
// Return the instance
return instance;
}
/**
* Schedules a notification
*
* @param context
* the context asking for a notification to be scheduled
* @param notification
* the notification to be scheduled
* @param when
* the {@link LocalDateTime} to schedule
* @return the pending intent scheduled (this allows to cancel it if needed)
*/
public PendingIntent scheduleNotification(final Context context, final Notification notification, final LocalDateTime when) {
Intent notificationIntent = new Intent(context, NotificationPublisher.class);
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION_ID, getNextId());
notificationIntent.putExtra(NotificationPublisher.NOTIFICATION, notification);
// Every scheduled intent needs a different ID, else it is just executed
// once
long currentTimeMillis = System.currentTimeMillis();
PendingIntent pendingIntent = PendingIntent.getBroadcast(context, (int) currentTimeMillis, notificationIntent,
PendingIntent.FLAG_UPDATE_CURRENT);
long futureInMillis = new Duration(null, when.toDateTime()).getMillis();
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
Log.d(getClass().getSimpleName(), "Scheduling notification at " + futureInMillis + " millis in the future");
alarmManager.setExact(AlarmManager.RTC_WAKEUP, currentTimeMillis + futureInMillis, pendingIntent);
return pendingIntent;
}
/**
* Cancels the given pending intent if found.
*
* @param context
* the context asking for this cancellation
* @param pendingIntent
* the pending intent to cancel
*/
public void removePendingNotification(final Context context, final PendingIntent pendingIntent) {
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
}
/**
* @return the next free id.
*/
private int getNextId() {
return notificationId++;
}
}
我的广播接收器:
import android.app.Notification;
import android.app.NotificationManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
public class NotificationPublisher extends BroadcastReceiver {
public static String NOTIFICATION_ID = "notification-id";
public static String NOTIFICATION = "notification";
@Override
public void onReceive(Context context, Intent intent) {
NotificationManager notificationManager = (NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE);
Notification notification = intent.getParcelableExtra(NOTIFICATION);
int id = intent.getIntExtra(NOTIFICATION_ID, 0);
Log.d(this.getClass().getSimpleName(), "on Receive for notification ID " + id);
notificationManager.notify(id, notification);
}
}
AndroidManifest.xml已更新为已注册广播接收器
<receiver android:name=".NotificationPublisher" android:exported="false" />
正确调用scheduleNotification,并通过以下方法创建通知:
/**
* Builds a notification about the departure time
*
* @param departure
* the departure time
* @param physicalStop
* the physical stop
* @return a notification
*/
private Notification getNotification(final JsonDeparture departure, final JsonPhysicalStop physicalStop) {
final NotificationCompat.Builder builder = new Builder(context);
final String title = context.getResources().getString(R.string.notificationTitle);
final String contentText = String.format(context.getResources().getString(R.string.notificationContent), physicalStop.getName(), departure
.getLine().getShortName(), fmt.print(departure.getDateTime()));
builder.setSmallIcon(R.drawable.ic_launcher).setContentTitle(title).setContentText(contentText);
return builder.build();
}
在日程安排通知方法中,我将警报管理器配置为使用RTC_WAKUPE类型的次数,我给它类似于currentTime +一些延迟(使用Joda Time Duration
类计算)
当在不久的将来以适当的通知时间(即LocalDateTime when = now + 5 minutes
)调用所有这些代码时,警报管理器永远不会调用广播接收器
答案 0 :(得分:-1)
<receiver android:name=".NotificationPublisher" android:exported="false" />
无效
我必须设置接收器的完整包名
<receiver android:name="com.xxx.xxx.NotificationPublisher" android:exported="false" />