我写的代码应该是当用户打开app时在地图上显示设备的位置。所以我在手机上试了一下,当我打开它时我可以看到我的位置,但是我走了大约2距离该位置数公里,然后再次打开应用程序,但我之前的位置显示在地图上。
清单:
package com.example.fgps;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.text.InputType;
import android.util.Log;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.MarkerOptions;
public class MainActivity extends FragmentActivity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener
//,LocationListener
{
public static final String TAG = MainActivity.class.getSimpleName();
/*
* Define a request code to send to Google Play services
* This code is returned in Activity.onActivityResult
*/
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private GoogleMap mMap; // Might be null if Google Play services APK is not available.
private GoogleApiClient mGoogleApiClient;
//private LocationRequest mLocationRequest;
private String T_Text="";
private double D_Text;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
setUpMapIfNeeded();
buildGoogleApiClient();
if(mGoogleApiClient!= null){
mGoogleApiClient.connect();
}
Toast.makeText(this,"Long press at the location you want to choose as your destination",Toast.LENGTH_LONG).show();
// Create the LocationRequest object
/*mLocationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(6 * 1000) // 4 seconds, in milliseconds
.setFastestInterval(1 * 500); // 1/2 second, in milliseconds
*/
mMap.setOnMapLongClickListener(new OnMapLongClickListener() {
Intent i;@Override
public void onMapLongClick(LatLng point) {
i=new Intent(MainActivity.this, MnaActivity.class);
i.putExtra("lat", point.latitude);
i.putExtra("lng", point.longitude);
AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
builder.setTitle("Setup");
TextView text123 = new TextView(MainActivity.this);
text123.setText("Enter title for alarm");
final EditText input = new EditText(MainActivity.this);
input.setInputType(InputType.TYPE_CLASS_TEXT);
final EditText input2 = new EditText(MainActivity.this);
input2.setInputType(InputType.TYPE_CLASS_TEXT);
LinearLayout lay = new LinearLayout(MainActivity.this);
lay.setOrientation(LinearLayout.VERTICAL);
lay.addView(text123);
lay.addView(input);
TextView text12 = new TextView(MainActivity.this);
text12.setText("Enter raduis to start alarm\n(in Kms and above 200m)");
lay.addView(text12);
lay.addView(input2);
builder.setView(lay);
builder.setPositiveButton("OK", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
boolean flag=true;
T_Text = input.getText().toString();
try {
D_Text = Double.parseDouble(input2.getText().toString());
} catch (NumberFormatException e) {
AlertDialog.Builder builder2 = new AlertDialog.Builder(MainActivity.this);
builder2.setTitle("Error");
builder2.setMessage("Try again but check that title won't be empty\ndistance is above 200m=0.2km and written in NUMBERS");
builder2.show();
flag=false;
e.printStackTrace();
}
if((T_Text.length()>0) && D_Text>=0.02)
{
i.putExtra("distance", D_Text);
i.putExtra("title", T_Text);
setResult(RESULT_OK, i);
finish();
}else {
if(flag){
AlertDialog.Builder builder2 = new AlertDialog.Builder(MainActivity.this);
builder2.setTitle("Error");
builder2.setMessage("Try again but check that title won't be empty and distance is above 200m=0.2km");
builder2.show();
}
}
}
});
builder.show();
}
});
}
@Override
protected void onStart() {
super.onStart();
setUpMapIfNeeded();
mGoogleApiClient.connect();
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
/*@Override
protected void onResume() {
super.onResume();
setUpMapIfNeeded();
mGoogleApiClient.connect();
}
@Override
protected void onPause() {
super.onPause();
if (mGoogleApiClient.isConnected()) {
LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
mGoogleApiClient.disconnect();
}
}
*/
protected synchronized void buildGoogleApiClient() {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
/**
* Sets up the map if it is possible to do so (i.e., the Google Play services APK is correctly
* installed) and the map has not already been instantiated.. This will ensure that we only ever
* call {@link #setUpMap()} once when {@link #mMap} is not null.
* <p/>
* If it isn't installed {@link SupportMapFragment} (and
* {@link com.google.android.gms.maps.MapView MapView}) will show a prompt for the user to
* install/update the Google Play services APK on their device.
* <p/>
* A user can return to this FragmentActivity after following the prompt and correctly
* installing/updating/enabling the Google Play services. Since the FragmentActivity may not
* have been completely destroyed during this process (it is likely that it would only be
* stopped or paused), {@link #onCreate(Bundle)} may not be called again so we should call this
* method in {@link #onResume()} to guarantee that it will be called.
*/
private void setUpMapIfNeeded() {
// Do a null check to confirm that we have not already instantiated the map.
if (mMap == null) {
// Try to obtain the map from the SupportMapFragment.
mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map))
.getMap();
// Check if we were successful in obtaining the map.
/*if (mMap != null) {
setUpMap();
}*/
}
}
/**
* This is where we can add markers or lines, add listeners or move the camera. In this case, we
* just add a marker near Africa.
* <p/>
* This should only be called once and when we are sure that {@link #mMap} is not null.
*/
/*private Marker oldMarker;
private void setUpMap() {
oldMarker=mMap.addMarker(new MarkerOptions().position(new LatLng(0, 0)).title("activate gps!!"));
}*/
/*private void handleNewLocation(Location location) {
Log.d(TAG, location.toString());
double currentLatitude = location.getLatitude();
double currentLongitude = location.getLongitude();
oldMarker.remove();
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
oldMarker=mMap.addMarker(new MarkerOptions().position(new LatLng(currentLatitude, currentLongitude)).title("Current Location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
}
*/
Location Mloc;
@Override
public void onConnected(Bundle bundle) {
double currentLatitude=0;
double currentLongitude=0;
Mloc = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
//Log.d(TAG, Mloc.toString());
if(Mloc!= null)
{
currentLatitude = Mloc.getLatitude();
currentLongitude = Mloc.getLongitude();
//oldMarker.remove();
}
LatLng latLng = new LatLng(currentLatitude, currentLongitude);
mMap.addMarker(new MarkerOptions().position(new LatLng(currentLatitude, currentLongitude)).title("Current Location"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
mMap.animateCamera(CameraUpdateFactory.zoomTo(15));
/*if (location == null) {
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);*/
/*}
else {
handleNewLocation(location);
}*/
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
/*
* Google Play services can resolve some errors it detects.
* If the error has a resolution, try sending an Intent to
* start a Google Play services activity that can resolve
* error.
*/
if (connectionResult.hasResolution()) {
try {
// Start an Activity that tries to resolve the error
connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
/*
* Thrown if Google Play services canceled the original
* PendingIntent
*/
} catch (IntentSender.SendIntentException e) {
// Log the error
e.printStackTrace();
}
} else {
/*
* If no resolution is available, display a dialog to the
* user with the error.
*/
Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
}
}
/*@Override
public void onLocationChanged(Location location) {
handleNewLocation(location);
}*/
}
活动:
{{1}}
此活动不应该跟踪我(获取位置更新),它应该显示我打开应用程序的位置。 我怎么解决这个问题?
答案 0 :(得分:0)
我也遇到了这个问题。首先,GPS需要一些时间来初始化,这可能会在第一次启动时给你一个空值。其次,你必须继续检查GPS以确保位置发生变化。幸运的是,经过长时间的搜索,我终于在Stack Overflow中找到了一个答案,它提供了获得当前位置的最佳/可靠方法
用于获取位置更改的MyLocation类,
public class MyLocation {
Timer timer1;
LocationManager lm;
LocationResult locationResult;
public boolean gps_enabled=false;
boolean network_enabled=false;
public boolean getLocation(Context context, LocationResult result)
{
//I use LocationResult callback class to pass location value from MyLocation to user code.
locationResult=result;
if(lm==null)
lm = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
//exceptions will be thrown if provider is not permitted.
try{gps_enabled=lm.isProviderEnabled(LocationManager.GPS_PROVIDER);}catch(Exception ex){}
try{network_enabled=lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}catch(Exception ex){}
//don't start listeners if no provider is enabled
if(!gps_enabled && !network_enabled)
return false;
if(gps_enabled)
lm.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGps);
if(network_enabled)
lm.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 0, 0, locationListenerNetwork);
timer1=new Timer();
timer1.schedule(new GetLastLocation(), 20000);
return true;
}
LocationListener locationListenerGps = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerNetwork);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
LocationListener locationListenerNetwork = new LocationListener() {
public void onLocationChanged(Location location) {
timer1.cancel();
locationResult.gotLocation(location);
lm.removeUpdates(this);
lm.removeUpdates(locationListenerGps);
}
public void onProviderDisabled(String provider) {}
public void onProviderEnabled(String provider) {}
public void onStatusChanged(String provider, int status, Bundle extras) {}
};
class GetLastLocation extends TimerTask {
@Override
public void run() {
lm.removeUpdates(locationListenerGps);
lm.removeUpdates(locationListenerNetwork);
Location net_loc=null, gps_loc=null;
if(gps_enabled)
gps_loc=lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if(network_enabled)
net_loc=lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
//if there are both values use the latest one
if(gps_loc!=null && net_loc!=null){
if(gps_loc.getTime()>net_loc.getTime())
locationResult.gotLocation(gps_loc);
else
locationResult.gotLocation(net_loc);
return;
}
if(gps_loc!=null){
locationResult.gotLocation(gps_loc);
return;
}
if(net_loc!=null){
locationResult.gotLocation(net_loc);
return;
}
locationResult.gotLocation(null);
}
}
public static abstract class LocationResult{
public abstract void gotLocation(Location location);
}
}
要接收位置更新,请覆盖gotLocation()
方法,该方法会在位置发生变化时为您提供数据。
MyLocation.LocationResult locationResult = new MyLocation.LocationResult() {
@Override
public void gotLocation(Location location) {
//Got the location!
}
};
MyLocation myLocation = new MyLocation();
myLocation.getLocation(getActivity(), locationResult);