Java 调用虚拟方法时出错';双android.location.location.getLatitude()';关于空对象引用

Java 调用虚拟方法时出错';双android.location.location.getLatitude()';关于空对象引用,java,android,google-maps,nullpointerexception,location,Java,Android,Google Maps,Nullpointerexception,Location,我所要做的就是让用户获得他喜欢的类型的位置列表。例如,如果输入是hospital,我的应用程序将使用搜索字符串“hospital”打开google地图。但正如文档中所建议的那样,使用地理编码,如geo:0,0?q=hospitaluri显示了坐标0纬度和0经度附近的所有医院。因此,当我尝试使用以下代码首先获取用户坐标时 Places Decoder.java package com.kkze.Mappy; import android.app.Activity; import android.

我所要做的就是让用户获得他喜欢的类型的位置列表。例如,如果输入是hospital,我的应用程序将使用搜索字符串“hospital”打开google地图。但正如文档中所建议的那样,使用地理编码,如
geo:0,0?q=hospital
uri显示了坐标0纬度和0经度附近的所有医院。因此,当我尝试使用以下代码首先获取用户坐标时

Places Decoder.java

package com.kkze.Mappy;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;

public class PlacesDecoder extends Activity {
Intent intentThatCalled;
public double latitude;
public double longitude;
public LocationManager locationManager;
public Criteria criteria;
public String bestProvider;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    intentThatCalled = getIntent();
    String voice2text = intentThatCalled.getStringExtra("v2txt");
    getLocation(voice2text);
}
public static boolean isLocationEnabled(Context context)
{
    int locationMode = 0;
    String locationProviders;
    if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
    {
        try
        {
            locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
        } catch (Settings.SettingNotFoundException e) {
            e.printStackTrace();
        }
        return locationMode != Settings.Secure.LOCATION_MODE_OFF;
    }
    else
    {
        locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
        return !TextUtils.isEmpty(locationProviders);
    }
}

public void getLocation(String voice2txt) {
    locationManager = (LocationManager)  this.getSystemService(Context.LOCATION_SERVICE);
    criteria = new Criteria();
    bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();
    Location location = locationManager.getLastKnownLocation(bestProvider);
    if (isLocationEnabled(PlacesDecoder.this)) {
            Log.e("TAG", "GPS is on");
            latitude = location.getLatitude();
            longitude = location.getLongitude();
            Toast.makeText(PlacesDecoder.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
            searchNearestPlace(voice2txt);

        }
    else
    {
        AlertDialog.Builder notifyLocationServices = new AlertDialog.Builder(PlacesDecoder.this);
        notifyLocationServices.setTitle("Switch on Location Services");
        notifyLocationServices.setMessage("Location Services must be turned on to complete this action. Also please take note that if on a very weak network connection,  such as 'E' Mobile Data or 'Very weak Wifi-Connections' it may take even 15 mins to load. If on a very weak network connection as stated above, location returned to application may be null or nothing and cause the application to crash.");
        notifyLocationServices.setPositiveButton("Ok, Open Settings", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                Intent openLocationSettings = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                PlacesDecoder.this.startActivity(openLocationSettings);
                finish();
            }
        });
        notifyLocationServices.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
            @Override
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        });
        notifyLocationServices.show();
    }
}

public void searchNearestPlace(String v2txt) {
    Log.e("TAG", "Started");
    v2txt = v2txt.toLowerCase();
    String[] placesS = {"accounting", "airport", "aquarium", "atm", "attraction", "bakery", "bakeries", "bank", "bar", "cafe", "campground", "casino", "cemetery", "cemeteries", "church", "courthouse", "dentist", "doctor", "electrician", "embassy", "embassies", "establishment", "finance", "florist", "food", "grocery", "groceries", "supermarket", "gym", "health", "hospital", "laundry", "laundries", "lawyer", "library", "libraries", "locksmith", "lodging", "mosque", "museum", "painter", "park", "parking", "pharmacy", "pharmacies", "physiotherapist", "plumber", "police", "restaurant", "school", "spa", "stadium", "storage", "store", "synagog", "synagogue", "university", "universities", "zoo"};
    String[] placesM = {"amusement park", "animal care", "animal care", "animal hospital", "art gallery", "art galleries", "beauty salon", "bicycle store", "book store", "bowling alley", "bus station", "car dealer", "car rental", "car repair", "car wash", "city hall", "clothing store", "convenience store", "department store", "electronics store", "electronic store", "fire station", "funeral home", "furniture store", "gas station", "general contractor", "hair care", "hardware store", "hindu temple", "home good store", "homes good store", "home goods store", "homes goods store", "insurance agency", "insurance agencies", "jewelry store", "liquor store", "local government office", "meal delivery", "meal deliveries", "meal takeaway", "movie rental", "movie theater", "moving company", "moving companies", "night club", "pet store", "place of worship", "places of worship", "post office", "real estate agency", "real estate agencies", "roofing contractor", "rv park", "shoe store", "shopping mall", "subway station", "taxi stand", "train station", "travel agency", "travel agencies", "veterinary care"};
    int index;
    for (int i = 0; i <= placesM.length - 1; i++) {
        Log.e("TAG", "forM");
        if (v2txt.contains(placesM[i])) {
            Log.e("TAG", "sensedM?!");
            index = i;
            Uri gmmIntentUri = Uri.parse("geo:" + latitude + "," + longitude + "?q=" + placesM[index]);
            Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
            mapIntent.setPackage("com.google.android.apps.maps");
            startActivity(mapIntent);
            finish();
        }
    }
    for (int i = 0; i <= placesS.length - 1; i++) {
        Log.e("TAG", "forS");
        if (v2txt.contains(placesS[i])) {
            Log.e("TAG", "sensedS?!");
            index = i;
            Uri gmmIntentUri = Uri.parse("geo:" + latitude + "," + longitude + "?q=" + placesS[index]);
            Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
            mapIntent.setPackage("com.google.android.apps.maps");
            startActivity(mapIntent);
            finish();
        }
    }
}
}

