Android Java — изменение requestLocation обновляет обновление в классе

#java #android #class #gps

#java #Android #класс #gps

Вопрос:

У меня есть этот класс GPS_Service ниже. Он работает отлично. Из MainActivity я могу изменить значение переменной GPS_Service.gpsupdatedelay, чтобы настроить, как часто вызывается GPS через requestLocationUpdates в GPS_Service. Из MainActivity я изменяю значение через GPS_Service.gpsupdatedelay = 10000; Я думаю, мне также нужно вызвать какой-то аспект GPS_Service, чтобы изменить значение переменной? Я не вижу способа вызвать GPS_Service.onCreate() и не думаю, что мне следует это делать?

ВОПРОС: После корректировки значения gpsupdatedelay, как я могу добиться изменения значения переменной в параметрах requestLocationUpdates и фактически настроить частоту GPS?

Заранее благодарю вас.

 import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

public class GPS_Service extends Service {
    private LocationListener listener;
    private LocationManager locationManager;
    public static Integer gpsupdatedelay;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }
    @Override
    public void onCreate() {
        Log.e("GPS","onCreate");
        listener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                Intent i = new Intent("location_update");
                //i.putExtra("coordinates",location.getLongitude() " " location.getLatitude());

                i.putExtra("coordinate1",location.getLatitude());
                i.putExtra("coordinate2",location.getLongitude());
                Log.e("GPS","sendBroadcast");
                sendBroadcast(i);
            }
            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
            }
            @Override
            public void onProviderEnabled(String s) {
            }
            @Override
            public void onProviderDisabled(String s) {
                Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
            }
        };
        locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        //noinspection MissingPermission
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,gpsupdatedelay,0,listener);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if(locationManager != null){
            //noinspection MissingPermission
            locationManager.removeUpdates(listener);
        }
    }
}
  

Ответ №1:

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

Первым шагом является определение onStartCommand() переопределения метода, которое обновит новое значение интервала, отменит регистрацию старого прослушивателя местоположения и повторно зарегистрирует обновления местоположения с новым интервалом:

 public class GPS_Service extends Service {
    private LocationListener listener;
    private LocationManager locationManager;
    public Integer gpsupdatedelay = 10000; //NOT static!

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    //Added:
    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        int newGpsUpdateDelay = intent.getIntExtra("new_gps_update_delay", -99);
        if (newGpsUpdateDelay != -99 amp;amp; locationManager != null) {
            gpsupdatedelay = newGpsUpdateDelay;
            //noinspection MissingPermission
            locationManager.removeUpdates(listener);
            //noinspection MissingPermission
            locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,gpsupdatedelay,0,listener);
        }
        return START_STICKY;
    }

    @Override
    public void onCreate() {
        Log.e("GPS","onCreate");
        listener = new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                Intent i = new Intent("location_update");
                //i.putExtra("coordinates",location.getLongitude() " " location.getLatitude());

                i.putExtra("coordinate1",location.getLatitude());
                i.putExtra("coordinate2",location.getLongitude());
                Log.e("GPS","sendBroadcast");
                sendBroadcast(i);
            }
            @Override
            public void onStatusChanged(String s, int i, Bundle bundle) {
            }
            @Override
            public void onProviderEnabled(String s) {
            }
            @Override
            public void onProviderDisabled(String s) {
                Intent i = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                i.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
                startActivity(i);
            }
        };
        locationManager = (LocationManager) getApplicationContext().getSystemService(Context.LOCATION_SERVICE);
        //noinspection MissingPermission
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,gpsupdatedelay,0,listener);
    }
    @Override
    public void onDestroy() {
        super.onDestroy();
        if(locationManager != null){
            //noinspection MissingPermission
            locationManager.removeUpdates(listener);
        }
    }
}
  

Чтобы обновить значение из действия, просто создайте Intent, введите новое значение в new_gps_update_delay Extra и вызовите startService() , чтобы отправить обновленную информацию в службу:

     int newDelay = 678;
    Intent i = new Intent(this, GPS_Service.class);
    i.putExtra("new_gps_update_delay", newDelay);
    startService(i);
  

Это работает, поскольку startService() метод может быть вызван, даже если служба уже запущена. Если служба уже запущена, по сути, она просто запускает onStartCommand() переопределение метода.

Из документации для startService():

Если эта служба еще не запущена, она будет создана и запущена (при необходимости для нее будет создан процесс); если он запущен, он остается запущенным.

Каждый вызов этого метода приведет к соответствующему вызову метода целевой службы onStartCommand(Intent, int, int) с указанным здесь намерением . Это обеспечивает удобный способ отправки заданий в службу без необходимости привязки и вызова ее интерфейса.

Комментарии:

1. Спасибо за быстрый ответ. Я ценю это. Быстрый вопрос с вашим кодом выше, чтобы обновить переменную. Служба определения местоположения запускается сегодня. Итак, приведет ли использование startService (i) к повторному запуску и дублированию службы определения местоположения, или startService (i) приведет к остановке / перезапуску существующей / запущенной службы определения местоположения или startServuce (i) просто передаст переменную и вообще не повлияет на работу службы определения местоположения? Вы, вероятно, можете сказать, что я новичок в Android / Java.

2. Еще раз спасибо — После обновления класса с рекомендуемыми изменениями и настройки вызова класса из MainActivity я получил эту ошибку: «E / AndroidRuntime: ФАТАЛЬНОЕ ИСКЛЮЧЕНИЕ: основной процесс: com.example. исключение ftonyan.gps4, PID: 15469 java.lang.RuntimeException: не удается создать сервис com.example. ftonyan.gps6.GPS_Service: java.lang. Исключение NullPointerException: попытка вызвать виртуальный метод ‘int java.lang. Integer.intValue()’ для нулевой ссылки на объект в android.app.ActivityThread.handleCreateService(ActivityThread.java:3158)»

3. Я ценю помощь, просто интересно, что я сделал неправильно.

4. @FrankZappa Похоже, что, возможно, у вас больше нет начального значения. Взгляните на редактирование, которое я только что сделал: public Integer gpsupdatedelay = 10000;

5. Даниэль — спасибо. Вы были правы. Он запускался без начального значения задержки. Теперь он компилируется и запускается. Я тестирую, чтобы определить, будет ли он регулировать задержку на основе запрограммированных событий. Большое спасибо за вашу помощь.