Отслеживание настроек местоположения в библиотеке

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

Я видел людей, предполагающих, что мне нужно чтобы зарегистрироваться для широковещательного приемника android.location.PROVIDERS_CHANGED в моем файле AndroidManifest.xml. Я сделал это, но этот широковещательный приемник вызывается только тогда, когда я добавляю и удаляю поставщиков тестов в своем тестовом приложении. Я вообще не получаю его при переключении Служб геолокации в настройках устройства.

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

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

Если это поможет, я тестирую Moto G под управлением Android 4.4.2. Все, что я делал с геозонами, до сих пор работало нормально.

РЕДАКТИРОВАТЬ: Проведя дополнительные исследования, я обнаружил, что поведение трансляции PROVIDERS_CHANGED сильно различается в зависимости от версии и модели телефона. Мой Nexus 5 под управлением Android 5.1, кажется, работает нормально — я могу очень регулярно получать трансляции PROVIDERS_CHANGED. У меня также есть телефоны Moto G и Moto X с 4.4.x, и они никогда не производили для меня трансляцию PROVIDERS_CHANGED. Samsung Galaxy S3 на Android 4.2 будет производить для меня трансляцию, но перестанет делать это после того, как я использовал свою активность на карте с поставщиками тестовых местоположений.

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


person Rob Szumlakowski    schedule 26.05.2015    source источник
comment
это может быть полезно stackoverflow.com/questions/10311834/ Также вы пытались сохранить данные геозоны локально или где-то еще, чтобы предотвратить их удаление?   -  person Rich Luick    schedule 27.05.2015
comment
Я уже сохраняю геозоны локально, чтобы не потерять их навсегда (если только пользователь не очистит кеш). Это не моя проблема. Моя проблема в том, что я не получаю событие, которое уведомляет меня об изменении настроек поставщика местоположения. (т. е.: мне не сообщают, что они были удалены ОС, и мне не сообщают, когда мне безопасно перезагружать).   -  person Rob Szumlakowski    schedule 27.05.2015
comment
stackoverflow.com /questions/25156977/ Я регистрируюсь для provider_changed в коде Вам действительно нужен какой-то код, чтобы получить достойный ответ. IDK с 4.4.2 возможно не работает. Я не запускал свою среду разработки Android несколько месяцев.   -  person danny117    schedule 01.06.2015


Ответы (2)


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

Следует отметить одну вещь: приложение, использующее библиотеку, должно иметь receiver в своем AndroidManifest.xml. См. здесь и здесь, оба содержат информацию из @CommonsWare.

Добавление цитаты здесь на случай, если ссылка испортится:

Есть ли способ для проекта библиотеки самостоятельно зарегистрироваться для получателя в своем собственном файле манифеста?

Не в настоящее время.

Таким образом, любое приложение, использующее вашу библиотеку, должно иметь receiveradded в своем AndroidManifest.xml.

Обратите внимание, что это было протестировано на Android 4.4.4 на Samsung S4.

Я получил эту работу, используя BroadcastReceiver в проекте библиотеки, скомпилированном в файл aar.

Используя элемент receiver, настроенный в AndroidManifest.xml основного приложения, которое ссылается на BroadcastReceiver в библиотеке, я смог получить событие при любом изменении настроек местоположения:

  • Местоположение включено
  • Местоположение выключено
  • Измените режим определения местоположения на высокую точность
  • Измените режим определения местоположения на энергосберегающий
  • Измените режим определения местоположения на только GPS

Каждый раз, когда в настройки местоположения вносятся изменения, активируется BroadcastReceiver в библиотеке, даже если приложение не запущено.

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

Вот LocationProviderChangedReceiver.java в проекте библиотеки:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.util.Log;
import android.widget.Toast;

public class LocationProviderChangedReceiver extends BroadcastReceiver {
    private final static String TAG = "LocationProviderChanged";

    boolean isGpsEnabled;
    boolean isNetworkEnabled;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
        {
            Log.i(TAG, "Location Providers changed");

            LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            Toast.makeText(context, "GPS Enabled: " + isGpsEnabled + " Network Location Enabled: " + isNetworkEnabled, Toast.LENGTH_LONG).show();
        }
    }

}

Затем в основном приложении я поместил скомпилированный myLibrary.aar в папку libs и настроил build.gradle для компиляции aar:

 repositories{
        flatDir{
            dirs 'libs'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:appcompat-v7:22.1.1"
    compile "com.google.android.gms:play-services:7.3.0"

    compile 'com.mylibrary.daniel:mylibrary:1.0@aar'

}

Настройте receiver в AndroidManifest.xml основного приложения:

    <receiver
        android:name="com.mylibrary.daniel.mylibrary.LocationProviderChangedReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="android.location.PROVIDERS_CHANGED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

Затем установил приложение и изменил настройки местоположения несколькими способами. BroadcastReceiver в библиотеке срабатывал каждый раз:

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

введите здесь описание изображения

person Daniel Nugent    schedule 01.06.2015
comment
Спасибо за ваш ответ. Мой код был в основном таким же, как ваш. Я попытался поместить свой BroadcastReceiver как в свое основное приложение, так и в свою библиотеку, и поведение было таким же. Я могу регулярно получать трансляции на свой Nexus 5 независимо от того, находится ли BroadcastReceiver в библиотеке или в приложении. Я думаю, что пока я объявляю свой BroadcastReceiver в файле AndroidManifest.xml моей библиотеки и использую Gradle для выполнения своих сборок, не имеет значения, где находится BroadcastReceiver. Другие телефоны гораздо менее надежны. Я думаю, что Android просто глючит, и я перестал работать над этой проблемой. - person Rob Szumlakowski; 05.06.2015
comment
Да, это работает, когда приложение рядом, но когда оно убито/закрыто из диспетчера задач, у меня не работает. Я использую Android версии 4.4.4 Kitkat на устройстве MI3. - person Poras Bhardwaj; 18.05.2016

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

<receiver android:name=".Receivers.LocationModeReceiver">
    <intent-filter>
        <action android:name="android.location.MODE_CHANGED" />
    </intent-filter>
</receiver>
person Donnie    schedule 06.01.2016