-1

我寫的代碼應該顯示用戶打開應用程序時設備在地圖上的位置。所以我在手機上試過它,當我打開它時,我可以看到我的位置,但是我走了約2公里,然後再次打開應用程序,但我以前的位置顯示在地圖上。在地圖上顯示當前位置

清單:

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.fgps" 
    android:versionCode="1" 
    android:versionName="1.0" > 

    <uses-sdk 
     android:minSdkVersion="11" 
     android:targetSdkVersion="22" /> 

    <uses-permission android:name="android.permission.INTERNET" /> 
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> 
    <uses-permission android:name="com.google.android.providers.gsf.permission.READ_GSERVICES" /> 
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
    <uses-permission android:name="android.permission.WAKE_LOCK" /> 

    <application 
     android:allowBackup="true" 
     android:icon="@drawable/ic_launcher" 
     android:label="@string/app_name" 
     android:theme="@style/AppTheme" > 
     <meta-data 
      android:name="com.google.android.gms.version" 
      android:value="@integer/google_play_services_version" /> 
     <meta-data 
      android:name="com.google.android.maps.v2.API_KEY" 
      android:value="my api key is here" /> 

     <activity 
      android:name=".MainActivity" 
      android:label="@string/app_name" >  
     </activity> 
     <activity android:name="AlarmReceiverActivity" android:label="@string/alarmReceiverActivity_string"></activity><activity 
      android:name=".MnaActivity" 
      android:label="@string/app_name" > 
      <intent-filter> 
       <action android:name="android.intent.action.MAIN" /> 

       <category android:name="android.intent.category.LAUNCHER" /> 
      </intent-filter> 
     </activity> 
     <service android:name="com.example.fgps.BackgroundLocationService" /> 
    </application> 

</manifest> 

的活動:

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); 
    }*/ 
} 

這項活動是不應該跟蹤我(獲得位置更新),它應該顯示在那裏我打開應用程序的位置。 我該如何解決這個問題?

+0

看看[這個](http://stackoverflow.com/questions/6181704/good-way-of-getting-the-users-location-in-android)。 –

回答

0

我也遇到了這個問題。首先,GPS需要一些時間來初始化,這可能會在首次發射時給你一個空值。其次,您必須繼續檢查GPS以確保有位置變化。幸運的是,在長時間搜索之後,我終於在堆棧溢出中找到了一個答案,它提供了獲取當前位置的最佳/可靠方法

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); 
相關問題