I am developing a app which has to get the location information (latitude and longitude) of the device only once but as fast as possible. My code is taking too much time. It is taking around 2-3 minutes to fetch location. Especially for those devices if location button is initially off. I happened to see a relatable question Link below but that is almost 6 year old and I would think the answers are apt in 2021. My situation is also same, I also need to collect longitude and latitude information (for one time only) so I can find the distance between 2 devices. Please find the code that I have used for latitude and longitude information and kindly tell me is there is any better way to do my task . Using this code I will display current location in a text view (BuyerArea in code) , once location is displayed correctly I will save latitude and longitude information in firebase database
` public class BuyerAreaFinderActivity extends AppCompatActivity {
String currentGroupName, BuyerLatitude,BuyerLongitude;
Button BuyerAreaFetchBtn, continueBtn;
TextView BuyerArea; // to display location
private FirebaseUser User;
private Task<Void> UserTask;
private FirebaseAuth mAuth;
private DatabaseReference RootRef;
private String currentUserId;
FusedLocationProviderClient fusedLocationProviderClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_buyer_area_finder);
BuyerAreaFetchBtn= findViewById(R.id.buyAfBtn);
continueBtn=findViewById(R.id.continueBtn);
BuyerArea=findViewById(R.id.tv_address);
mAuth=FirebaseAuth.getInstance();
currentUserId=mAuth.getCurrentUser().getUid();
RootRef= FirebaseDatabase.getInstance().getReference();
fusedLocationProviderClient= LocationServices.getFusedLocationProviderClient(
BuyerAreaFinderActivity.this);
BuyerAreaFetchBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!isConnected(this)) { // checking internet connection
Toast.makeText(getApplicationContext(), " Please connect to internet", Toast.LENGTH_SHORT).show();
}else {
LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE
);
if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
|| locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
if (ActivityCompat.checkSelfPermission(BuyerAreaFinderActivity.this
, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(BuyerAreaFinderActivity.this
, Manifest.permission.ACCESS_COARSE_LOCATION) == PackageManager.PERMISSION_GRANTED){
getCurrentLocation();
}else {
//when permission is not granted
//Request permission
ActivityCompat.requestPermissions(BuyerAreaFinderActivity.this
, new String[]{Manifest.permission.ACCESS_FINE_LOCATION
, Manifest.permission.ACCESS_COARSE_LOCATION}
, 100);
}
}else {
Toast.makeText(getApplicationContext(), "Please switch on location , We will be sending enquiry to bet shops in your location ", Toast.LENGTH_LONG).show();
startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
}
}
}
});
BuyerArea.addTextChangedListener(new TextWatcher() { //Here I am displaying location, Once displayed correctly I will save latitude and longitude in my database
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) { Here I am displaying location, Once displayed correctly I will save latitude and longitude in my database
HashMap<String, Object>buyerLocationMap = new HashMap<>();
buyerLocationMap.put("buyerLatitude", BuyerLatitude);
buyerLocationMap.put("buyerLongitude", BuyerLongitude);
RootRef.child("Users").child(currentUserId).updateChildren(buyerLocationMap)
.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(@NonNull Task<Void> task) {
if(task.isSuccessful()){
continueBtn.setVisibility(View.VISIBLE);
continueBtn.setEnabled(true);
}else {
String ErrorMessage = task.getException().toString(); // get the error ocuured from net/firebase
Toast.makeText(BuyerAreaFinderActivity.this, "Error : " + ErrorMessage, Toast.LENGTH_SHORT).show();
}
}
});
}
});
continueBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
SendToNextActivity(); // next activity
finish();
}
});
}
@SuppressLint("MissingSuperCall")
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
//This methood check whether permmission is granted or not after requesting permission using the request code
//here suppress error by right clicking.
if(requestCode ==100 && grantResults.length>0&&(grantResults[0]+grantResults[1]
==PackageManager.PERMISSION_GRANTED)){
//when permission granted
// Call method
getCurrentLocation();
}else {
//when permissions are denied
if (!ActivityCompat.shouldShowRequestPermissionRationale(BuyerAreaFinderActivity.this, Manifest.permission.ACCESS_FINE_LOCATION )
&& !ActivityCompat.shouldShowRequestPermissionRationale(BuyerAreaFinderActivity.this, Manifest.permission.ACCESS_COARSE_LOCATION)) {
//This block here means PERMANENTLY DENIED PERMISSION
new AlertDialog.Builder(BuyerAreaFinderActivity.this)
.setMessage("You have permanently denied this permission, go to settings to enable this permission")
.setPositiveButton("Go to settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialogInterface, int i) {
gotoApplicationSettings();
}
})
.setNegativeButton("Cancel", null)
.setCancelable(false)
.show();
}else{
Toast.makeText(getApplicationContext(),"Location permission denied, Please click again to allow location permission.",Toast.LENGTH_LONG).show();
}
}
}
@SuppressLint("MissingPermission")
private void getCurrentLocation() {
fusedLocationProviderClient.flushLocations();// used by me for refreshing don't know correct or not
fusedLocationProviderClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
@Override
public void onComplete(@NonNull Task<Location> task) {
Location location=task.getResult();
//Check condition
if(location !=null){
BuyerLatitude=String.valueOf(location.getLatitude());
BuyerLongitude=String.valueOf(location.getLongitude());
/ ----------------- Geocoder is used to find the address if we dont want address to be displayed don't use this part -----------------
Geocoder geocoder = new Geocoder(BuyerAreaFinderActivity.this, Locale.getDefault());
try {
List<Address> addresses = geocoder.getFromLocation(location.getLatitude(),location.getLongitude(),1);
String address = addresses.get(0).getAddressLine(0);
BuyerArea.setText(address);
BuyerAreaFetchBtn.setVisibility(View.INVISIBLE);
} catch (IOException e) {
e.printStackTrace();
}
//------------------up to here for Geocoder-------------------------------------------------------------------------------
}
else {
//Location update.. when location result is null , Initialize location update part
// LocationRequest locationRequest = new LocationRequest() //deprecated so changed by me
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(10000)
.setFastestInterval(1000)
.setNumUpdates(1);
//Initialize location call back
LocationCallback locationCallback=new LocationCallback(){
@Override
public void onLocationResult(LocationResult locationResult) {
Location location1=locationResult.getLastLocation();
BuyerLatitude=String.valueOf(location1.getLatitude());
BuyerLongitude=String.valueOf(location1.getLongitude());
}
};
// Request location updates, Actually I dont want location updates but removal caused further delay in fetching location.
fusedLocationProviderClient.requestLocationUpdates(locationRequest,locationCallback, Looper.myLooper());
Toast.makeText(getApplicationContext(),"We are collecting your location details. Please wait for few seconds and press the button again",Toast.LENGTH_LONG).show();
fusedLocationProviderClient.removeLocationUpdates(locationCallback);
}
}
});
}
private void gotoApplicationSettings() { // if location is off, this will allow us to open the settings
Intent intent = new Intent();
intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package", this.getPackageName(), null);
intent.setData(uri);
startActivity(intent);
}
private boolean isConnected(View.OnClickListener onClickListener) {
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo wifiConn = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
NetworkInfo mobileConn = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
return (wifiConn != null && wifiConn.isConnected()) || (mobileConn != null && mobileConn.isConnected());
}
private void SendToNextActivity() {
Intent nextIntent = new Intent(Current.this, Next.class); // Take to next activity
startActivity(nextIntent);
finish();
}
}`