How to persistently save PendingIntent provided by

2019-06-17 05:42发布

问题:

let's say I want to implement an app which exposes services to other apps (like Google Play Services..).

potential apps would register to my special events associated with my services, and would be notified at the right time.

I was thinking to implement this exactly like Google did with the Google Play services:

thanks to Android Inter-Process Communication, other apps could bind to my app Service, and by that - pass to my app PendingIntent "callback" that I could execute for them at the right time.

now, I'll get to the problem:

  • my app process currently running (in background) and holding reference to PendingIntent provided by other app.

  • now, from some reason (System decisions/ user explicitly) my process been stopped.

  • my process cumming back in some point, and come back to "do it's thing.."

in that point - I lost reference to the PendingIntent provided to me before, and I don't see any way in the API to retrieve back reference to it.

also I don't see any way to save persistently(database/sharedPreferences/file system) saving the pending intent for latter on usage

my questions are:

  • is it possible to store pending intent persistently somehow?

  • is it possible to "get back" reference to the same pending intent I already got before?

  • if not, is there any other suggestion to implement such thing as I described?

回答1:

is it possible to store pending intent persistently somehow?

No.

is it possible to "get back" reference to the same pending intent I already got before?

Not from the OS. If you have some other "bootstrap" communications method, you could ask the original app to re-supply a PendingIntent. For example, you could send a broadcast stating that you need apps to re-register; apps using your service would listen for such broadcasts and give you a fresh PendingIntent.

Or, skip the PendingIntent entirely and use something else. For example, apps could export a BroadcastReceiver. Where they would register a PendingIntent in your current plan, they would simply provide you the ComponentName of the BroadcastReceiver. That information (package name and class name) could be persisted, and you could then send a broadcast to that specific ComponentName as needed.

Note that with any strategy that involves persistence, you will need to deal with the cases where the client app has been upgraded and the old stored details are now incorrect (e.g., they refactored their code, and the old ComponentName is now invalid).



回答2:

I say Yes,it is possible to save pending intent for using right time but not as usual there is possibility something already happened with pending intent or another application maybe removed so pending intent is no more useful...But if pending intent is not destroyed yet then you save it for a right time.And fire pending intent as usual..

CODE:

public void savePendingIntent(Context context,PendingIntent pendingIntentYouWantToSave)
{
    int YEAR=2015;
    int MONTH=10; //remember month start from 0
    int DATE=25;
    int HOUR=12;
    int MINUTE=10;
    int SECOND=0;
    Calendar righttime = Calendar.getInstance();
    righttime.setTimeInMillis(System.currentTimeMillis());
    righttime.set(YEAR, MONTH,DATE, HOUR, MINUTE, SECOND);
    AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    Intent intent = new Intent(context, AlarmBroadcastReceiver.class);
    intent.putExtra("SAVED_PI", pendingIntentYouWantToSave);
    PendingIntent pi = PendingIntent.getBroadcast(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
    alarmManager.set(AlarmManager.RTC_WAKEUP, righttime.getTimeInMillis(),pi);
}

HERE IS AlarmBroadcastReceiver

public class AlarmBroadcastReceiver extends BroadcastReceiver 
{    
     @Override
     public void onReceive(Context context, Intent intent) 
     {   //your saved pending intent
         PendingIntent  SAVED_PI = (PendingIntent) intent.getParcelableExtra("SAVED_PI");
        //Fire it if need or save it again for later use
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        try {
            SAVED_PI.send(context, 0, intent);
        } catch (PendingIntent.CanceledException e) {
            Log.d("ERROR_ON_FIRE", "ERROR_ON_FIRE");
        }
     }
}

Hope this will help someone