2017-04-30 41 views
1

我已经经历的Android开发者文档,试图找出吨如何获得当前位置,特别是https://developer.android.com/training/location/retrieve-current.html获取最后已知的位置与谷歌播放服务

当我创建android的一个新项目,并选择映射模板在onCreate方法中有代码,然后还有一个onMapReady方法。

首先,只需确认下面的代码将地图放在屏幕上?如果是这样,那么只需要一个方法来允许操作地图?

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

在文档重:获取当前位置有信息回复:建筑以GoogleApiClient如

// Create an instance of GoogleAPIClient. 
if (mGoogleApiClient == null) { 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
     .addConnectionCallbacks(this) 
     .addOnConnectionFailedListener(this) 
     .addApi(LocationServices.API) 
     .build(); 
} 

了在该文档中指定的其他方法在onStart,和的onStop onConnected。这一切都有道理,但做一个非常基本的获取当前位置的应用程序,我仍然使用SupportMapMapFragment mapFragment =(SupportMapFragment)....从onCreate生成地图? onMapReady函数还有必要吗?哪里是创建GoogleApiClient实例的最佳位置?

在随后的文档页面也有关于得到一次与

LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder() 
    .addLocationRequest(mLocationRequest); 

连接,但我只是不知道在哪里应该定义的当前位置设置信息。

终于在Android Studio中的地图模板默认类定义为:

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback 

但在它被定义为谷歌文档:

公共类MainActivity扩展ActionBarActivity实现 ConnectionCallbacks,OnConnectionFailedListener

这个类延伸到哪个Activity上吗?

谢谢。

回答

2

我已经使用了预定义的Map Activity。您可以通过它获取最后一次已知的当前位置。

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, 
     GoogleApiClient.ConnectionCallbacks, 
     GoogleApiClient.OnConnectionFailedListener, 
     LocationListener { 

    private GoogleMap mMap; 
    GoogleApiClient mGoogleApiClient; 
    Location mLastLocation; 
    Marker mCurrLocationMarker; 
    LocationRequest mLocationRequest; 

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

     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      checkLocationPermission(); 
     } 
     // Obtain the SupportMapFragment and get notified when the map is ready to be used. 
     SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() 
       .findFragmentById(R.id.map); 
     mapFragment.getMapAsync(this); 
    } 


    /** 
    * Manipulates the map once available. 
    * This callback is triggered when the map is ready to be used. 
    * This is where we can add markers or lines, add listeners or move the camera. In this case, 
    * we just add a marker near Sydney, Australia. 
    * If Google Play services is not installed on the device, the user will be prompted to install 
    * it inside the SupportMapFragment. This method will only be triggered once the user has 
    * installed Google Play services and returned to the app. 
    */ 
    @Override 
    public void onMapReady(GoogleMap googleMap) { 
     mMap = googleMap; 
     mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); 

     //Initialize Google Play Services 
     if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { 
      if (ContextCompat.checkSelfPermission(this, 
        Manifest.permission.ACCESS_FINE_LOCATION) 
        == PackageManager.PERMISSION_GRANTED) { 
       buildGoogleApiClient(); 
       mMap.setMyLocationEnabled(true); 
      } 
     } 
     else { 
      buildGoogleApiClient(); 
      mMap.setMyLocationEnabled(true); 
     } 
    } 

    protected synchronized void buildGoogleApiClient() { 
     mGoogleApiClient = new GoogleApiClient.Builder(this) 
       .addConnectionCallbacks(this) 
       .addOnConnectionFailedListener(this) 
       .addApi(LocationServices.API) 
       .build(); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnected(Bundle bundle) { 

     mLocationRequest = new LocationRequest(); 
     mLocationRequest.setInterval(1000); 
     mLocationRequest.setFastestInterval(1000); 
     mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
     if (ContextCompat.checkSelfPermission(this, 
       Manifest.permission.ACCESS_FINE_LOCATION) 
       == PackageManager.PERMISSION_GRANTED) { 
      LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); 
     } 

    } 

    @Override 
    public void onConnectionSuspended(int i) { 

    } 

    @Override 
    public void onLocationChanged(Location location) { 

      mLastLocation = location; 
      if (mCurrLocationMarker != null) { 
       mCurrLocationMarker.remove(); 
      } 

      //Place current location marker 
      LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude()); 
      MarkerOptions markerOptions = new MarkerOptions(); 
      markerOptions.position(latLng); 
      markerOptions.title("Current Position"); 
      markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA)); 
      mCurrLocationMarker = mMap.addMarker(markerOptions); 

      //move map camera 
      mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng)); 
      mMap.animateCamera(CameraUpdateFactory.zoomTo(11)); 

      //stop location updates 
      if (mGoogleApiClient != null) { 
       LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); 
      } 

    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 

    } 

    public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; 
    public boolean checkLocationPermission(){ 
     if (ContextCompat.checkSelfPermission(this, 
       Manifest.permission.ACCESS_FINE_LOCATION) 
       != PackageManager.PERMISSION_GRANTED) { 

      // Asking user if explanation is needed 
      if (ActivityCompat.shouldShowRequestPermissionRationale(this, 
        Manifest.permission.ACCESS_FINE_LOCATION)) { 

       // Show an explanation to the user *asynchronously* -- don't block 
       // this thread waiting for the user's response! After the user 
       // sees the explanation, try again to request the permission. 

       //Prompt the user once explanation has been shown 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
         MY_PERMISSIONS_REQUEST_LOCATION); 


      } else { 
       // No explanation needed, we can request the permission. 
       ActivityCompat.requestPermissions(this, 
         new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, 
         MY_PERMISSIONS_REQUEST_LOCATION); 
      } 
      return false; 
     } else { 
      return true; 
     } 
    } 

    @Override 
    public void onRequestPermissionsResult(int requestCode, 
              String permissions[], int[] grantResults) { 
     switch (requestCode) { 
      case MY_PERMISSIONS_REQUEST_LOCATION: { 
       // If request is cancelled, the result arrays are empty. 
       if (grantResults.length > 0 
         && grantResults[0] == PackageManager.PERMISSION_GRANTED) { 

        // permission was granted. Do the 
        // contacts-related task you need to do. 
        if (ContextCompat.checkSelfPermission(this, 
          Manifest.permission.ACCESS_FINE_LOCATION) 
          == PackageManager.PERMISSION_GRANTED) { 

         if (mGoogleApiClient == null) { 
          buildGoogleApiClient(); 
         } 
         mMap.setMyLocationEnabled(true); 
        } 

       } else { 

        // Permission denied, Disable the functionality that depends on this permission. 
        Toast.makeText(this, "permission denied", Toast.LENGTH_LONG).show(); 
       } 
       return; 
      } 

      // other 'case' lines to check for other permissions this app might request. 
      // You can add here other case statements according to your requirement. 
     } 
    } 
} 

