android - 无法正确获取经度和纬度

时间:2017-12-12 08:11:45

标签: android google-maps firebase firebase-realtime-database

我的应用程序中有两个帐户,家人和老人。我已将帐户设置为一对。我想将旧人的位置检索到家庭帐户,并在地图中显示。现在,我在获取纬度和经度方面存在问题。该位置无法正确更新到firebase。特别是当我走路时,应用程序无法检索位置。这是数据库结构。

Firebase的结构

enter image description here

老年人:

public class MainActivity extends Activity implements 
  android.location.LocationListener {

LocationManager locationManager;
String provider;
private FirebaseUser user;
private FirebaseAuth mAuth;
private DatabaseReference mDatabase;


private ImageButton helpButton;
private Button logout;

private double longitude;
private double latitude;

private String userId = "";



@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    helpButton = (ImageButton) findViewById(R.id.help);
    logout = (Button) findViewById(R.id.logout);

    mAuth = FirebaseAuth.getInstance();
    mDatabase = FirebaseDatabase.getInstance().getReference();

    user = mAuth.getCurrentUser();



    helpButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            startActivity(new Intent(MainActivity.this, HelpActivity.class));
        }
    });

    logout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FirebaseAuth.getInstance().signOut();
            startActivity(new Intent(MainActivity.this, HomeActivity.class));
        }
    });


    if (ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // Check Permissions Now
        ActivityCompat.requestPermissions(this,
                new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                0);
    }
    // Getting LocationManager object
    statusCheck();

    locationManager = (LocationManager) getSystemService(
            Context.LOCATION_SERVICE);

    // Creating an empty criteria object
    Criteria criteria = new Criteria();

    // Getting the name of the provider that meets the criteria
    provider = locationManager.getBestProvider(criteria, false);

    if (provider != null && !provider.equals("")) {
        if (!provider.contains("gps")) { // if gps is disabled
            final Intent poke = new Intent();
            poke.setClassName("com.android.settings",
                    "com.android.settings.widget.SettingsAppWidgetProvider");
            poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
            poke.setData(Uri.parse("3"));
            sendBroadcast(poke);
        }
        // Get the location from the given provider
        Location location = locationManager
                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

        locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 500, 0, this);

        if (location != null)
            onLocationChanged(location);
        else
            location = locationManager.getLastKnownLocation(provider);
        if (location != null)
            onLocationChanged(location);
        else

            Toast.makeText(getBaseContext(), "Location can't be retrieved",
                    Toast.LENGTH_SHORT).show();

    } else {
        Toast.makeText(getBaseContext(), "No Provider Found",
                Toast.LENGTH_SHORT).show();
    }
}

public void statusCheck() {
    final LocationManager manager = (LocationManager) getSystemService(
            Context.LOCATION_SERVICE);

    if (!manager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
        buildAlertMessageNoGps();

    }
}

private void buildAlertMessageNoGps() {
    final AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setMessage(
            "Your GPS seems to be disabled, do you want to enable it?")
            .setCancelable(false).setPositiveButton("Yes",
            new DialogInterface.OnClickListener() {
                public void onClick(final DialogInterface dialog,
                                    final int id) {
                    startActivity(new Intent(
                            android.provider.Settings.ACTION_LOCATION_SOURCE_SETTINGS));
                }
            })
            .setNegativeButton("No", new DialogInterface.OnClickListener() {
                public void onClick(final DialogInterface dialog,
                                    final int id) {
                    dialog.cancel();
                }
            });
    final AlertDialog alert = builder.create();
    alert.show();
}


