Как упорно сохранять PendingIntent, предоставленный другим приложением


Предположим, я хочу реализовать приложение, которое предоставляет сервисы другим приложениям (например, Google Play Services..).

Потенциальные приложения будут регистрироваться на мои специальные мероприятия, связанные с моими сервисами, и получать уведомления в нужное время.

Я думал реализовать это точно так же, как Google сделал с сервисами Google Play:

Благодаря Межпроцессной связи Android другие приложения могут привязываться к моему приложению Service, а тем самым-передавать в мое приложение PendingIntent "обратный вызов", который я мог бы казнить за них в нужный момент.

Теперь я перейду к проблеме:

  • Мой процесс приложения, запущенный в данный момент (в фоновом режиме) и содержащий ссылку на PendingIntent, предоставленную другим приложением.

  • Теперь по какой-то причине (системные решения/ пользователь явно) мой процесс был остановлен.

  • Мой процесс кончает обратно в какой-то момент, и вернуться к "Сделать это вещь.."

В этом пункте-я потерял ссылку на PendingIntent предоставлено мне ранее, и я не вижу никакого способа в API, чтобы получить обратную ссылку на него.

Также я не вижу никакого способа сохранить настойчиво (database/sharedPreferences/file system) сохранение отложенного намерения для последнего использования

Мои вопросы:

  • Можно ли как-то упорно хранить ожидающее намерение?

  • Возможно ли "вернуть" ссылку на то же отложенное намерение, которое я уже получил раньше?

  • Если нет, то есть есть еще какие-то предложения по реализации того, что я описал?

2 7

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");
        }
     }
}

Надеюсь, это кому-то поможет