Запрос обновлений местоположения в Android, когда FusedLocationAPI не возвращается

ОБНОВЛЕНИЕ: я получаю эту ошибку, как описано в этом вопросе (1 и 2), но в соответствии с этим ответ, это только внутренний журнал, и он не должен влиять на функциональность

V/GoogleSignatureVerifier: подпись com.google.android.gms недействительна

ИСХОДНЫЙ ВОПРОС:

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

Вот наиболее важные части моей службы:

ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ. Код был упрощен для удобства чтения. Все методы, связанные с привязкой службы, а также несколько обратных вызовов удалены, так как не являются частью проблемы

public class LocationService extends RoboService implements LocationListener {

    private static final String TAG = "LocationService";
    private static final long UPDATE_INTERVAL_IN_MILLISECONDS = TimeUnit.SECONDS.toMillis(5);
    private static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = TimeUnit.SECONDS.toMillis(1);
    private GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRequest;

    @Override
    public void onCreate() {
        super.onCreate();

        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addApi(LocationServices.API)
                    .build();

            mGoogleApiClient.connect();
        }

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return START_REDELIVER_INTENT;
    }

    public Location getCurrentLocation() {
        ConnectionResult connectionResult = mGoogleApiClient.blockingConnect();
        if (connectionResult.isSuccess()) {
            return LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        }
        return null;
    }

    public void startLocationUpdates() {
        ConnectionResult connectionResult = mGoogleApiClient.blockingConnect();
        if (connectionResult.isSuccess()) {
            Log.d(TAG, "startLocationUpdates: Posting request");
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
            Log.d(TAG, "startLocationUpdates: Request posted");
        }
    }

    @Override
    public void onLocationChanged(Location newLocation) {
        System.out.println("LocationService.onLocationChanged");
    }
}

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

Когда я вызываю startLocationUpdates(), выполнение кажется потерянным, когда я запрашиваю обновления местоположения, и ни Log.d(TAG, "startLocationUpdates: Request posted"), ни onLocationChanged(Location newLocation) никогда не вызываются.

Вот логарифм:

05-23 11:42:47.509 13547-13547/com.example.location D/MapPresenterImpl: onRouteAdded: Starting route tracking
05-23 11:42:47.512 13547-13950/com.example.location D/LocationService: startLocationUpdates: Posting request
05-23 11:43:28.115 13547-13557/com.example.location W/art: Suspending all threads took: 7.530ms

Мой код в основном скопирован из примеров для Android. Я скачал исходный код примера, и он у меня работает правильно. Два единственных различия между моим кодом и примером заключаются в том, что я нахожусь внутри службы и использую mGoogleApiClient.blockingConnect(), но я не знаю, как это может повлиять таким образом.

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

ВРЕМЕННОЕ РЕШЕНИЕ:

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

Способ запуска обновлений местоположения:

public void startLocationTracking(long routeId) {
    ConnectionResult connectionResult = mGoogleApiClient.blockingConnect();
    if (connectionResult.isSuccess()) {
        Intent intent = new Intent(this, TrackingService.class);
        PendingIntent pi = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        LocationRequest request = new LocationRequest();
        request.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        request.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, pi);
    }
}

Служба отслеживания:

public class TrackingService extends IntentService {

    public TrackingService() {
        super("TrackingService");
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        if (LocationResult.hasResult(intent)) {
            LocationResult locationResult = LocationResult.extractResult(intent);
            Location location = locationResult.getLastLocation();
            // Do whatever you need with the location
        }
    }
}

Используя этот метод, я столкнулся с еще одной странной проблемой. Если вы добавите какое-то дополнительное намерение, используемое для создания PendingIntent, при вызове TrackingService в дополнительных намерениях не будет никакого места, а будет только то, что было добавлено при создании намерения. Мой обходной путь для этого заключался в использовании SharedPreferences для передачи идентификатора, который мне нужен, но этот патч меня не очень убеждает. Эта проблема обсуждается в этом вопросе.


comment
Можете выложить логкэт   -  person akhil Rao    schedule 23.05.2016
comment
Конечно, но я не получаю никаких ошибок, так что это не очень полезно   -  person Jofre Mateu    schedule 23.05.2016
comment
Вы добавили права доступа Access_fine_location и Access_coarse_location?   -  person akhil Rao    schedule 23.05.2016
comment
Конечно. Как я ясно сказал, когда я пытаюсь получить текущее местоположение, оно работает безупречно. Без разрешений я бы получил ошибку.   -  person Jofre Mateu    schedule 23.05.2016
comment
Вы узнали, что blockingConnect отвечает SUCCESS?   -  person Shvet    schedule 23.05.2016
comment
Теперь попробуйте, удалив mGoogleApiClient.connect(); в методе Oncreate()   -  person akhil Rao    schedule 23.05.2016
comment
Вы можете видеть, что он успешно подключается, потому что первый журнал печатается в logcat.   -  person Jofre Mateu    schedule 23.05.2016
comment
В вашем коде, где вы вызвали этот метод? Я не нашел ничего, вызывающего этот метод! (startLocationUpdates()), вызывайте его после `mLocationRequest.setPriority()`.   -  person Shvet    schedule 23.05.2016
comment
@akhilRao разницы нет, как и должно быть по документации   -  person Jofre Mateu    schedule 23.05.2016
comment
@Shvet этот метод вызывается извне службы через привязку. Метод setPriority() вызывается при создании службы, поэтому он всегда вызывается до startLocationUpdates().   -  person Jofre Mateu    schedule 23.05.2016
comment
Дело в том, что при вызове этого метода mLocationRequest не должно быть нулевым или onCreate этой службы должно быть вызвано, иначе этот оператор будет выполняться через nullpointerexecption.   -  person Shvet    schedule 23.05.2016
comment
mLocationRequest никогда не имеет значение null при использовании. При использовании связанной службы метод onCreate() всегда вызывается перед возвратом привязки в методе onBind() в соответствии с жизненным циклом developer.android.com/images/service_lifecycle.png   -  person Jofre Mateu    schedule 23.05.2016