Using AlarmManager to sync data with a server

2019-08-26 23:48发布

问题:

First of all, I apologize for my English.

I need to sent data to a server and query for data in that server from time to time, maybe from week to week.

So I'm going to use the AlarmManager to do that. I wanna know if I can register two separated pending intents in the alarm manager, one to push data to the server, and another one to query data from the server. Can I register those two intents every time the application executes? Or do I need to test if I already got those intents registered?

I'm asking that because I'm afraid that I register one alarm to execute one week from now and then the user close the app and start again and the alarm is registered again one week from now and in the end will never be launched.

Another thing, is it safe to register a service to be executed with the AlarmManager?

Oh and this is the code I'm using:

long WEEK_IN_MILLIS = AlarmManager.INTERVAL_DAY * 7;

PendingIntent querySyncService = PendingIntent.getService(context, 0, new Intent(context,
    QuerySyncService.class), PendingIntent.FLAG_CANCEL_CURRENT);

PendingIntent pushSyncService = PendingIntent.getService(context, 1, new Intent(context,
    PushSyncService.class), PendingIntent.FLAG_CANCEL_CURRENT);

AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);

alarmManager.setInexactRepeating(AlarmManager.RTC, WEEK_IN_MILLIS, WEEK_IN_MILLIS, querySyncService);

alarmManager.setInexactRepeating(AlarmManager.RTC, WEEK_IN_MILLIS, WEEK_IN_MILLIS, pushSyncService);

I was thinking in putting this code inside some method and then just call the method every time the app start.

And I also saw that the solution I should probably use is the SyncAdapter, but the SyncAdapter just seems to be dirt, with a lot of code that does nothing, for example, you need one Stub Authenticator, then one Stub Authenticator Service and one Stub Content Provider and again one Stub Content Provider Service, then a lot of code for the Sync Adapter, then another bunch of code to only run the SyncAdapter. This just seems too dirty for me since I don't need a content provider neither one Authenticator.

回答1:

You can, most certainly, register two separate Intents, with the AlarmManager. Just be sure to use different ids in your call to PendingIntent.getService... (and, btw, I suggest that you not use 0 as an id. 0s are just to easy to come by, in Java). Use the ACTION, or a parameter in the Extras, to distinguish between them.

There is no reason to use a BroadcastReceiver: you can fire the intent at the Service directly. If you are concerned about security, don't export the Service. A PendingIntent is fired from within your application, so there is no need to make the Service externally visible.

Finally, although you are right about the overhead for a SyncAdapter, it really is a great way to do exactly what you are trying to do. There is a good description of how to write one in EnterpriseAndroid (I am one of the authors). Once you get through the boiler-plate, it is actually almost elegant.

There is an example of a minimal SyncAdapter here.