Reputation: 11
I wanted to try to create a way to be oriented towards a GPS point that I previously acquired with LOCATION. I would like the navigator cursor to detect where I am moving with respect to the point of arrival and to calculate the distance between me and the point. I've already tried to read and see some tutorials but I couldn't solve anything. I have already acquired my destination GPS position using LocationManager.getLastKnownLocation, but then the cursone does not point to that point but to a random point and when I try to calculate the distance between me and the destination position with distanceTo () gives me values very high since I'm testing in the garden I walk a few meters away and he gives me much higher distances.
Another thing I don't understand is why the acquisition of LocationManager.getLastKnownLocation is not immediate and gives me values of 0 for more than 20 seconds and several clicks on the button to receive the data. Then using onLocationChanged I checked the changes to acquire new GPS points that I use to compare them with the destination GPS to calculate the cursor angle and distance.
Below is the code I've written so far but it doesn't work.
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.hardware.GeomagneticField;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import java.util.Objects;
import static android.Manifest.permission.ACCESS_FINE_LOCATION;
import static android.location.LocationManager.GPS_PROVIDER;
import static com.dooale.testcompass2.R.*;
import static com.dooale.testcompass2.R.layout.*;
public class MainActivity extends AppCompatActivity implements LocationListener {
// DICHIARE LE MIE VARIABILI E GLI OGGETTI DELLA MIA APP
public ImageView imageView;
public Double ULatitude, ULongitude, TargetLat,TargetLong;
Context context;
LocationManager locationManager;
public TextView tvHeading, tvDestPos;
public Button btDestPos;
public Boolean Trovato = false;
private float correntDegree = 0f;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(activity_main);
Log.d("MyApp", "Sono dentro il mio OnCreate");
requestPermission();
// INIZIALIZO GLI OGGETI
btDestPos = (Button) findViewById(id.BTposdest);
Log.d("MyApp", "OnCreate: Ho inizializzato btDestPos");
tvDestPos = (TextView) findViewById(id.TXposdest);
Log.d("MyApp", "OnCreate: Ho inizializzato tvDestPos");
tvHeading = (TextView) findViewById(id.TXHeading);
Log.d("MyApp", "OnCreate: Ho inizializzato tvHeading");
imageView = (ImageView) findViewById(id.compass);
Log.d("MyApp", "OnCreate: Ho inizializzato imageView");
// INIZIALIZZO IL MIO LOCATIONMANAGER
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
Criteria criteria = new Criteria();
final String bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();
Log.d("MyApp", "OnCreate: Dopo la richiesta di posizione bestProvider : " + bestProvider);
Log.d("MyApp", "OnCreate: Ho inizializzato locationManager");
Log.d("MyApp", "OnCreate: Gestisco il click sul bottone");
btDestPos.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!Objects.requireNonNull(locationManager).isProviderEnabled(GPS_PROVIDER)) {
Toast.makeText(getApplicationContext(), "NON FUNZIONA IL LOCATIONMANAGER", Toast.LENGTH_LONG).show();
Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:if(!Objects.requireNonNull(locationManager).isProviderEnabled(GPS_PROVIDER)) è negativo :");
} else if (locationManager.isProviderEnabled(GPS_PROVIDER)) {
Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:else if (locationManager.isProviderEnabled(GPS_PROVIDER) è positivo ");
Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:else if (locationManager.isProviderEnabled(GPS_PROVIDER) lancio il metodo getLocationProdoct();");
getLocationProdoct();
Log.d("MyApp", "OnCreate:btDestPos.setOnClickListener:else if (locationManager.isProviderEnabled(GPS_PROVIDER)esco dal metodo getLocationProdoct();");
if (Trovato) {
if (ULongitude == null || ULongitude == null) {
Toast.makeText(getApplicationContext(), "Riprova la posizione non è stata Trovata", Toast.LENGTH_LONG).show();
Log.v("MyApp", "OkRes_Activity:(ULongitude == 0 || ULongitude == 0): Recupero i campi Latitude e Longitude..." + " \n" +
"Latitude : " + ULatitude + "\n" +
"Longitude : " + ULongitude);
}
}else {
Log.v("MyApp", "OkRes_Activity:(Trovato == true):(ULongitude == 0 || ULongitude == 0):Il valore è stato trovato Recupero i campi Latitude e Longitude..." + " \n" +
"Latitude : " + ULatitude + "\n" +
"Longitude : " + ULongitude);
}
}
}
});
}
private void getLocationProdoct() {
Log.v("MyApp", "OkRes_Activity:getLocationProdoct: Sono al interno del metodo getLocationProdoct...");
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// 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.
return;
}
Log.v("MyApp", "OkRes_Activity:getLocationProdoct: Lancio il getLastKnownLocation ...");
Location location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
locationManager.requestLocationUpdates(GPS_PROVIDER, 1000, 1, locationListener);
Log.v("MyApp", "OkRes_Activity:getLocationProdoct: Verifico che il campo Location non sia nullo ...");
if (Trovato == true) {
if (ULatitude != null || ULongitude != null) {
//VERIFICO CHE IL I VALORI LATITUDINE E LONGITUDINE SIANO COMPILATI
Log.v("MyApp", "OkRes_Activity:getLocationProdoct:if (Trovato == true):ULatitude != null || ULongitude != null): " + "\n" +
"Il valore è stato trovato Recupero i campi Latitude e Longitude..." + " \n" +
"Latitude : " + ULatitude + "\n" +
"Longitude : " + ULongitude);
String Testo = String.valueOf(ULatitude);
Testo = Testo + " - " + String.valueOf(ULongitude);
tvDestPos.setText(Testo);
} else {
Log.v("MyApp", "OkRes_Activity:getLocationProdoct:Il valore è negativo Recupero i campi Latitude e Longitude..." + " \n" +
"Latitude : " + ULatitude + "\n" +
"Longitude : " + ULongitude);
}
} else{
Log.v("MyApp", "OkRes_Activity:getLocationProdoct: if (Trovato == true) :" + " \n" +
"NOn è ancora stato trovato il GPS Latitude e Longitude..." + " \n" +
"Latitude : " + ULatitude + "\n" +
"Longitude : " + ULongitude);
}
}
// METODO PER GESTIRE L'ACQUISIZIONE GPS LOCATIO
//TODO:METODO LOCATIONLISTENER
private final LocationListener locationListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged: Sono al interno del metodo LocationListener...");
//Double TargetLat = null,TargetLong= null;
ULatitude = location.getLatitude();
ULongitude= location.getLongitude();
Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged: Il valore è negativo Recupero i campi Latitude e Longitude..." + " \n" +
"Latitude : " + ULatitude + "\n" +
"Longitude : " + ULongitude);
if (ULatitude != null || ULongitude != null){
Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:ULatitude != null || ULongitude != null: " +
"Sono entrato nella condizione perchè ha trovato il punto GPS ");
if (Trovato == false) {
Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:ULatitude != null || ULongitude != null " + "\n" +
"Ma non fermo il LocationListener...");
TargetLat = ULatitude;
TargetLong = ULongitude;
String Testo = String.valueOf(ULatitude);
Testo = Testo + " - " + String.valueOf(ULongitude);
tvDestPos.setText(Testo);
//locationManager.removeUpdates(this);
Trovato = true;
Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:if (ULatitude != null || ULongitude != null):" +
"IF(Trovato == false)Chiamo la Funzione RotationCompass ");
//new RotationCompass(context,TargetLat,TargetLong,ULongitude,ULatitude,imageView,tvHeading);
Rotation();
} else {
Log.v("MyApp", "OkRes_Activity:LocationListener:onLocationChanged:ULatitude != null || ULongitude != null: " +
"Trovato = TRUE quindi attivo la frunzione TRAKER e aggiorno costantemente il puntatore GPS e chiamo RotationCompass ");
//new RotationCompass(context, TargetLat, TargetLong, ULongitude,ULatitude,imageView,tvHeading);
Rotation();
}
}
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
};
private void Rotation() {
Log.v("MyApp", "OkRes_Activity:Rotation(): Sono al interno del metodo Rotation()...");
Log.v("MyApp", "OkRes_Activity:Rotation(): Inizilizzo le 2 Location...");
Location UserLoc = new Location("service Provider");
Location DestinLoc =new Location("service Provider");
UserLoc.setLatitude(ULatitude);
UserLoc.setLongitude(ULongitude);
DestinLoc.setLatitude(TargetLat);
DestinLoc.setLongitude(TargetLong);
Log.v("MyApp", "OkRes_Activity:Rotation():Inizializzo bearTO...");
Float bearTO=UserLoc.bearingTo(DestinLoc);
Log.v("MyApp", "OkRes_Activity:Rotation(): bearTO è ..." + bearTO);
Log.v("MyApp", "OkRes_Activity:Rotation(): Calocolo la distanza con destinatioTo ...");
Float DestinTO= UserLoc.distanceTo(DestinLoc);
Log.v("MyApp", "OkRes_Activity:Rotation(): destinatioTo ..." + DestinTO);
Log.v("MyApp", "OkRes_Activity:Rotation():Inizializzo il GeomagneticFieald...");
GeomagneticField geoField= new GeomagneticField(Double.valueOf(UserLoc.getLatitude()).floatValue(),
Double.valueOf(UserLoc.getLongitude()).floatValue(),
Double.valueOf(UserLoc.getAltitude()).floatValue(),
System.currentTimeMillis());
Float head =+ geoField.getDeclination();
Log.v("MyApp", "OkRes_Activity:Rotation(): head è ..." + head);
if (bearTO<0){
bearTO=bearTO+360;
Log.v("MyApp", "OkRes_Activity:Rotation():if (bearTO<0): bearTO è ..." + bearTO);
}
float direction= bearTO - head;
Log.v("MyApp", "OkRes_Activity:Rotation(): direction è ..." + direction);
if (direction<0){
direction = direction +360;
Log.v("MyApp", "OkRes_Activity:Rotation():if (direction<0): direction è ..." + direction);
}
tvHeading.setText("Heading : " + Float.toString(correntDegree));
RotateAnimation rotateAnimation = new RotateAnimation(correntDegree,direction, Animation.RELATIVE_TO_SELF,0.5f,Animation.RELATIVE_TO_SELF,0.5f);
rotateAnimation.setDuration(210);
rotateAnimation.setRepeatCount(0);
rotateAnimation.setFillAfter(true);
imageView.startAnimation(rotateAnimation);
correntDegree = direction;
Log.v("MyApp", "OkRes_Activity:Rotation(): correntDegree è ..." + correntDegree);
}
public void requestPermission() {
Log.d("MyApp", "Sono dentro in requestPermission");
ActivityCompat.requestPermissions(this, new String[]{ACCESS_FINE_LOCATION}, 1);
}
@Override
public void onLocationChanged(Location location) {
Log.d("MyApp", "OnCreate:onLocationChanged: Sono dentro il onLocationChanged :");
ULatitude= location.getLatitude();
ULongitude= location.getLongitude();
Log.d("MyApp", "OnCreate:onLocationChanged:Ho acquisito i valori di ULatitude : " + ULatitude + "\n"+
"e il valore di ULongitude : " + ULongitude);
}
@Override
public void onStatusChanged(String s, int i, Bundle bundle) {
}
@Override
public void onProviderEnabled(String s) {
}
@Override
public void onProviderDisabled(String s) {
}
What I ask is to help me understand where I'm wrong and give me a guide line to follow !!! I was thinking of using the ACCELEROMETER sensors to solve the problem of pointing the compass but I haven't understood yet how to use it! I thank you in advance because I have been stuck for months Thank you
Upvotes: 1
Views: 183