#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();
}
}
}