无法设置正确的上下文来取消alarmmanager

时间:2017-05-13 08:33:53

标签: android android-intent alarmmanager android-context android-pendingintent

我已经创建了一个警报,其中包含一个通知和一个停止警报的按钮,但似乎我必须获得Context的某些问题才能取消AlarmManager

我已经研究了很多,我认为我已经应用了我发现的大部分内容,但不知何故无法使其发挥作用。

我知道PendingIntent必须是相同的,在我看来他们也有相同的请求代码。

AlarmSlave.class - 设置闹钟

 public class AlarmSlave /*extends Service*/ {

    private static final String STOP_ACTION = "STOP";

    private int hourOfDay;
    private int minuteOfHour;


    private AlarmManager alarmManager;
    private PendingIntent pendingIntent;

    public AlarmSlave() {

    }
AlarmSlave(int hour, int minute) {

        hourOfDay = hour;
        minuteOfHour = minute;

    }

    public void setAlarm(Context context) {

        alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        /*Intent intent = new Intent(context, AlarmReceiver.class);*/
        pendingIntent = PendingIntent.getBroadcast(context, 327, new Intent(context, AlarmReceiver.class), 0);

        Calendar calendar = Calendar.getInstance();
        calendar.set(Calendar.HOUR_OF_DAY, hourOfDay);
        calendar.set(Calendar.MINUTE, minuteOfHour);
        alarmManager.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), pendingIntent);

        Log.d("Ctx setAlarm ", context.toString());

    }

AlarmReceiver.class - 播放铃声非常多。

    public class AlarmReceiver extends WakefulBroadcastReceiver{

    @Override
    public void onReceive(final Context context, Intent intent){

        /*MainActivity inst = MainActivity.instance();

        Log.d("Testing","this is here"+inst);*/

        Uri alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM);
        if (alarmUri == null){
            alarmUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
        }

        Ringtone ringtone = RingtoneManager.getRingtone(context, alarmUri);
        ringtone.play();


        ComponentName componentName = new ComponentName(context.getPackageName(), AlarmService.class.getName());
        startWakefulService(context, (intent.setComponent(componentName)));
        setResultCode(Activity.RESULT_OK);
    }
}

AlarmService.class - 这是显示通知的内容,内容意图工作正常,但对于它们不是的操作。

    public class AlarmService extends IntentService {

    public static final String STOP_ACTION = "STOP";

    public AlarmService() {
        super("AlarmService");
    }


    @Override
    public void onHandleIntent(Intent intent) {
        sendNotification("Wake Up! Wake Up");
    }

    private void sendNotification(String msg) {
        Log.d("AlarmService", "Preparing to send notification...:" + msg);
        NotificationManager notificationManager = (NotificationManager) getApplicationContext().getSystemService(Context.NOTIFICATION_SERVICE);

        //PendingIntent pendingIntent = PendingIntent.getActivity(getApplicationContext(), 327, new Intent(getApplicationContext(), AlarmActivity.class), 0);
        int notificationId = 1; // just use a counter in some util class...
        PendingIntent dismissIntent = AlarmActivity.getDismissIntent(notificationId, getApplicationContext());

        /*Intent stopIntent = new Intent(this, AlarmSlave.class);
        stopIntent.setAction(STOP_ACTION);

        PendingIntent stopPendingIntent = PendingIntent.getBroadcast(this, 10, stopIntent, 0);*/

        NotificationCompat.Builder alarmNotificationBuilder = new NotificationCompat.Builder(getApplicationContext())
                .setContentTitle("Alarm")
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setStyle(new NotificationCompat.BigTextStyle().bigText(msg))
                .setContentText(msg)
                .addAction(R.mipmap.ic_launcher_round, "STOP", dismissIntent);

        alarmNotificationBuilder.setContentIntent(dismissIntent);
        notificationManager.notify(1, alarmNotificationBuilder.build());

        Log.d("AlarmService", "Notification Sent");
    }
}

ContextApp.class - 这是为我生成Context的内容。

public class ContextBitchApp extends Application {

 private static Context mContext;

@Override
public void onCreate(){
    super.onCreate();
    mContext = getApplicationContext();
}

public static Context getContext(){
    return mContext;


   }
}

请原谅某些语言的命名,在两天内尝试了几件不同的事情后,完全失败了。

编辑:这是Log Context显示的05-13 09:37:55.208 24235-24235/<omitted> D/Ctx setAlarm: <omitted>.ContextBitchApp@7709bb7 05-13 09:41:18.760 3244-3244/<omitted>:remote D/Ctx onReceive: android.app.ReceiverRestrictedContext@2c317d9 05-13 09:41:18.760 3244-3244/<omitted>:remote D/Ctx cancelAlarm: android.app.ReceiverRestrictedContext@2c317d9

{{1}}

编辑:更新代码

2 个答案:

答案 0 :(得分:0)

我使用0代替PendingIntent.FLAG_UPDATE_CURRENT并取消方法正常工作,尝试在两个意图中使用0或尝试将PendingIntent.FLAG_CANCEL_CURRENT设置为private void cancelAlarm(Context context)方法中的待定意图。

答案 1 :(得分:0)

所有与Context混在一起导致您的问题。你绝对不能这样做:

private static  Context ctx = ContextBitchApp.getContext();
private static final Context ctxCopy = ctx;

加载类时,static变量被初始化。目前,您还不知道ContextBitchApp.getContext()会返回什么。

在任何情况下,您都不需要尝试保存Context等等。当您需要getApplicationContext()作为参数传递给Context时,请始终使用PendingIntent.getBroadcast()

此外,在致电AlarmManager.cancel()后,您也可以通过调用PendingIntent取消cancel()