@Override
public void onLocationChanged(Location location) {
    // Getting reference to TextView tv_longitude
    TextView tvLongitude = (TextView) findViewById(R.id.tv_longitude);

    // Getting reference to TextView tv_latitude
    TextView tvLatitude = (TextView) findViewById(R.id.tv_latitude);

    // Setting Current Longitude
    tvLongitude.setText("Longitude:" + location.getLongitude());

    // Setting Current Latitude
    tvLatitude.setText("Latitude:" + location.getLatitude());

    latitude = location.getLatitude();
    longitude = location.getLongitude();

    mAuth = FirebaseAuth.getInstance();
    user = mAuth.getCurrentUser();
    //save text in edittext into the firebase
    if (!String.valueOf(latitude).equals(""))
        mDatabase.child("users").child(user.getUid()).child("latitude").setValue(latitude);
    if (!String.valueOf(longitude).equals(""))
        mDatabase.child("users").child(user.getUid()).child("longitude").setValue(longitude);



}

@Override
public void onProviderDisabled(String provider) {
    // TODO Auto-generated method stub

    if (ActivityCompat.checkSelfPermission(this,
            Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // Check Permissions Now
        ActivityCompat.requestPermissions(this,
                new String[] { Manifest.permission.ACCESS_FINE_LOCATION },
                0);
    }
}

@Override
public void onProviderEnabled(String provider) {
    // TODO Auto-generated method stub
}

@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
    // TODO Auto-generated method stub
}
}


}

家庭方:

public class MainActivity_Family extends FragmentActivity implements
    OnMapReadyCallback,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener,
    GoogleMap.OnMarkerDragListener,
    GoogleMap.OnMapLongClickListener,
    View.OnClickListener {

private Button logout;
private ImageButton buttonCurrent;
private DatabaseReference mDatabase;
private FirebaseAuth mAuth;
private FirebaseUser user;
private double longitude;
private double latitude;
private String currentUserId;
private com.google.firebase.database.Query mQueryMF;
private TextView tt;



private GoogleMap mMap;


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

    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    mAuth = FirebaseAuth.getInstance();
    user = mAuth.getCurrentUser();
    currentUserId = user.getUid();
    mDatabase = FirebaseDatabase.getInstance().getReference();

    logout = (Button) findViewById(R.id.logout);
    buttonCurrent = (ImageButton) findViewById(R.id.buttonCurrent);
    tt = (TextView) findViewById(R.id.tt);


    buttonCurrent.setOnClickListener(this);

    logout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FirebaseAuth.getInstance().signOut();
            startActivity(new Intent(MainActivity_Family.this, HomeActivity.class));
        }
    });


}

private void getCurrentLocation() {
    mQueryMF = mDatabase.child("users").orderByChild("familyId").equalTo(currentUserId);

    mQueryMF.addValueEventListener(new ValueEventListener() {
        @Override
        public void onDataChange(DataSnapshot dataSnapshot) {
            for (DataSnapshot userSnapshot: dataSnapshot.getChildren()) {
                latitude = userSnapshot.child("latitude").getValue(Double.class);
                longitude = userSnapshot.child("longitude").getValue(Double.class);
            }
            //String to display current latitude and longitude
            String msg = latitude + ", " + longitude;
            tt.setText(msg);
            //Creating a LatLng Object to store Coordinates
            LatLng latLng = new LatLng(latitude, longitude);
            //Adding marker to map
            mMap.addMarker(new MarkerOptions()
                    .position(latLng) //setting position
                    .draggable(true) //Making the marker draggable
                    .title("Current Location")); //Adding a title

            //Moving the camera
            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));

            //Animating the camera
            mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
        }

        @Override
        public void onCancelled(DatabaseError databaseError) {
        }
    });

}


@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;
    LatLng latLng = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(latLng).draggable(true));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mMap.setOnMarkerDragListener(this);
    mMap.setOnMapLongClickListener(this);
}

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

@Override
public void onConnectionSuspended(int i) {

}

@Override
public void onConnectionFailed(ConnectionResult connectionResult) {

}

@Override
public void onMapLongClick(LatLng latLng) {
    //Clearing all the markers
    mMap.clear();

    //Adding a new marker to the current pressed position
    mMap.addMarker(new MarkerOptions()
            .position(latLng)
            .draggable(true));
}

