Как получать обновления местоположения, даже если GPS отключен, с помощью API плавного определения местоположения?

Этот вопрос можно задавать много раз, но я не мог найти для него решения. Мне нужно получить местоположение пользователя в фоновом режиме в течение 15 минут.

Он отлично работает, когда GPS включен, но когда GPS выключен, приложение не получает обновления местоположения. Мне нужно, чтобы получить хотя бы сетевое местоположение или местоположение Wi-Fi.

Как я могу добиться этого с помощью API плавного определения местоположения?

Менеджер местоположения имеет эту функцию, но в плавном расположении. Поскольку Google предлагает разработчикам использовать Location из API игровых сервисов, я не хочу использовать диспетчер местоположений. Как я могу добиться этого, поэтому позвольте мне опубликовать то, что я пробовал до сих пор:

import android.content.Context;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.util.Log;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.FusedLocationProviderApi;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

/**
 * Created by 4264 on 14-10-2016.
 */

public class Locationlistener implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener,LocationListener  {


    private Location mlocation; // location
    private double latitude; // latitude
    private double longitude; // longitude
    private GoogleApiClient mGAC;
    private Context mContext;
    public static final String TAG = "GPSresource";
    private FusedLocationProviderApi fusedLocationProviderApi;
    private LocationRequest locationRequest;

    public Locationlistener(Context c)
    {
        mContext = c;
        try {
            buildGoogleApiClient();
            mGAC.connect();
        }
        catch(Exception e)
        {
            Log.d(TAG,e.toString());
        }
    }

    protected synchronized void buildGoogleApiClient() {
        locationRequest = LocationRequest.create();
        locationRequest.setPriority(LocationRequest.PRIORITY_LOW_POWER);
        locationRequest.setInterval(1);
        locationRequest.setFastestInterval(1);
        mGAC = new GoogleApiClient.Builder(mContext)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
       }


    public double getLatitude(){
        if(mlocation != null){
            latitude = mlocation.getLatitude();
        }

        // return latitude
        return latitude;
    }

    /**
     * Function to get longitude
     * */
    public double getLongitude() {
        if (mlocation != null) {
            longitude = mlocation.getLongitude();
        }

        // return longitude
        return longitude;
    }

    public Location GetLocationBlocking() throws InterruptedException {



        //      String lat=String.valueOf(moCurrentLocation.getLatitude());
        //    String longt=String.valueOf(moCurrentLocation.getLongitude());
//        Toast.makeText(oContext,"Lat"+lat+"long"+longt,Toast.LENGTH_SHORT).show();
        return mlocation;

    }


    @Override
    public void onConnected(Bundle bundle) {
            Location oLocation = LocationServices.FusedLocationApi.getLastLocation(mGAC);
            if (mGAC != null) {

                mlocation = oLocation;
            getLatitude();
            getLongitude();
            if (oLocation != null){
              Log.d("lat",String.valueOf(mlocation.getLatitude()));
            Log.d("long",String.valueOf(mlocation.getLongitude()));
            }
            else{
                LocationServices.FusedLocationApi.requestLocationUpdates(mGAC, locationRequest, this);
        }   }}


    @Override
    public void onConnectionSuspended(int i) {

    }




    @Override
    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    }

    @Override
    public void onLocationChanged(Location location) {
        mlocation=location;
    }
}

person M.Yogeshwaran    schedule 15.10.2016    source источник
comment
см. это .stackoverflow.com/questions/34305377/   -  person Vishal Thakkar    schedule 15.10.2016


Ответы (1)


я не понимаю, когда вы говорите, что не хотите использовать диспетчер местоположения и GPS... посмотрите на это Стратегии определения местоположения... на основе этого документа у нас есть 3 стратегии доступа к местоположению:

  1. GPS
  2. Поставщик сетевого местоположения
  3. или используя оба

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

private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;

private long UPDATE_INTERVAL = 10 * 1000;  /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    // Create the location client to start receiving updates
    mGoogleApiClient = new GoogleApiClient.Builder(this)
                          .addApi(LocationServices.API)
                          .addConnectionCallbacks(this)
                          .addOnConnectionFailedListener(this).build();
}

protected void onStart() {
    super.onStart();
    // Connect the client.
    mGoogleApiClient.connect();
}

protected void onStop() {
    // Disconnecting the client invalidates it.
    LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);

    // only stop if it's connected, otherwise we crash
    if (mGoogleApiClient != null) {
        mGoogleApiClient.disconnect();
    }
    super.onStop();
}

public void onConnected(Bundle dataBundle) {
    // Get last known recent location. 
    Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    // Note that this can be NULL if last location isn't already known.
    if (mCurrentLocation != null) {
      // Print current location if not null
      Log.d("DEBUG", "current location: " + mCurrentLocation.toString());
      LatLng latLng = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
    }
    // Begin polling for new location updates.
    startLocationUpdates();
}

@Override
public void onConnectionSuspended(int i) {
    if (i == CAUSE_SERVICE_DISCONNECTED) {
      Toast.makeText(this, "Disconnected. Please re-connect.", Toast.LENGTH_SHORT).show();
    } else if (i == CAUSE_NETWORK_LOST) {
      Toast.makeText(this, "Network lost. Please re-connect.", Toast.LENGTH_SHORT).show();
    }
}

// Trigger new location updates at interval
protected void startLocationUpdates() {
    // Create the location request
    mLocationRequest = LocationRequest.create()
        .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
        .setInterval(UPDATE_INTERVAL)
        .setFastestInterval(FASTEST_INTERVAL);
    // Request location updates
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,
        mLocationRequest, this);
}

а затем зарегистрируйтесь для получения обновлений местоположения с помощью onLocationChanged:

public void onLocationChanged(Location location) {
    // New location has now been determined
    String msg = "Updated Location: " +
        Double.toString(location.getLatitude()) + "," +
        Double.toString(location.getLongitude());
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    // You can now create a LatLng Object for use with maps
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}

Дополнительную информацию об API-интерфейсе Fused Location см. в разделе Настройка определения местоположения приложения ypur Устранение неполадок с обновлениями местоположения

Обновления местоположения всегда должны выполняться с использованием GoogleApiClient с использованием LocationServices.API, как показано выше. Не используйте старые API-интерфейсы Location, которые менее надежны. Даже при использовании правильного FusedLocationApi есть много вещей, которые могут пойти не так. Рассмотрите следующие возможные проблемы:

  • Добавили ли вы необходимые разрешения? Убедитесь, что ваше приложение имеет разрешения INTERNET и ACCESS_COARSE_LOCATION, чтобы обеспечить доступ к местоположению, как показано в руководстве выше.
  • Вы получаете null при вызове LocationServices.FusedLocationApi.getLastLocation? Это нормально, так как этот метод возвращает значение только в том случае, если уже есть местоположение, недавно полученное другим приложением. Если это возвращает null, это означает, что вам нужно начать получать обновления местоположения с LocationServices.FusedLocationApi.requestLocationUpdates, прежде чем получать местоположение, как показано выше.
  • Вы пытаетесь определить местоположение с помощью эмулятора genymotion? Убедитесь, что вы включили GPS и правильно настроили широту/долготу. Попробуйте перезапустить эмулятор, если это необходимо, и повторно включить GPS или попробовать устройство (или официальный эмулятор), чтобы исключить проблемы, связанные с genymotion.
person mohammadreza khalifeh    schedule 15.10.2016
comment
он должен работать в фоновом режиме, а не при взаимодействии с пользователем, тогда как можно подключиться к активности - person M.Yogeshwaran; 15.10.2016