Как исправить «GPS не может определить местоположение»?

Я создаю приложение для Android, чтобы получить свое текущее местоположение GPS. Сначала он работал, но теперь он всегда возвращает ноль. Он просто показывает значок GPS на панели уведомлений моего телефона, но значок не активируется и не выделяется. Я пробовал много трюков, но пока ничего не сработало. Вот мой код:

final FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
    @SuppressLint("RestrictedApi")
    @Override
    public void onClick(View view) {

        fab.setVisibility(View.VISIBLE);

        GpsTracker gt = new GpsTracker(getApplicationContext());
        Location l = gt.getLocation();
        if(l != null) {

            double lat = l.getLatitude();
            double lon = l.getLongitude();
            Toast.makeText(getApplicationContext(),"GPS Lat = "+lat+"\n lon = "+lon,Toast.LENGTH_SHORT).show();
            Snackbar.make(view, "GPS Lat = "+lat+"\n lon = "+lon, Snackbar.LENGTH_LONG)
                    .setAction("Action", null).show();
            } else {
                Snackbar.make(view, "GPS unable to Connect", Snackbar.LENGTH_LONG)
                        .setAction("Action", null).show();
                Toast.makeText(getApplicationContext(),"GPS unable to Connect",Toast.LENGTH_SHORT).show();
            }
        }
    });

GpsTracker.java

import android.content.Context;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import static android.content.Context.LOCATION_SERVICE;

public class GpsTracker implements LocationListener {

    public Context context;

    public GpsTracker(Context context) {
        super();
        this.context = context;
    }

    public Location getLocation(){
        if (ContextCompat.checkSelfPermission(context, android.Manifest.permission.ACCESS_FINE_LOCATION ) != PackageManager.PERMISSION_GRANTED) {
            Log.e("fist","error");
            return null;
        }
        try {
            LocationManager lm = (LocationManager) context.getSystemService(LOCATION_SERVICE);
            boolean isGPSEnabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
            if (isGPSEnabled) {
                lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 6000,10,this);
                Location loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                return loc;
            } else {
                Log.e("sec","Please enable your GPS");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public void onLocationChanged(Location location) {
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

    @Override
    public void onProviderDisabled(String provider) {
    }
}   

AndroidManifest.xml

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

person Hassan Hameed    schedule 25.04.2019    source источник
comment
возможный дубликат gps-трекера   -  person coroutineDispatcher    schedule 25.04.2019


Ответы (2)


Хасан,

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

  • Шаг первый

Настройте ключ Google API в консоли Google API: https://console.developers.google.com/?pli=1

Выберите Maps SDK для Android и включите его, а затем сгенерируйте в нем ключ API.

Консоль разработчика Google

  • Шаг второй

Скопируйте и вставьте ключ API в файл strings.xml в своем проекте.

strings.xml в вашем проекте

  • Шаг третий

Добавьте следующую зависимость в файл app.gradle.

implementation 'com.google.android.gms:play-services-maps:16.1.0'
  • Шаг четвертый

Добавьте следующее в свой AndroidManifest.xml после тега приложения

<meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
<meta-data
        android:name="com.google.android.geo.API_KEY"
        android:value="@string/google_maps_key" />

<meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="@string/google_maps_key" />
  • Шаг пятый

Реализуйте следующие классы

public class MainActivity extends AppCompatActivity
        implements  OnMapReadyCallback,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener, LocationListener {

/*Declare the following Variables */
    private final static int PLAY_SERVICES_RESOLUTION_REQUEST = 1000;
    private boolean mRequestingLocationUpdates = false;
    private static int UPDATE_INTERVAL = 10000; // 10 sec
    private static int FATEST_INTERVAL = 5000; // 5 sec
    private static int DISPLACEMENT = 10; // 10 meters
    public GoogleApiClient mGoogleApiClient;
    LocationRequest mLocationRequest;
    Location mLastLocation;
    public static double lat = 0, lng = 0;
    LocationManager locationManager;
    Location location = null;
  • Шаг шестой

Создайте следующие функции вне функции OnCreate.

protected synchronized void buildGoogleApiClient() {
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        mGoogleApiClient.connect();
        createLocationRequest();
    }

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FATEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(DISPLACEMENT);

    }

    @SuppressLint("MissingPermission")
    protected void startLocationUpdates() {
        try {
            LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, (LocationListener) this);
        } catch (Exception e) {
            Log.d("LOCATION_MSG", e.getMessage());
        }
    }

    protected void stopLocationUpdates() {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, (LocationListener) this);
    }
  • Шаг седьмой

Вызовите buildGoogleApiClient() в вашем onCreate

