AlarmManager不触发广播接收器

时间:2014-06-28 12:54:43

标签: android notifications broadcastreceiver alarmmanager

我正在尝试使用警报管理器来安排通知,以便在不久的将来向用户显示。

我的代码看起来像

自定义通知管理器,用于触发警报并在用户以某种方式“取消选择”通知时取消警报:

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)调用所有这些代码时,警报管理器永远不会调用广播接收器

1 个答案:

答案 0 :(得分:-1)

好吧,问题出在androidmanifest

<receiver android:name=".NotificationPublisher" android:exported="false"  />

无效

我必须设置接收器的完整包名

<receiver android:name="com.xxx.xxx.NotificationPublisher" android:exported="false"  />