Узнать текущее местоположение пользователя — Android

#java #android

Вопрос:

Я знаю, что в Интернете есть много примеров на эту тему, но моя проблема не в коде, а в той части, где я получаю местоположение. Функция FusedLocationProviderClient.getLastLocation() всегда возвращает значение null, когда я раньше не открывал Карты Google. Чтобы узнать свое текущее местоположение, мне нужно открыть карты Google, чтобы узнать свое текущее местоположение, и после этого мое приложение сможет узнать его местоположение. Мой вопрос: есть ли способ отслеживать мое текущее местоположение, не открывая карты Google раньше? Вот что я попробовал:

 package com.example.gps;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;

import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Address;
import android.location.Geocoder;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.Switch;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResu<
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.tasks.OnSuccessListener;

import java.io.IOException;
import java.util.List;

public class MainActivity extends AppCompatActivity {

public static final int DEFAULT_UPDATE_INTERVAL = 30;
public static final int FAST_UPDATE_INTERVAL = 5;
public static final int PERMISSIONS_FINE_LOCATION = 99;
TextView tv_lat, tv_lon, tv_altitude,
        tv_accuracy, tv_speed, tv_sensor, tv_updates, tv_address;
Switch sw_locationupdates, sw_gps;

//    Google API for location services.
FusedLocationProviderClient fusedLocationProviderClient;

//    Location request config file for all settings related to FusedLocationProviderClient
LocationRequest locationRequest;

LocationCallback locationCallBack;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    tv_lat = findViewById(R.id.tv_lat);
    tv_lon = findViewById(R.id.tv_lon);
    tv_altitude = findViewById(R.id.tv_altitude);
    tv_accuracy = findViewById(R.id.tv_accuracy);
    tv_speed = findViewById(R.id.tv_speed);
    tv_sensor = findViewById(R.id.tv_sensor);
    tv_updates = findViewById(R.id.tv_updates);
    tv_address = findViewById(R.id.tv_address);
    sw_gps = findViewById(R.id.sw_gps);
    sw_locationupdates = findViewById(R.id.sw_locationsupdates);

    locationRequest = new LocationRequest();

    locationRequest.setInterval(1000 * DEFAULT_UPDATE_INTERVAL);

    locationRequest.setFastestInterval(1000 * FAST_UPDATE_INTERVAL);

    locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

    locationCallBack = new LocationCallback() {
        @Override
        public void onLocationResult(@NonNull LocationResult locationResult) {
            super.onLocationResult(locationResult);
            updateUIValues(locationResult.getLastLocation());
        }
    };

    sw_locationupdates.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (sw_locationupdates.isChecked()) {
                startLocationUpdates();
            } else {
                stopLocationUpdates();
            }
        }
    });

    sw_gps.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            if (sw_gps.isChecked()) {
                locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
                String text = "Using GPS sensors";
                tv_sensor.setText(text);
            } else {
                locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
                String text = "Using Towers   WIFi";
                tv_sensor.setText(text);
            }
        }
    });
    updateGPS();
}// end onCreate


private void stopLocationUpdates() {
    String text = "Location is NOT being tracked";
    tv_updates.setText(text);
    Toast.makeText(this, "done", Toast.LENGTH_SHORT).show();
    fusedLocationProviderClient.removeLocationUpdates(locationCallBack);
}


private void startLocationUpdates() {
    String text = "Location is being tracked";
    tv_updates.setText(text);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED
            amp;amp; ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        Toast.makeText(this, "a", Toast.LENGTH_SHORT).show();
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        //            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION,
        //                    Manifest.permission.ACCESS_COARSE_LOCATION}, 
        PERMISSIONS_FINE_LOCATION);
        //            return;
    }
    fusedLocationProviderClient.requestLocationUpdates(locationRequest, locationCallBack, null);
    updateGPS();
    Toast.makeText(this, "tracking again", Toast.LENGTH_SHORT).show();

}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);

    switch (requestCode) {
        case PERMISSIONS_FINE_LOCATION:
            if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                updateGPS();
            } else {
                Toast.makeText(this, "This app requires permission to be granted in order to work properly", Toast.LENGTH_SHORT).show();
                finish();
            }
    }
}

private void updateGPS() {
    fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(MainActivity.this);
    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED amp;amp; ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        fusedLocationProviderClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
            @Override
            public void onSuccess(Location location) {
                updateUIValues(location);
            }
        });
    } else {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSIONS_FINE_LOCATION);
        }
    }
}

