zoukankan      html  css  js  c++  java
  • Android 中PendingIntent---附带解决AlarmManager重复加入问题

    最近在程序中使用到了notification功能,自然,就涉及到了PendingIntent,下面总结下。

    1 什么是PendingIntent

    A description of an Intent and target action to perform with it. Instances of this class are created with getActivity(Context, int, Intent, int),getActivities(Context, int, Intent[], int)getBroadcast(Context, int, Intent, int), and getService(Context, int, Intent, int); the returned object can be handed to other applications so that they can perform the action you described on your behalf at a later time.

    简单的说,就是一个不立即执行的intent。虽然这里函数形式是getActivity,但这个函数的效果不仅仅是获得了一个对象,正如官网文档对这个函数的介绍     Retrieve a PendingIntent that will start a new activity, like calling Context.startActivity(Intent).      这个函数调用后,相应的pendingIntent就会在系统中注册,等待调用。如果想取消注册,必须在创建它的程序中cancel掉。在调用效果上,getActivityContext.startActivity(Intent)比,仅仅是延缓了执行。

    2 如何判断PendingIntent相同

    Because of this behavior, it is important to know when two Intents are considered to be the same for purposes of retrieving a PendingIntent. A common mistake people make is to create multiple PendingIntent objects with Intents that only vary in their "extra" contents, expecting to get a different PendingIntent each time. This does nothappen. The parts of the Intent that are used for matching are the same ones defined by Intent.filterEquals. If you use two Intent objects that are equivalent as perIntent.filterEquals, then you will get the same PendingIntent for both of them.

    There are two typical ways to deal with this.

    If you truly need multiple distinct PendingIntent objects active at the same time (such as to use as two notifications that are both shown at the same time), then you will need to ensure there is something that is different about them to associate them with different PendingIntents. This may be any of the Intent attributes considered byIntent.filterEquals, or different request code integers supplied to getActivity(Context, int, Intent, int)getActivities(Context, int, Intent[], int)getBroadcast(Context, int, Intent, int), or getService(Context, int, Intent, int).

    If you only need one PendingIntent active at a time for any of the Intents you will use, then you can alternatively use the flags FLAG_CANCEL_CURRENT orFLAG_UPDATE_CURRENT to either cancel or modify whatever current PendingIntent is associated with the Intent you are supplying.

    简单的说,要想要2个不同的PendingIntent,有2个办法

    A.用不同的intent(相同的intent指的是:same operation, same Intent action, data, categories, and components, 其实,action, data, categories, and components这4个属性都是intent的过滤条件,当然要一样才行!),特别注意只更改"extra contents“没用。

    B.用不同的requestCode。就是getActivity(Context, int, Intent, int)的第二个参数。

    3.创建时可以用的flag(就是getActivity(Context, int, Intent, int)的第四个参数)

    一般就4个

    FLAG_CANCEL_CURRENT

    请参见文档

    FLAG_NO_CREATE

    这个可以用来验证指定的pendingIntent是否已经存在于系统中了,在我写的程序里这样用

    Intent temIntent = new Intent("notificationCheck");
    PendingIntent oldSender = PendingIntent.getBroadcast(context, 0, temIntent, PendingIntent.FLAG_NO_CREATE);
    if(oldSender != null)
    {
    return;
    }

    Date now = new Date();
    Calendar calendar = Calendar.getInstance();
    calendar.setTime(now);
    calendar.set(Calendar.HOUR_OF_DAY,0);
    calendar.set(Calendar.MINUTE,0);
    calendar.set(Calendar.SECOND,0);


    PendingIntent operation = PendingIntent.getBroadcast(context, 0, temIntent, PendingIntent.FLAG_UPDATE_CURRENT);

    AlarmManager am = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
    am.setRepeating(AlarmManager.RTC_WAKEUP,calendar.getTimeInMillis(), 1000*60*15, operation);

    这样就保证了,不会重复向系统中注册alarm(解决的问题:每次注册都会导致alarm立即响应一次,即使不是设置的时间,不明白为什么))。

    其实这里没有直接对AlarmManager的信息进行验证,仅仅是通过验证pendingIntent是否在系统注册过,来间接检验是否已经加过了alarm。

    FLAG_ONE_SHOT

    请参见文档

    FLAG_UPDATE_CURRENT

    if the described PendingIntent already exists, then keep it but its replace its extra data with what is in this new Intent. This can be used if you are creating intents where only the extras change, and don't care that any entities that received your previous PendingIntent will be able to launch it with your new extras even if they are not explicitly given to it.

    当仅仅更换intent中的extra数据时,就用这个。

  • 相关阅读:
    nginx限流方案的实现(三种方式)
    Pthreads并行编程之spin lock与mutex性能对比分析(转)
    C/C++中float和double的存储结构(转)
    list_entry(ptr, type, member)——知道结构体内某一成员变量地址,求结构体地址
    stderr和stdout详细解说(转)
    结构体内存分配理解
    C中的C文件与h文件辨析(转)
    访问vector元素方法的效率比较(转)
    linux c中select使用技巧——计时器(转)
    thread::id
  • 原文地址:https://www.cnblogs.com/breezemist/p/3433680.html
Copyright © 2011-2022 走看看