Как отобразить уведомление, когда мое приложение находится в фоновом режиме? - PullRequest
0 голосов
/ 26 июня 2018

Я пытаюсь создать приложение для Android, которое имеет -

a Первая активность ( Активность запуска )

и Второе занятие

Чего я пытаюсь достичь:

First Actvity принимает данные от пользователя, извлекает данные из Интернета, используя AsyncTaskLoader . В onLoadFinished он проверяет, является ли ввод действительным и запускает ли он намерение для второго действия, чтобы показать больше деталей. Ввод также передается вместе с намерением.

Поскольку работа по сети может занять некоторое время, поэтому я решил показать уведомление, используя IntentService непосредственно перед созданием Second Activity, т.е. уведомление вызывается в onLoadFinished непосредственно перед Intent. Уведомление должно непосредственно начинать второе действие, если оно еще не запущено.

Что отлично работает:

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

Что не:

Когда пользователь уходит от первого действия во время загрузки данных, уведомление не отображается, потому что выполняется onPause . Я попытался найти его и узнал о BroadcastReceiver , JobScheduler и FirebaseJobDispatcher , но я не могу понять их и как они помогают.

Итак, я на правильном пути? И как я могу достичь той же функциональности, даже если приложение переходит в фоновый режим?

P.S. Код гораздо обширнее, чем предполагает проблема, поэтому я не включил его. Поэтому, если объяснение кажется неполным или грязным, я сделаю все возможное, чтобы прояснить ваши сомнения.

Ответы [ 4 ]

0 голосов
/ 27 июня 2018

Я наконец заставил его работать без использования BroadcastReciever или Сервиса, чтобы те из вас, кто не знаком с ними, могли ссылаться на это, но используйте его по своему усмотрению как Услуги и Ресиверы - рекомендуемый способ сделать это.

@Override
public void deliverResult(Data data) {
    super.deliverResult(data);
    showNotification(input);
}

Это метод в AsyncTaskLoader, который запускается после получения данных. Переопределите его и измените метод уведомления, который реагирует на щелчок уведомления.

private PendingIntent onClick(Context context) {
     return PendingIntent.getActivity(context, 0, new Intent(context, ExtraActivity.class).
putExtra(Intent.EXTRA_TEXT,input),PendingIntent.FLAG_UPDATE_CURRENT);
}

ExtraActivity аналогично this . Это позволяет вашему уведомлению отвечать, даже если действие было закрыто, но уведомление не было.

Опять же, это только обходной путь для этой конкретной ситуации, который заставляет меня обходить входную переменную во многих местах, и поэтому она может быть не такой эффективной с точки зрения производительности, как другие варианты.

0 голосов
/ 26 июня 2018

Зарегистрируйте широковещательный получатель через LocalBroadcastManager и определите фильтры. Теперь в зависимости от фильтров вы можете играть с элементами или намерениями пользовательского интерфейса.

IntentFilter filter = new IntentFilter();
    filter.addAction("A");
    filter.addAction("B");
    filter.addAction("C");
    LocalBroadcastManager.getInstance(getContext()).registerReceiver(dummyReceiver, filter);



private BroadcastReceiver dummyReceiver = new BroadcastReceiver() {
@Override
    public void onReceive(final Context context, final Intent intent) {
          //Do your work**
 }}

Попробуй это. Я реализовал это, и это работает.

0 голосов
/ 26 июня 2018

как мне добиться такой же функциональности, даже если приложение переходит в фоновый режим

используйте связанные услуги или намеренные услуги . Интент службы позволяют выполнять действия асинхронно. связанные службы могут предоставлять интерфейс, используя aidl . Пока служба связана, она будет менее вероятно уничтожена. Существуют различные способы привязки сервиса с использованием флагов.

imho, активность - это просто способ отображения пользовательского интерфейса. если вам нужна дополнительная работа, воспользуйтесь услугами. при работе со связанными сервисами через aidl вам придется продлить подключение к услуге . он получит интерфейс от службы после привязки.

0 голосов
/ 26 июня 2018

Да. Вы на правильном пути.

Вот пример из загрузчика карт, который я сделал. Надеюсь, вы не возражаете, но поскольку вы не дали контекста, мне пришлось найти подходящий пример.

/**
* @param entry the map entry to be downloaded
* @return returns a receiver that unzips the map file after downloading
*/
private BroadcastReceiver createMapReceiver(MapEntry entry) {
     return new BroadcastReceiver() {
         @Override
         public void onReceive(Context context, Intent intent) {
             unregisterReceiver(this); // we unregister this receiver after the download is complete
             receiveDownloadedFile(entry); // once we receive the map file, we run this function, but you can do whatever you want. This is the part of the code youn were asking for
         }
     };
}


void downloadMap() {

    // preparing the download
    BroadcastReceiver receiver = createMapReceiver(entry); // see function above

  DownloadManager manager = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
  registerReceiver(receiver, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));

  String downloadURL = fileListURL + entry.getFileName() + fileExtension; // building the url for the map
  DownloadManager.Request request = new DownloadManager.Request(Uri.parse(downloadURL));

  if (manager != null) {
      manager.enqueue(request
              .setDestinationUri(Uri.fromFile(new File(areaFolder, entry.getFolderName())))
                    .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI|DownloadManager.Request.NETWORK_MOBILE)
                    .setAllowedOverRoaming(false)
                    .setTitle("Some title, preferably taken from Strings.xml")
                    .setDescription("Some Description")
                    .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
            );
        } else {
            // if we couldn't find the DownloadManager
            onFailure(entry); // we simply run some onFailure function
        }

    }

Не забудьте разрешения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...