  • Шаг восьмой

Переопределить методы

 @Override
    public void onConnected(@Nullable Bundle bundle) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FATEST_INTERVAL);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
    }

    @Override
    public void onConnectionSuspended(int i) {
        mGoogleApiClient.connect();
    }

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

    }

    @SuppressLint("MissingPermission")
    @Override
    public void onLocationChanged(Location location) {
        mLastLocation = location;
        mLastLocation = LocationServices.FusedLocationApi
                .getLastLocation(mGoogleApiClient);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

    }
  • Шаг девятый

В вашем прослушивателе OnClick:

fab.setOnClickListener

Добавь это

    mLastLocation = LocationServices.FusedLocationApi
            .getLastLocation(mGoogleApiClient);
    startLocationUpdates();

                    if (mLastLocation != null)

    {

        try {
            lat = mLastLocation.getLatitude();
            lng = mLastLocation.getLongitude();
        } catch (Exception e) {
            lat = 0;
            lng = 0;
        }
      /* Check your log cat for the following */
 Log.d("LOC_Latitude" , Double.toString(lat));
       Log.d("LOC_Longitude" , Double.toString(lng));


    }else{

    //Something is a miss, maybe the location service on your phone is not on, it could even be the internet connection.               
    }
  • Что следует отметить Убедитесь, что у вас есть все необходимые разрешения для вашего манифеста, некоторые устройства потребуют разрешения, которые будут запрашиваться во время выполнения. Вы можете использовать следующее, чтобы сделать это

    /*Объявить этот метод вне нашей функции onCreate */

        public static boolean hasPermissions(Context context, String... permissions) {
    
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && context != null && permissions != null) {
                for (String permission : permissions) {
                    if (ActivityCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) {
                        return false;
                    }
                }
            }
            return true;
        }
    
    /*Add this in your onCreate Function */  
    
    
    
    String[] PERMISSIONS = {Manifest.permission.INTERNET, Manifest.permission.ACCESS_COARSE_LOCATION, Manifest.permission.ACCESS_FINE_LOCATION};
    
        if (!hasPermissions(this, PERMISSIONS)) {
            ActivityCompat.requestPermissions(this, PERMISSIONS, 1);
        }
    

Также убедитесь, что у вас есть следующие разрешения на файл AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />

Попробуйте это и вернитесь в любом случае, если вы все еще застряли.

person Osoro    schedule 25.04.2019
comment
Спасибо, это очень помогло мне, и теперь мой GPS начинает работать после получения помощи. - person Hassan Hameed; 25.04.2019

Вы получаете доступ только к последнему известному местоположению. Часто это значение равно нулю или совершенно не соответствует вашему текущему местоположению. Вы должны подождать, пока не получите несколько успешных показаний от onLocationChanged, прежде чем возвращать значение вызывающей стороне.

Возможно, вам следует разделить код, в котором вы инициализируете диспетчер местоположения, на метод startLocationTracking(). Затем в своем коде вызовите это при первом создании действия/фрагмента. Как только диспетчер местоположения получает события onLocationChanged, он обновляет переменную Public с текущим местоположением. Затем ваш метод getLocation() просто вернет эту переменную currentLocation вызывающей стороне. Затем у вас, вероятно, должен быть метод stopLocationTracking(), который вы вызываете, когда действие/фрагмент закрывается.

person Michael Dougan    schedule 25.04.2019
comment
Большое спасибо, теперь я понял, что делать с GPS - person Hassan Hameed; 25.04.2019