@Override
public void onMarkerDragStart(Marker marker) {

}

@Override
public void onMarkerDrag(Marker marker) {

}

@Override
public void onMarkerDragEnd(Marker marker) {
    //Getting the coordinates
    latitude = marker.getPosition().latitude;
    longitude = marker.getPosition().longitude;
}

@Override
public void onClick(View v) {
    if (v == buttonCurrent) {
        getCurrentLocation();
    }
}
}

服务:

public static final String BROADCAST_ACTION = "Hello World";
private static final int TWO_MINUTES = 1000 * 60 * 2;
public LocationManager locationManager;
public MyLocationListener listener;
public Location previousBestLocation = null;
private FirebaseUser user;
private FirebaseAuth mAuth;
private DatabaseReference mDatabase;


private ImageButton helpButton;
private Button logout;

Intent intent;
int counter = 0;

@Override
public void onCreate()
{
    super.onCreate();
    intent = new Intent(BROADCAST_ACTION);


    mAuth = FirebaseAuth.getInstance();
    mDatabase = FirebaseDatabase.getInstance().getReference();

    user = mAuth.getCurrentUser();

    logout.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            FirebaseAuth.getInstance().signOut();
            startActivity(new Intent(MainActivity.this, HomeActivity.class));
        }
    });

}

@Override
public void onStart(Intent intent, int startId)
{
    locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    listener = new MyLocationListener();
    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 4000, 0, listener);
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 4000, 0, listener);
}

@Override
public IBinder onBind(Intent intent)
{
    return null;
}

protected boolean isBetterLocation(Location location, Location currentBestLocation) {
    if (currentBestLocation == null) {
        // A new location is always better than no location
        return true;
    }

    // Check whether the new location fix is newer or older
    long timeDelta = location.getTime() - currentBestLocation.getTime();
    boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
    boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
    boolean isNewer = timeDelta > 0;

    // If it's been more than two minutes since the current location, use the new location
    // because the user has likely moved
    if (isSignificantlyNewer) {
        return true;
        // If the new location is more than two minutes older, it must be worse
    } else if (isSignificantlyOlder) {
        return false;
    }

    // Check whether the new location fix is more or less accurate
    int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation.getAccuracy());
    boolean isLessAccurate = accuracyDelta > 0;
    boolean isMoreAccurate = accuracyDelta < 0;
    boolean isSignificantlyLessAccurate = accuracyDelta > 200;

    // Check if the old and new location are from the same provider
    boolean isFromSameProvider = isSameProvider(location.getProvider(),
            currentBestLocation.getProvider());

    // Determine location quality using a combination of timeliness and accuracy
    if (isMoreAccurate) {
        return true;
    } else if (isNewer && !isLessAccurate) {
        return true;
    } else if (isNewer && !isSignificantlyLessAccurate && isFromSameProvider) {
        return true;
    }
    return false;
}



/** Checks whether two providers are the same */
private boolean isSameProvider(String provider1, String provider2) {
    if (provider1 == null) {
        return provider2 == null;
    }
    return provider1.equals(provider2);
}



@Override
public void onDestroy() {
    // handler.removeCallbacks(sendUpdatesToUI);
    super.onDestroy();
    Log.v("STOP_SERVICE", "DONE");
    locationManager.removeUpdates(listener);
}

public static Thread performOnBackgroundThread(final Runnable runnable) {
    final Thread t = new Thread() {
        @Override
        public void run() {
            try {
                runnable.run();
            } finally {

            }
        }
    };
    t.start();
    return t;
}




public class MyLocationListener implements LocationListener
{

