查找设备当前坐标时抛出空指针异常

Throwing Null Pointer Exception when finding the current co ordinates of the device

大家好,我正在尝试使用基于 GPS 和网络的设备来查找当前设备的坐标。我正在为 API 23 测试此代码。但是此代码返回 NullPointerException。代码如下:

public class AndroidLocationActivity extends Activity {

    Button btnGPSShowLocation;
    Button btnNWShowLocation;

    private static final int MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 2;

    protected LocationManager locationManager;
    Location location;

    private static final long MIN_DISTANCE_FOR_UPDATE = 10;
    private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_android_location);
        btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation);
        btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation);

    }

    public void mGPS(View view){
        Location gpsLocation = getLocation(LocationManager.GPS_PROVIDER);
        if (gpsLocation != null) {
            double latitude = gpsLocation.getLatitude();
            double longitude = gpsLocation.getLongitude();
            Toast.makeText(getApplicationContext(), "Mobile Location (GPS): \nLatitude: " + latitude + "\nLongitude: " + longitude, Toast.LENGTH_LONG).show();
        }
        else {
            showSettingsAlert("GPS");
        }
    }

    public void mNW(View view){
        Location nwLocation =getLocation(LocationManager.NETWORK_PROVIDER);
        if (nwLocation != null) {
            double latitude = nwLocation.getLatitude();
            double longitude = nwLocation.getLongitude();
            Toast.makeText(getApplicationContext(), "Mobile Location (NW): \nLatitude: " + latitude + "\nLongitude: " + longitude, Toast.LENGTH_LONG).show();
        }
        else {
            showSettingsAlert("NETWORK");
        }
    }

    public void showSettingsAlert(String provider) {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(
                AndroidLocationActivity.this);

        alertDialog.setTitle(provider + " SETTINGS");

        alertDialog.setMessage(provider + " is not enabled! Want to go to settings menu?");

        alertDialog.setPositiveButton("Settings",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                        AndroidLocationActivity.this.startActivity(intent);
                    }
                });

        alertDialog.setNegativeButton("Cancel",
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.cancel();
                    }
                });

        alertDialog.show();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    public Location getLocation(String provider) {
        if (locationManager.isProviderEnabled(provider)) {
            if(ContextCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!=PackageManager.PERMISSION_GRANTED){
                ActivityCompat.requestPermissions(this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION},MY_PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);

            }
            else {
                locationManager.requestLocationUpdates(provider, MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, (LocationListener) this);
                if (locationManager != null) {
                    location = locationManager.getLastKnownLocation(provider);
                    return location;
                }
            }
        }
        return null;
    }

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

                        Toast.makeText(this, "Permission Granted", Toast.LENGTH_SHORT).show();

                    }
                    else if(grantResults[0]==PackageManager.PERMISSION_DENIED) {
                        Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show();
                    }
                    else {

                        Toast.makeText(this, "Never Ask Again", Toast.LENGTH_SHORT).show();
                    }
                }
                return;
            }
        }
    }
}

代码返回以下错误:

FATAL EXCEPTION: main Process: com.cetpainfotech.locationtrackerapplication, PID: 29068 java.lang.IllegalStateException: Could not execute method for android:onClick at android.view.View$DeclaredOnClickListener.onClick(View.java:4461) at android.view.View.performClick(View.java:5207) at android.view.View$PerformClick.run(View.java:21177) at android.os.Handler.handleCallback(Handler.java:739) at android.os.Handler.dispatchMessage(Handler.java:95) at android.os.Looper.loop(Looper.java:148) at android.app.ActivityThread.main(ActivityThread.java:5441) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628) Caused by: java.lang.reflect.InvocationTargetException at java.lang.reflect.Method.invoke(Native Method) at android.view.View$DeclaredOnClickListener.onClick(View.java:4456) at android.view.View.performClick(View.java:5207)  at android.view.View$PerformClick.run(View.java:21177)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5441)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)  Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.location.LocationManager.isProviderEnabled(java.lang.String)' on a null object reference at com.cetpainfotech.locationtrackerapplication.AndroidLocationActivity.getLocation(AndroidLocationActivity.java:108) at com.cetpainfotech.locationtrackerapplication.AndroidLocationActivity.mGPS(AndroidLocationActivity.java:52) at java.lang.reflect.Method.invoke(Native Method)  at android.view.View$DeclaredOnClickListener.onClick(View.java:4456)  at android.view.View.performClick(View.java:5207)  at android.view.View$PerformClick.run(View.java:21177)  at android.os.Handler.handleCallback(Handler.java:739)  at android.os.Handler.dispatchMessage(Handler.java:95)  at android.os.Looper.loop(Looper.java:148)  at android.app.ActivityThread.main(ActivityThread.java:5441)  at java.lang.reflect.Method.invoke(Native Method)  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:738)  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:628)

我设定了条件,如果函数 getLocation() returns 为空,那么它将显示一个警告对话框。相反,当我单击按钮时它显示空指针异常。

我已经在 XML 文件中注册了 onClick 方法(mGPS 和 mNW)。

您没有初始化 locationManager,因此当您调用 locationManager.isProviderEnabled(provider) 时它会失败并显示 NullPointerException

这显示在您的堆栈跟踪中,就在这里

Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'boolean android.location.LocationManager.isProviderEnabled(java.lang.String)' on a null object reference

But my problem here is that despite being given an else condition in mGPS() and mNW() for handling null this code is throwing an exception

您的异常被抛出 因为 if 语句被计算但是 变量为空。

if (locationManager.isProviderEnabled(provider)) {

这是一个合适的null-check。

if (locationManager != null && locationManager.isProviderEnabled(provider)) {

} else {

}

你应该真正初始化你的变量,并在 onCreate

中加入这样一行
locationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);