地理编码器,locationName == null

Geocoder, locationName == null

所以我正在开发一个社交活动应用程序,用户可以在其中发布活动并让人们在地图或列表上看到这些活动。我目前正在尝试对数据库中的位置地址进行地理编码,并将其转换为纬度和经度坐标。我已经查看了代码数十次并得到相同的错误。 "locationName == null" 我得出的唯一结论是,我实际上并没有从数据库中提取任何数据,而是将空值发送到地理编码器,这给了我这个错误。我正在使用 Android Studio 和 Google Firestore 作为我的数据库。希望一些新鲜的眼光能让我对这个问题有所了解。如果您需要查看其他相关代码片段,请告诉我。

MainActivity.java

public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleMap.OnMyLocationButtonClickListener, ActivityCompat.OnRequestPermissionsResultCallback {

private static final String TAG = MainActivity.class.getSimpleName();
private ImageButton notifyButton;
private ImageButton messagesButton;
private ImageButton exploreButton;
private ImageButton profileButton;

private double lat;
private double lng;
private String address;
private String city;
private String state;
private int zipcode;

private LatLng geoCoord;

/**
 * Request code for location permission request.
 *
 * @see #onRequestPermissionsResult(int, String[], int[])
 */
private static final int LOCATION_PERMISSION_REQUEST_CODE = 1;

/**
 * Flag indicating whether a requested permission has been denied after returning in
 * {@link #onRequestPermissionsResult(int, String[], int[])}.
 */
private boolean mPermissionDenied = false;

private GoogleMap mMap;
private MarkerOptions options = new MarkerOptions();

private FirebaseFirestore db = FirebaseFirestore.getInstance();

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.activity_main);

    notifyButton = (ImageButton) findViewById(R.id.notifyButton);
    notifyButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent main = new Intent(MainActivity.this, NotifyActivity.class);
            startActivity(main);
        }
    });

    messagesButton = (ImageButton) findViewById(R.id.messagesButton);
    messagesButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent main = new Intent(MainActivity.this, MessengerActivity.class);
            startActivity(main);
        }
    });

    exploreButton = (ImageButton) findViewById(R.id.exploreButton);
    exploreButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent main = new Intent(MainActivity.this, ExploreActivity.class);
            startActivity(main);
        }
    });

    profileButton = (ImageButton) findViewById(R.id.profileButton);
    profileButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            Intent main = new Intent(MainActivity.this, ProfileActivity.class);
            startActivity(main);
        }
    });



    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(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.setOnMyLocationButtonClickListener(this);
    enableMyLocation();


    try {
        // Customise the styling of the base map using a JSON object defined
        // in a raw resource file.
        boolean success = googleMap.setMapStyle(
                MapStyleOptions.loadRawResourceStyle(
                        this, R.raw.style_json));

        if (!success) {
            Log.e(TAG, "Style parsing failed.");
        }
    } catch (Resources.NotFoundException e) {
        Log.e(TAG, "Can't find style. Error: ", e);
    }
    // Position the map's camera near Sydney, Australia.

    googleMap.moveCamera(CameraUpdateFactory.newLatLng(new LatLng(-34, 151)));
    googleMap.addMarker(new MarkerOptions().position(geoLocate()));
}

private void enableMyLocation() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        // Permission to access the location is missing.
        PermissionUtils.requestPermission(this, LOCATION_PERMISSION_REQUEST_CODE,
                Manifest.permission.ACCESS_FINE_LOCATION, true);
    } else if (mMap != null) {
        // Access to the location has been granted to the app.
        mMap.setMyLocationEnabled(true);
    }
}

@Override
public boolean onMyLocationButtonClick() {
    Toast.makeText(this, "Current Location", Toast.LENGTH_SHORT).show();
    // Return false so that we don't consume the event and the default behavior still occurs
    // (the camera animates to the user's current position).
    return false;
}


@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
                                       @NonNull int[] grantResults) {
    if (requestCode != LOCATION_PERMISSION_REQUEST_CODE) {
        return;
    }

    if (PermissionUtils.isPermissionGranted(permissions, grantResults,
            Manifest.permission.ACCESS_FINE_LOCATION)) {
        // Enable the my location layer if the permission has been granted.
        enableMyLocation();
    } else {
        // Display the missing permission error dialog when the fragments resume.
        mPermissionDenied = true;
    }
}