    public void onLocationChanged(final Location loc)
    {

        if(isBetterLocation(loc, previousBestLocation)) {
            loc.getLatitude();
            loc.getLongitude();

            mAuth = FirebaseAuth.getInstance();
            user = mAuth.getCurrentUser();
            //save text in edittext into the firebase
            if (!String.valueOf(loc.getLatitude()).equals(""))
                mDatabase.child("users").child(user.getUid()).child("latitude").setValue(loc.getLatitude());
            if (!String.valueOf(loc.getLongitude()).equals(""))
                mDatabase.child("users").child(user.getUid()).child("longitude").setValue(loc.getLongitude());




            sendBroadcast(intent);

        }
    }

    public void onProviderDisabled(String provider)
    {
        Toast.makeText( getApplicationContext(), "Gps Disabled", Toast.LENGTH_SHORT ).show();
    }


    public void onProviderEnabled(String provider)
    {
        Toast.makeText( getApplicationContext(), "Gps Enabled", Toast.LENGTH_SHORT).show();
    }


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

    }

}
}

2 个答案:

答案 0 :(得分:1)

使用LocationManager获取纬度和经度: -

这是完美的工作,所以试试这个以获得纬度和经度:)

try {
            LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

            // getting GPS status
            isGPSEnabled = locationManager
                    .isProviderEnabled(LocationManager.GPS_PROVIDER);

            // getting network status
            isNetworkEnabled = locationManager
                    .isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        location = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                            Toast.makeText(this, "+"+latitude, Toast.LENGTH_SHORT).show();
                        }
                    }
                }
                // if GPS Enabled get lat/long using GPS Services
                if (isGPSEnabled) {
                    if (location == null) {
                        locationManager.requestLocationUpdates(
                                LocationManager.GPS_PROVIDER,
                                MIN_TIME_BW_UPDATES,
                                MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (locationManager != null) {
                            location = locationManager
                                    .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();

                                Toast.makeText(this, "+"+latitude, Toast.LENGTH_SHORT).show();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

build.gradle中添加以下依赖项:

compile 'com.google.android.gms:play-services-location:11.0.2'

和import语句如下: -

import android.location.Location;
import android.location.LocationManager;

答案 1 :(得分:1)

Google Fused Api用于实现此目的。其较高级别API包含基础location sensors,如GPS

编译此

compile 'com.google.android.gms:play-services-location:11.0.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.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

现在的MainActivity:

 private long UPDATE_INTERVAL = 10 * 1000;  /* 10 secs */
private long FASTEST_INTERVAL = 2000; /* 2 sec */

public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    startLocationUpdates(); 
}

    // Trigger new location updates at interval
    protected void startLocationUpdates() {

        // Create the location request to start receiving updates
        mLocationRequest = new LocationRequest();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(UPDATE_INTERVAL);
        mLocationRequest.setFastestInterval(FASTEST_INTERVAL);

        // Create LocationSettingsRequest object using location request
        LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder();
        builder.addLocationRequest(mLocationRequest);
        LocationSettingsRequest locationSettingsRequest = builder.build();

        // Check whether location settings are satisfied
        // https://developers.google.com/android/reference/com/google/android/gms/location/SettingsClient
        SettingsClient settingsClient = LocationServices.getSettingsClient(this);
        settingsClient.checkLocationSettings(locationSettingsRequest);

        // new Google API SDK v11 uses getFusedLocationProviderClient(this)
        getFusedLocationProviderClient(this).requestLocationUpdates(mLocationRequest, new LocationCallback() {
          @Override
          public void onLocationResult(LocationResult locationResult) {
             // do work here
             onLocationChanged(locationResult.getLastLocation();
          }
        },
        Looper.myLooper()); }

然后使用onLocationChanged:

注册位置更新
public void onLocationChanged(Location location) {
    // New location has now been determined
    String msg = "Updated Location: " +
        Double.toString(location.getLatitude()) + "," +
        Double.toString(location.getLongitude());
    Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
    // You can now create a LatLng Object for use with maps
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
}

您可以从以下github链接中了解更多信息 https://github.com/codepath/android_guides/wiki/Retrieving-Location-with-LocationServices-API