还要检查位置=null需要访问\u FINE\u LOCATION权限,这会弄乱我的应用程序,使其始终返回null。

getLocation
方法中更改此选项

if (isLocationEnabled(PlacesDecoder.this) && location != null) {
 ...
}

正如Jon Skeet在评论中提到的,
getLastKnownLocation()
方法可以并且将返回null。主要问题是,它不会提示操作系统请求新的位置锁,而只是检查是否存在来自其他应用程序位置请求的最后一个已知位置。如果最近没有其他应用程序发出位置请求,则返回给您的位置为空

确保您实际获得位置的唯一方法是请求一个位置,这是通过调用来完成的

传递到
onLocationChanged()
回调方法的位置将不会为null,因为回调仅在成功锁定位置时发生

请注意,在您的应用程序注册位置更新的整个过程中,这将导致额外的电池消耗,因此请务必尽快取消注册位置更新。在这里,您可以在第一个位置出现时立即取消注册

也可以考虑在该活动中等待进程锁定时显示进度对话框,以便给用户一些应用程序正在等待的反馈。

以下是代码的一般结构:

public class MainActivity extends Activity
        implements LocationListener {

    Intent intentThatCalled;
    public double latitude;
    public double longitude;
    public LocationManager locationManager;
    public Criteria criteria;
    public String bestProvider;

    String voice2text; //added

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

        intentThatCalled = getIntent();
        voice2text = intentThatCalled.getStringExtra("v2txt");
        getLocation();
    }

    public static boolean isLocationEnabled(Context context)
    {
       //...............
        return true;
    }

    protected void getLocation() {
        if (isLocationEnabled(MainActivity.this)) {
            locationManager = (LocationManager)  this.getSystemService(Context.LOCATION_SERVICE);
            criteria = new Criteria();
            bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();

            //You can still do this if you like, you might get lucky:
            Location location = locationManager.getLastKnownLocation(bestProvider);
            if (location != null) {
                Log.e("TAG", "GPS is on");
                latitude = location.getLatitude();
                longitude = location.getLongitude();
                Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
                searchNearestPlace(voice2text);
            }
            else{
                //This is what you need:
                locationManager.requestLocationUpdates(bestProvider, 1000, 0, this);
            }
        }
        else
        {
            //prompt user to enable location....
            //.................
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        locationManager.removeUpdates(this);

    }

    @Override
    public void onLocationChanged(Location location) {
        //Hey, a non null location! Sweet!

        //remove location callback:
        locationManager.removeUpdates(this);

        //open the map:
        latitude = location.getLatitude();
        longitude = location.getLongitude();
        Toast.makeText(MainActivity.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
        searchNearestPlace(voice2text);
    }

    @Override
    public void onStatusChanged(String provider, int status, Bundle extras) {

    }

    @Override
    public void onProviderEnabled(String provider) {

    }

    @Override
    public void onProviderDisabled(String provider) {

    }

    public void searchNearestPlace(String v2txt) {
        //.....
    }
}

出现空指针异常是因为您的应用程序不请求当前位置,而是使用上次找到的位置,只检查您是否已打开位置并运行使用当前位置的任何其他应用程序。之后,只需再次尝试运行您的项目。希望这能解决您的问题。

您编写了获取当前位置(latlng)的代码,此错误是因为您的真实android设备上的gps(位置)未打开。
我打开了它,它对我有效。希望有用

这里有另一种方法来做这件事,你的引信位置概念我已经用过了,并且成功了 mFusedLocationClient=LocationServices.getFusedLocationProviderClient(此)

是在什么地方

 @SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent() {
    System.out.println("on map click is here in permission///////////////");
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {

        // Activate the MapboxMap LocationComponent to show user location
        // Adding in LocationComponentOptions is also an optional parameter
        LocationComponent locationComponent = mapboxMap.getLocationComponent();
        locationComponent.activateLocationComponent(this);
        locationComponent.setLocationComponentEnabled(true);
        // Set the component's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);

        mFusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        originLocation=location;
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {
                            originLocation=location;
                            System.out.println(" permission granted location is in iff ++///////////////"+location);
                        }
                    }
                });

        //originLocation = locationComponent.getLastKnownLocation();
        System.out.println("origin location is that//////////"+originLocation);


    } else {


        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Toast.makeText(this, "granted", Toast.LENGTH_LONG).show();
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
    if (granted) {
        enableLocationComponent();
    } else {
        Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();``
        finish();
    }
}
@SuppressWarnings({“MissingPermission”})
私有void enableLocationComponent(){
System.out.println(“在地图上单击此处处于权限中]//”;
//检查权限是否已启用,如果未启用,则请求
if(许可证管理人areLocationPermissionsGranted(本)){
//激活MapboxMap LocationComponent以显示用户位置
//添加LocationComponentOptions也是一个可选参数
LocationComponent LocationComponent=mapboxMap.getLocationComponent();
locationComponent.activateLocationComponent(此);
locationComponent.setLocationComponentEnabled(true);
//设置零部件的相机模式
locationComponent.setCameraMode(CameraMode.TRACKING);
mFusedLocationClient.getLastLocation().addOnSuccessListener(这是新的OnSuccessListener()){
@凌驾
成功时的公共无效(位置){
原始位置=位置;
//已获取最后一个已知位置。在某些罕见情况下,此值可以为空。
如果(位置!=null){
原始位置=位置;
System.out.println(“授予权限的位置位于iff++//”位置);
}
}
});
//originLocation=locationComponent.getLastKnownLocation();
System.out.println(“原始位置是那个////“+originLocation”);
}否则{
permissionsManager=新的permissionsManager(此);
permissionsManager.requestLocationPermissions(此);
}
}
@凌驾
public void onRequestPermissionsResult(int-requestCode,@NonNull-String[]permissions,@NonNull-int[]grantResults){
permissionsManager.onRequestPermissionsResult(请求代码、权限、grantResults);
Toast.makeText(此“已授予”,Toast.LENGTH_LONG).show();
}
@凌驾
public void OneExplanationRequired(列出许可证解释){
Toast.makeText(this,R.string.user_位置_权限_解释,Toast.LENGTH_LONG).show();
}
@凌驾
public void onPermissionResult(已授予布尔值){
如果(授予){
enableLocationComponent();
}否则{
Toast.makeText(此,R.string.user_位置_权限未授予,Toast.LENGTH_LONG).show()``
完成();
}
}

正如Yash所说,你的应用程序不请求当前位置,而是使用上次找到的位置。一个简单的解决方法对我来说很有效。这个错误是,打开你的GPS,在你的手机上打开你的谷歌地图应用程序,或者在模拟器上查看你的当前位置,然后关闭它。现在,当您打开当前应用程序(您正在使用)或运行它时,不会出现此错误。为我工作。

我使用
.getLastLocation()
也遇到了同样的问题。然后我使用
mMap.setMyLocationEnabled(true)
,并使用
启用的地图上位置按钮获取GPS位置。setMyLocationEnabled(true)
。之后,下一次
.getLastLocation()
工作正常。我不知道确切的原因,但我认为地图上的位置按钮曾经保存了我的当前位置,下一次我使用
.ge
 @SuppressWarnings( {"MissingPermission"})
private void enableLocationComponent() {
    System.out.println("on map click is here in permission///////////////");
    // Check if permissions are enabled and if not request
    if (PermissionsManager.areLocationPermissionsGranted(this)) {

        // Activate the MapboxMap LocationComponent to show user location
        // Adding in LocationComponentOptions is also an optional parameter
        LocationComponent locationComponent = mapboxMap.getLocationComponent();
        locationComponent.activateLocationComponent(this);
        locationComponent.setLocationComponentEnabled(true);
        // Set the component's camera mode
        locationComponent.setCameraMode(CameraMode.TRACKING);

        mFusedLocationClient.getLastLocation().addOnSuccessListener(this, new OnSuccessListener<Location>() {
                    @Override
                    public void onSuccess(Location location) {
                        originLocation=location;
                        // Got last known location. In some rare situations this can be null.
                        if (location != null) {
                            originLocation=location;
                            System.out.println(" permission granted location is in iff ++///////////////"+location);
                        }
                    }
                });

        //originLocation = locationComponent.getLastKnownLocation();
        System.out.println("origin location is that//////////"+originLocation);


    } else {


        permissionsManager = new PermissionsManager(this);
        permissionsManager.requestLocationPermissions(this);
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
    permissionsManager.onRequestPermissionsResult(requestCode, permissions, grantResults);
    Toast.makeText(this, "granted", Toast.LENGTH_LONG).show();
}

@Override
public void onExplanationNeeded(List<String> permissionsToExplain) {
    Toast.makeText(this, R.string.user_location_permission_explanation, Toast.LENGTH_LONG).show();
}

@Override
public void onPermissionResult(boolean granted) {
    if (granted) {
        enableLocationComponent();
    } else {
        Toast.makeText(this, R.string.user_location_permission_not_granted, Toast.LENGTH_LONG).show();``
        finish();
    }
}