Подтвердить что ты не робот

Делают ли Geofences активными в android после перезагрузки устройства?

Я пишу приложение, которое должно использовать геообслуживание, когда кто-то входит или выходит из нескольких сайтов в течение всего срока службы установленного приложения.

Моя реализация геопостановки (очень похожая на вторую ссылку ниже) работает нормально, когда я впервые устанавливаю приложение, как при перемещении в/из геообъектов, так и при использовании макетных мест для имитации его, пока устройство не перезагрузится,

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

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

Это ссылки, которые я просмотрел при переполнении стека: Являются ли Android-геофорумы выжившими после перезагрузки?

Android Geofence в конечном итоге перестает получать намерения перехода

Устанавливаются ли Android Geofences до удаления/истечения срока действия или пока не запущен мой PendingIntent

Если кто-то знает ответ на вопрос, будут ли они стоять после перезагрузки или работать, если они этого не сделают, это будет очень признательно! Моя последняя надежда в настоящее время состоит в том, чтобы создать слушателя для BOOT_COMPLETED и перерегистрировать их при запуске, но id предпочитает делать это только в случае крайней необходимости.

Большое спасибо!

Изменить: пока я не нашел окончательного (в письменном виде) ответа, я уверен, что то, что опубликовал г-н ТониК, является правильным и решил использовать это решение. Большое спасибо TonyC!

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

Это в манифесте:

<!-- Listen for the device starting up -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

<receiver android:name="com.YOUR.PACKAGE.geofence.BootCompleteReceiver">
    <intent-filter>
        <action android:name="android.intent.action.BOOT_COMPLETED"/>
    </intent-filter>
</receiver>

а затем создайте для него широковещательный приемник, который будет перерегистрировать геозоны при загрузке:

package com.YOUR.PACKAGE.geofence;

import android.app.PendingIntent.CanceledException;
import android.content.Context;
import android.content.Intent;
import android.support.v4.content.WakefulBroadcastReceiver;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.location.Geofence;

public class BootCompleteReceiver extends WakefulBroadcastReceiver
{
    private static final String TAG = "BootCompleteReceiver";

    @Override
    public void onReceive(Context context, Intent intent)
    {
        //Do what you want/Register Geofences
    }
}

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

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

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

4b9b3361

Ответ 1

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

Ответ 2

Geofences не выдерживает перезагрузки. Существуют и другие случаи, когда вам придется перерегистрировать геопостановки.

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

Пусть идут по пунктам, принимая во внимание новые ограничения выполнения фона, введенные начиная с Android O:

  • Устройство перезагружено

Это можно обработать, добавив следующее в ваш фильтр намерений, поскольку они освобождаются от запрещенного запрета на трансляцию:

<action android:name="android.intent.action.BOOT_COMPLETED" />

Затем обязательно добавьте следующее разрешение на ваш манифест:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

Вы можете захотеть поймать новый LOCKED_BOOT_COMPLETED, введенный в Android N:

<action android:name="android.intent.action.LOCKED_BOOT_COMPLETED" />

Но, если вы это сделаете, вам также нужно будет пометить ваш приемник android:directBootAware="true". Это приводит к последствиям для вашего приложения. А именно, что любые файлы на основе данных, которые вы получаете, должны выполняться с использованием защищенного устройства. Длинные и короткие, если вам не нужно получать уведомления, когда устройство загружается на экран блокировки, не используйте LOCKED_BOOT_COMPLETED.

  • Приложение удалено и переустановлено.

Опять же, нам повезло, так как вы можете использовать это явное намерение:

<action android:name="android.intent.action.MY_PACKAGE_REPLACED" />
  • Данные приложения очищаются

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

  • Данные служб Google Play очищаются

Это можно решить, добавив следующее к получателю:

<intent-filter>
    <!-- Used to watch for Google Play Services data cleared -->
    <action android:name="android.intent.action.PACKAGE_DATA_CLEARED" />
    <data android:scheme="package" android:sspPrefix="com.google.android.gms"/>
</intent-filter>

а затем добавив следующий код в метод BroadcastReceiver onReceive:

String action = intent.getAction();
if (TextUtils.equals(Intent.ACTION_PACKAGE_DATA_CLEARED, action)) {
    Uri uri = intent.getData();
    if (uri.toString().equals("package:com.google.android.gms")) {
        // Code here to handle Google Play services data cleared
    }
}

Это способ Android, уведомляющий вас через API геообъектов, что службы определения местоположения больше недоступны и обозначается путем отправки GeofencingEvent с кодом ошибки и состояния GEOFENCE_NOT_AVAILABLE.

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

До Android O, зарегистрировав BroadcastReceiver для android.location.MODE_CHANGED_ACTION, вы получите этот крючок. На Android O и более поздних версиях это скрытое намерение запрещено, и ваш BroadcastReceiver больше не будет вызываться, поэтому нужен еще один крючок.

Для Android O и более поздних версий я обнаружил, что с помощью JobScheduler совместно с JobInfo.Builder.addTriggerContentUri для мониторинга URI Settings.Secure.LOCATION_PROVIDERS_ALLOWED работает с этой целью и даже запускает ваше приложение, если оно в настоящее время не запускается для вызова ваш JobService. Для этого подхода требуется API> = 24. Я проверил, что это работает, в том числе с Android P (API 28).

Несколько предостережений с подходом JobScheduler:

  1. Ваше приложение может не получить уведомление сразу после изменения, но в моем тестировании он получает уведомление в течение нескольких минут.
  2. LOCATION_PROVIDERS_ALLOWED устарел и может быть удален в будущей версии Android.

Итак, если вы в порядке с версией minApi 24, вы можете просто использовать JobScheduler/JobService, чтобы получить hook.Secure.LOCATION_PROVIDERS_ALLOWED.

Но если вам не нравится отказываться от 10% вашей пользовательской базы (на момент написания этой статьи KitKat (API 19) отображает 9,1% активной базы Android-пользователей), и для этого требуется меньший minApi, вам нужно будет иметь как BroadcastReceiver и JobService.