![](/img/trans.png)
[英]NullPointerException in onCreate(), but not in onLocationChanged()
[英]onCreate, onMapReady and onLocationChanged
我正在開發一個使用(谷歌地圖)的應用程序,但是我無法理解這三種方法中的哪一種首先開始運行? 還是onLocationChanged等待onCreate完成執行然后開始運行?並且,如果它只是並行運行,如何強制它等待onCreate完成執行。 這可能是一個荒謬的問題,但是文檔並沒有幫助我。 謝謝。
onLocationChanged和onMapReady方法是偵聽器 。 它們幾乎表現為異步,並在完成后為您更新UI。 事件發生時也會觸發它們,即,如果更改設備的位置,則將觸發onLocationChanged方法並將提供要使用的新位置。 onMapReady方法也會發生這種情況,一旦地圖准備就緒(顧名思義,該方法便會被激活並隨GoogleMap對象一起提供)。 onCreate方法是創建活動時執行的常規方法。 如果您使用的是Google Maps API而不是設備的GPS實用程序來查找設備的位置,則需要有一個GoogleApiClient對象來確定設備的當前位置。 您可以從onConnected偵聽器中檢索當前位置,然后在地圖上放置一個指示該位置的標記。
這是運行Google地圖片段活動的示例代碼:
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v4.content.ContextCompat;
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.LocationListener;
import com.google.android.gms.location.LocationRequest;
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.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;
public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
private GoogleMap myMap;
private GoogleApiClient googleClient;
private Location lastLocation;
private LocationRequest locationRequest;
private Marker currentLocationMarker;
public static final int REQUEST_LOCATION_CODE = 99;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_maps);
// this code is to check whether the app gains the necessary permissions to get device location
if(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);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
switch(requestCode){
case REQUEST_LOCATION_CODE:
if(grantResults.length>0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
// Premission is granted
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
if(googleClient == null){
buildGoogleApiClient();
}
myMap.setMyLocationEnabled(true);
}
}
else{ // Permission is not granted
Toast.makeText(this, "Permission denied", Toast.LENGTH_LONG).show();
}
return;
}
}
/**
* 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) {
myMap = googleMap;
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
// 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.
buildGoogleApiClient();
myMap.setMyLocationEnabled(true);
//return;
}
}
protected synchronized void buildGoogleApiClient(){
googleClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
googleClient.connect();
}
@Override
public void onLocationChanged(Location location) {
lastLocation = location;
if(currentLocationMarker != null){
currentLocationMarker.remove();
}
LatLng latlng = new LatLng(location.getLatitude(), location.getLongitude());
MarkerOptions markerOptions = new MarkerOptions();
markerOptions.position(latlng);
markerOptions.title("your current location");
markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_AZURE));
currentLocationMarker = myMap.addMarker(markerOptions);
myMap.moveCamera(CameraUpdateFactory.newLatLng(latlng));
myMap.animateCamera(CameraUpdateFactory.zoomBy(10));
if(googleClient != null){
LocationServices.FusedLocationApi.removeLocationUpdates(googleClient,this);
}
}
@Override
public void onConnected(@Nullable Bundle bundle) {
locationRequest = new LocationRequest();
locationRequest.setInterval(1000);
locationRequest.setFastestInterval(1000);
locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
LocationServices.FusedLocationApi.requestLocationUpdates(googleClient, locationRequest, this);
}
}
public boolean checkLocationPermission(){
if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION_CODE);
return false;
}
return true;
}
@Override
public void onConnectionSuspended(int i) {
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
}
}
XML代碼只是一個片段:
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="so.tweet.client.MapsActivity" />
希望對您有所幫助:)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.