允许网络状态的权限和位置权限的Android清单

+0

嗨。感谢那。我的问题是onLocationChanged是否被调用,以及它被调用的地方。在Android文档有一个部分重新: – Mike

+0

嗨Avinash。感谢那。我的问题是onLocationChanged是否被调用,以及它被调用的地方。在android文档https://developer.android.com/guide/topics/location/strategies.html中,它通过使用LocationManager&LocationListener - 但这显然不是用在你的(或我的)代码中的。我也只是不确定这是做什么:LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);干杯。 – Mike

1

如果您的要求只是获得用户的当前位置,那么你可以不用MapActivity,你可以依靠LocationServices并要求getLastLocation。这里是充当你的目的下面的示例代码。

// Create an instance of GoogleAPIClient. 
if (mGoogleApiClient == null) { 
    mGoogleApiClient = new GoogleApiClient.Builder(this) 
     .addConnectionCallbacks(this) 
     .addOnConnectionFailedListener(this) 
     .addApi(LocationServices.API) 
     .build(); 
} 

既然你已经实现GoogleApiClient的听众,因此,你可以要求位置如下图所示代码:

 @Override 
     public void onConnected(Bundle bundle) { 
      Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); 
      startLocationUpdates(); 
     } 

     protected void startLocationUpdates() { 
      Log.d(TAG, "startLocationUpdates--> Start Location Updates"); 
      LocationServices.FusedLocationApi.requestLocationUpdates(
        mGoogleApiClient, mLocationRequest, this); 
     } 

     public void stopLocationUpdates() { 
      Log.d(TAG,"stopLocationUpdates--> Stop location updates"); 
      LocationServices.FusedLocationApi.removeLocationUpdates(
        mGoogleApiClient, this); 
      stopService(); 
     } 

    @Override 
    public void onConnectionSuspended(int i) { 
     Log.i(TAG, "Connection suspended"); 
     mGoogleApiClient.connect(); 
    } 

    @Override 
    public void onConnectionFailed(ConnectionResult connectionResult) { 
     Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + 
       connectionResult.getErrorCode()); 
    } 

    @Override 
    public void onLocationChanged(Location location) { 
     Log.d(TAG, "onLocationChanged--> Location is " + location.toString()); 
     mCurrentLocation = location; 
    } 

另外,如果你想跟踪位置的有规律的间隔之后,为您打造locationRequest这样从的OnCreate(您创建GoogleApiClient的对象)的对象:

protected void createLocationRequest() { 
    Log.d(TAG,"createLocationRequest--> Create Location Request"); 
    mLocationRequest = new LocationRequest(); 
    mLocationRequest.setInterval(10 * 1000); //UPDATE_INTERVAL_IN_MS 
    mLocationRequest.setFastestInterval(5 * 1000); //FASTEST_UPDATE_INTERVAL_IN_MS 
    mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); 
} 

这里是startLocation更新方法:

protected void startLocationUpdates() { 
    Log.d(TAG, "startLocationUpdates--> Start Location Updates"); 
    LocationServices.FusedLocationApi.requestLocationUpdates(
      mGoogleApiClient, mLocationRequest, this); 
} 

我希望这回答了你的问题,请记住这为答案,如果它解决您的问题。

+0

感谢您的。你能解释一下startLocationUpdates方法是如何渲染地图的吗?我假设LocationServices.FusedLocationApi.requestLocationUpdates( mGoogleApiClient,mLocationRequest,this);将获得更新的位置,但是如何将它放到地图上? – Mike

+0

嗨Avinash。感谢那。我的问题是onLocationChanged是否被调用,以及它被调用的地方。在android文档https://developer.android.com/guide/topics/location/strategies.html中,它通过使用LocationManager&LocationListener - 但这显然不是用在你的(或我的)代码中的。我也只是不确定这是做什么:LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this);干杯。 – Mike