抛出NullPointerException

时间:2017-03-29 00:09:49

标签: java android gps

这是我使用Android Location API进行的第n次尝试,我似乎无法让它正常工作。这个教程看起来最有希望,但我似乎只能得到这个代码来返回0.0,0.0的GPS坐标,这不是很有用......

似乎有一个线索,getLocation()返回一个java.lang.NullPointerException错误,但我不知道我应该在哪里开始寻找它。

这是错误:

 W/System.err: java.lang.NullPointerException
 W/System.err:     at android.content.ContextWrapper.checkPermission(ContextWrapper.java:557)

我尝试制作一个新的权限块,粘贴在底部,但它只是给出了同样的错误。

有谁能请我指出正确的方向?

代码分为两个类文件:MainActivity.java和GPSTracker.java。

GPSTracker.java

    package com.tutorial.android.location.api;

// http://www.androidhive.xyz/2016/07/android-gps-location-manager-tutorial.html
// with some modifications, especially for new permissions

import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Service;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.os.IBinder;
import android.provider.Settings;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.util.Log;

public class GPSTracker extends Service implements LocationListener {
    private String TAG = "¤¤";
    private final Context mContext;

    public GPSTracker(Context mContext) {
        this.mContext = mContext;
        this.getLocation();
    }

    boolean isGPSEnabled = false;
    boolean isNetworkEnabled = false;
    boolean canGetLocation = false;

    Location location;
    double latitude;
    double longitude;

    private static final long MIN_DISTANCE_CHANGE_FOR_UPDATE = 10; // 10 meters
    private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 30 sec

    protected LocationManager locationManager;

    public Location getLocation() {
        try {

            if(locationManager == null) {
                locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);
            }
            if(isGPSEnabled != true) {
                isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            }
            if(isNetworkEnabled != true) {
                isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
            }

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no provider enabled :p
                Log.e(TAG, "getLocation() no provider :(");
            } else {
                this.canGetLocation = true;
                // get network location
                if (isNetworkEnabled) {
                    // permission block:
                    if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    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.
                        // return TODO;
                    } else {
                        Log.e(TAG, "getLocation() permission DENIED");
                    }
                    locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATE, this);
                    if(locationManager != null) {
                        location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if(location != null) {
                            latitude = location.getLatitude();
                            longitude = location.getLongitude();
                        }
                    }
                }
                // get GPS location
                if(isGPSEnabled) {
                    if(location == null) {
                        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES, MIN_DISTANCE_CHANGE_FOR_UPDATE, this);
                        Log.d(TAG, "getLocation() GPS Enabled");
                        if(locationManager != null){
                            location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if(location != null) {
                                latitude = location.getLatitude();
                                longitude = location.getLongitude();
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            Log.e(TAG, "getLocation() ERROR...: " + e);
            e.printStackTrace();
        }
        return location;
    }

    public double getLatitude() {
        if(location != null) {
            latitude = location.getLatitude();
        }
        return latitude;
    }

    public double getLongitude() {
        if(location != null) {
            longitude = location.getLongitude();
        }
        return longitude;
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void onLocationChanged(Location location) {

    }

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

    }

    @Override
    public void onProviderEnabled(String provider) {
        // GPS is ON
        Log.d(TAG, "GPS is ON");
    }

    @Override
    public void onProviderDisabled(String provider) {
        // GPS is OFF
        Log.d(TAG, "GPS is OFF");
    }

    // GPS dialog
    public boolean canGetLocation() {
        return this.canGetLocation;
    }
    // don't really need this when testing
    public void showSettingsAlert() {
        AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

        alertDialog.setTitle(R.string.gps_settings_title);

        alertDialog.setMessage(R.string.gps_settings_msg);
        alertDialog.setPositiveButton(R.string.gps_settings_word, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                mContext.startActivities(new Intent[]{intent}); // hm...
            }
        });
        alertDialog.show();
    }

    public void stopUsingGPS() {
        if(locationManager != null) {
            locationManager.removeUpdates(GPSTracker.this);
        }
    }
}

在GPSTracker.java中重写但仍然没有工作权限阻止:

int permissionCheck = ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if(!(permissionCheck == PackageManager.PERMISSION_GRANTED)) {
    if(ActivityCompat.shouldShowRequestPermissionRationale((Activity) mContext, Manifest.permission.ACCESS_FINE_LOCATION)) {
        // explanation :p
        Log.i(TAG, "NOpe...");
    } else {
        // request permission
        Log.d(TAG, "Requestion new permission");
        ActivityCompat.requestPermissions((Activity) mContext, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1);
    }
}

MainActivity.java

package com.tutorial.android.location.api;

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;

public class MainActivity extends AppCompatActivity {
    String TAG = "¤";

    GPSTracker gps;

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

        gps = new GPSTracker(this);

        if(gps.canGetLocation()) {
            Log.i(TAG, "onCreate() GPS is ON");
            Log.i(TAG, "onCreate() " + gps.getLatitude()+ ", " + gps.getLongitude());
        } else {
            Log.d(TAG, "onCreate() GPS is OFF");
        }

    }
}

1 个答案:

答案 0 :(得分:9)

  

本教程似乎是最有希望的

这是非常糟糕的代码。

  

我似乎只能让这段代码返回0.0,0.0的GPS坐标,这不是很有用

这是因为如果getLastKnownLocation()恰好返回一个位置,它将只有一个位置。它不太可能这样做。

  

在GPSTracker.java中重写但仍然没有工作权限阻止:

这里有两个问题:

  1. 您无法从服务请求权限。

  2. 这不是真正的服务。此代码的作者选择创建一个扩展Service的类,而不实际正确地实现或使用该服务。这是导致NullPointerException的原因,因为这不是正确初始化的Context

  3.   

    有谁能请我指出正确的方向?

    抛弃所有这些。

    FWIW,my sample app使用LocationManager API。

    配方很简单:

    步骤1:在某些LocationManager上致电getSystemService(Context.LOCATION_SERVICE),获取Context。我碰巧在一个片段中这样做了:

      @Override
      public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setRetainInstance(true);
    
        template=getActivity().getString(R.string.url);
        mgr=(LocationManager)getActivity()
          .getSystemService(Context.LOCATION_SERVICE);
      }
    

    步骤2:调用requestUpdates(),传入实现LocationListener的内容。就我而言,恰好是片段本身:

      @Override
      @SuppressWarnings({"MissingPermission"})
      public void onStart() {
        super.onStart();
    
        mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3600000,
          1000, this);
      }
    

    第3步:在onLocationChanged()的{​​{1}}中,对您获得的LocationListener执行某些操作,在我的情况下,执行Location以获取天气预报:

    AsyncTask

    步骤4:完成后致电 @Override public void onLocationChanged(Location location) { new FetchForecastTask().execute(location); }

    removeUpdates()

    就是这样(除了运行时权限之外,我将其抽象为 @Override @SuppressWarnings({"MissingPermission"}) public void onStop() { mgr.removeUpdates(this); super.onStop(); } )。

    如果需要,请使用AbstractPermissionsActivity作为优化,但不要依赖它。