Как упорно сохранять PendingIntent, предоставленный другим приложением
Предположим, я хочу реализовать приложение, которое предоставляет сервисы другим приложениям (например, Google Play Services..).
Потенциальные приложения будут регистрироваться на мои специальные мероприятия, связанные с моими сервисами, и получать уведомления в нужное время.Я думал реализовать это точно так же, как Google сделал с сервисами Google Play:
Благодаря Межпроцессной связи Android другие приложения могут привязываться к моему приложению Service
, а тем самым-передавать в мое приложение PendingIntent
"обратный вызов", который я мог бы казнить за них в нужный момент.
Теперь я перейду к проблеме:
-
Мой процесс приложения, запущенный в данный момент (в фоновом режиме) и содержащий ссылку на
PendingIntent
, предоставленную другим приложением. -
Теперь по какой-то причине (системные решения/ пользователь явно) мой процесс был остановлен.
-
Мой процесс кончает обратно в какой-то момент, и вернуться к "Сделать это вещь.."
В этом пункте-я потерял ссылку на PendingIntent
предоставлено мне ранее, и я не вижу никакого способа в API, чтобы получить обратную ссылку на него.
Также я не вижу никакого способа сохранить настойчиво (database/sharedPreferences/file system) сохранение отложенного намерения для последнего использования
Мои вопросы:
-
Можно ли как-то упорно хранить ожидающее намерение?
-
Возможно ли "вернуть" ссылку на то же отложенное намерение, которое я уже получил раньше?
-
Если нет, то есть есть еще какие-то предложения по реализации того, что я описал?
2 ответа:
Можно ли как-то упорно хранить ожидающее намерение?
Нет.
Возможно ли "вернуть" ссылку на то же ожидающее намерение, которое я уже получил раньше?
Не из ОС. Если у вас есть какой-то другой метод связи "bootstrap", вы можете попросить исходное приложение повторно предоставить
PendingIntent
. Например, вы можете отправить сообщение о том, что вам нужно повторно зарегистрировать приложения; приложения, использующие ваш сервис, будут прослушивать такие передачи и дать вам свежийPendingIntent
.Или полностью пропустите
PendingIntent
и используйте что-то другое. Например, приложения могут экспортироватьBroadcastReceiver
. Там, где они зарегистрируютPendingIntent
в вашем текущем плане, они просто предоставят вамComponentName
изBroadcastReceiver
. Эта информация (имя пакета и имя класса) может быть сохранена, и вы можете отправить широковещательную передачу на этот конкретныйComponentName
по мере необходимости.Обратите внимание, что при любой стратегии, включающей настойчивость, вам нужно будет иметь дело со случаями, когда клиентское приложение было обновлено, и старые сохраненные данные теперь неверны (например, они изменили свой код, и старый
ComponentName
Теперь недействителен).
Я говорю Да , можно сохранить отложенное намерение для использования правильного времени, но не так, как обычно, есть вероятность, что что-то уже произошло с отложенным намерением или другое приложение может быть удалено, поэтому отложенное намерение больше не полезно...Но если отложенное намерение еще не уничтожено, вы сохраняете его в нужное время.И огонь в ожидании намерения, как обычно..
Код:
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); }
Вот 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"); } } }
Надеюсь, это кому-то поможет