private void updateUIValues(Location location) {
    if (location != null) {
        tv_lat.setText(String.valueOf(location.getLatitude()));
        tv_lon.setText(String.valueOf(location.getLongitude()));
        tv_accuracy.setText(String.valueOf(location.getAccuracy()));

        if (location.hasAltitude()) {
            tv_altitude.setText(String.valueOf(location.getAltitude()));
        } else {
            String text = "Not available- altitude";
            tv_altitude.setText(text);
        }

        if (location.hasSpeed()) {
            tv_speed.setText(String.valueOf(location.getSpeed()));
        } else {
            String text = "Not available- speed";
            tv_speed.setText(text);
        }

        Geocoder geocoder = new Geocoder(MainActivity.this);

        try {
            List<Address> addressList = geocoder.getFromLocation(location.getLatitude(),
                    location.getLongitude(), 1);
            tv_address.setText(addressList.get(0).getAddressLine(0));
        } catch (IOException e) {
            String text = "geocode didnt work";
            tv_address.setText(text);
            e.printStackTrace();
        }


    } else {
        Toast.makeText(this, "the gps doesnt work", Toast.LENGTH_SHORT).show();
    }


}


}
 

Этот код восстановит мое текущее местоположение и обновит название местоположения, но он будет работать только в том случае, если я открою карты Google, закрою карты Google и запущу свое приложение, оно будет работать. Может быть, это единственный способ заставить его работать? Но мне интересно, как другие приложения могут отслеживать мое местоположение, не открывая карты Google раньше.

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

1. Я нашел одну ошибку в тосте) Тост.makeText(это, «»gps не работает, тост. LENGTH_SHORT).show(); Здесь строка написана неправильно

Ответ №1:

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

Этот код работает без карты, я надеюсь, что у вас есть код разрешения на применение во время выполнения

также подайте заявку на получение разрешения в манифесте Android, проверьте его…

следуйте этим URL — адресам- https://javapapers.com/android/android-location-fused-provider/

общедоступный класс HomeFragment расширяет фрагмент, реализует LocationListener, GoogleApiClient.Обратные вызовы подключения, GoogleApiClient.OnConnectionFailedListener {

 GoogleApiClient googleApiClient;
LocationRequest locationRequest;
Location mCurrentLocation;
private static final long INTERVAL = 1000;
private static final long FASTEST_INTERVAL = 1000;
private int Play_SERVICES_RESOLUTION_REQUEST = 11;
FragmentHomeBinding binding;
AddressListDialogBinding dialogBinding;
AddressInterface anInterface;
FirebaseFirestore firebaseFirestore;
BottomSheetDialog dialog;


public HomeFragment() {
}

protected void createLocationRequest() {
    locationRequest = new LocationRequest();
    locationRequest.setInterval(INTERVAL);
    locationRequest.setFastestInterval(FASTEST_INTERVAL);
    locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}

@Nullable
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {

    LayoutInflater layoutInflater = getLayoutInflater();
    binding = FragmentHomeBinding.inflate(layoutInflater);
    View view = binding.getRoot();
    setHasOptionsMenu(true);
    return view;

}

@Override
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    init();
}

private void init() {

    if (!isGooglePlayServicesAvailable()) {

    }

    createLocationRequest();
    anInterface = this;

    // setAddress();


    googleApiClient = new GoogleApiClient.Builder(getActivity())
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

}


@Override
public void onStart() {
    super.onStart();
    googleApiClient.connect();
}

@Override
public void onStop() {
    super.onStop();
    googleApiClient.disconnect();
}

private boolean isGooglePlayServicesAvailable() {
    int status = GooglePlayServicesUtil.isGooglePlayServicesAvailable(getActivity());
    if (ConnectionResult.SUCCESS == status) {
        return true;
    } else {
        GooglePlayServicesUtil.getErrorDialog(status, getActivity(), 0).show();
        return false;
    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    startLocationUpdates();
}

protected void startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED amp;amp; ActivityCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        return;
    }

    PendingResult<Status> pendingResult = LocationServices.FusedLocationApi.requestLocationUpdates(
            googleApiClient, locationRequest, this);
    Log.d("LocationUpdate", "Location update started ..............: ");
}

@Override
public void onConnectionSuspended(@NonNull int i) {

}

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

}

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

private void updateUI() {

    if (mCurrentLocation != null) {
        Log.e("getLocation", "updateUI: "   mCurrentLocation.getLatitude()   ":"   mCurrentLocation.getLongitude());

        Geocoder geocoder = new Geocoder(getActivity(), Locale.getDefault());
        try {
            List<Address> addresses = geocoder.getFromLocation(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude(), 1);
            String address = addresses.get(0).getAddressLine(0);

            binding.tvCurrentLocation.setText(address);
        } catch (IOException e) {
            e.printStackTrace();
        }


    }
}

@Override
public void onPause() {
    super.onPause();
    stopLocationUpdate();
}

protected void stopLocationUpdate() {
    try {
        LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
    } catch (Exception e) {
        Log.e("error", "stopLocationUpdate: "   e.toString());
    }

}

@Override
public void onResume() {
    super.onResume();
    if (googleApiClient.isConnected()) {
        startLocationUpdates();
    }
}
 

}