@Override
protected void onResumeFragments() {
    super.onResumeFragments();
    if (mPermissionDenied) {
        // Permission was not granted, display error dialog.
        showMissingPermissionError();
        mPermissionDenied = false;
    }
}

/**
 * Displays a dialog with error message explaining that the location permission is missing.
 */
private void showMissingPermissionError() {
    PermissionUtils.PermissionDeniedDialog
            .newInstance(true).show(getSupportFragmentManager(), "dialog");
}

public LatLng geoLocate() {
    Geocoder gc = new Geocoder(this);
    List <Address> list;
    try{
        list = gc.getFromLocationName(getFullAddress(), 1);
    }
    catch (IOException e) {

        return null;
    }
    Address add = list.get(0);
    String locality = add.getLocality();
    Toast.makeText(this, locality, Toast.LENGTH_LONG).show();

    return new LatLng(add.getLatitude(), add.getLongitude());

}

public String getFullAddress() {
    DocumentReference docRef = db.collection("events").document("House Party");
    docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() {
        @Override
        public void onSuccess(DocumentSnapshot documentSnapshot) {
            Event event = documentSnapshot.toObject(Event.class);
            address = event.getAddress() + ", " + event.getCity() + ", " + event.getState() + " " + event.getZipcode();
        }
    });
    return address;
}

}

错误日志

FATAL EXCEPTION: main
                                                                     Process: com.example.android.gathr, PID: 8599
                                                                     java.lang.IllegalArgumentException: locationName == null
                                                                         at android.location.Geocoder.getFromLocationName(Geocoder.java:171)
                                                                         at com.example.android.gathr.MainActivity$override.geoLocate(MainActivity.java:232)
                                                                         at com.example.android.gathr.MainActivity$override.access$dispatch(MainActivity.java)
                                                                         at com.example.android.gathr.MainActivity.geoLocate(MainActivity.java:0)
                                                                         at com.example.android.gathr.MainActivity$override.onMapReady(MainActivity.java:169)
                                                                         at com.example.android.gathr.MainActivity$override.access$dispatch(MainActivity.java)
                                                                         at com.example.android.gathr.MainActivity.onMapReady(MainActivity.java:0)
                                                                         at com.google.android.gms.maps.zzak.zza(Unknown Source)
                                                                         at com.google.android.gms.maps.internal.zzaq.onTransact(Unknown Source)
                                                                         at android.os.Binder.transact(Binder.java:507)
                                                                         at gl.b(:com.google.android.gms.DynamiteModulesB@11518448:20)
                                                                         at com.google.android.gms.maps.internal.bf.a(:com.google.android.gms.DynamiteModulesB@11518448:5)
                                                                         at com.google.maps.api.android.lib6.impl.bc.run(:com.google.android.gms.DynamiteModulesB@11518448:5)
                                                                         at android.os.Handler.handleCallback(Handler.java:751)
                                                                         at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                         at android.os.Looper.loop(Looper.java:154)
                                                                         at android.app.ActivityThread.main(ActivityThread.java:6642)
                                                                         at java.lang.reflect.Method.invoke(Native Method)
                                                                         at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1468)
                                                                         at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1358)

编辑:

DocumentReference docRef = db.collection("cities").document("BJ");
 docRef.get().addOnSuccessListener(new OnSuccessListener<DocumentSnapshot>() 
 {
    @Override
    public void onSuccess(DocumentSnapshot documentSnapshot) {
    City city = documentSnapshot.toObject(City.class);
    }
   });

所以我将数据作为一个对象保存在我的数据库中,并根据上述代码从数据库中提取。我将地址元素存储在一个地址变量中,然后让地理定位方法将该代码转换为纬度和经度坐标。

getFullAddress() 中你调用我认为是异步操作 (docRef.get()) 来设置 address 但你 return address 立即 address 没有等待您添加以执行的侦听器。

要解决此问题,您可以将地理编码移至 onSuccess 回调中,这会产生很好的副作用,即仅在文档检索有效时才执行地理编码。