代码将只返回0.0,0.0 GPS坐标,同时抛出NullPointerException [英] Code will only return 0.0, 0.0 GPS coordinate while throwing NullPointerException

查看:193
本文介绍了代码将只返回0.0,0.0 GPS坐标,同时抛出NullPointerException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我对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。


$ b

GPSTracker.java

  package com.tutorial.android.location.api; 

// http://www.androidhive.xyz/2016/07/android-gps-location-manager-tutorial.html
//有一些修改,尤其是对于新的权限

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

公共类GPSTracker扩展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;
布尔值canGetLocation = false;

位置位置;
双纬度;
双经度;

private static final long MIN_DISTANCE_CHANGE_FOR_UPDATE = 10; // 10米
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 30秒

保护LocationManager locationManager;
$ b公共位置getLocation(){
尝试{

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); (!isGPSEnabled&&!isNetworkEnabled){
//没有启用提供者:p
Log.e(TAG,getLocation())


if没有提供者:();
} else {
this.canGetLocation = true;
//获取网络位置
if(isNetworkEnabled){
//权限块:
if(ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
// TODO:考虑调用
// ActivityCompat#requestPermissions
/ /在这里请求丢失的权限,然后覆盖
// public void onRequestPermissionsResult(int requestCode,String [] permissions,
// int [] grantResults)
//处理用户授予权限的情况。有关更多详细信息,请参阅文档
//获取ActivityCompat#requestPermissions。
//返回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();


$ b //获取GPS位置
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();




$ b catch(Exception e){
Log.e(TAG,getLocation()错误...:+ e);
e.printStackTrace();
}
返回地点;

$ b $ public double getLatitude(){
if(location!= null){
latitude = location.getLatitude();
}
返回纬度;


public double getLongitude(){
if(location!= null){
longitude = location.getLongitude();
}
返回经度;
}

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

@Override
public void onLocationChanged(位置位置){

}

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

}

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

@覆盖
public void onProviderDisabled(String provider){
// GPS关闭
Log.d(TAG,GPS关闭);
}

// GPS对话框
public boolean canGetLocation(){
return this.canGetLocation;
}
//在测试
时并不真的需要这样的内容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();

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


$ b $ / code $ / pre
$ b

重写但仍然不工作的权限块在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)){
//说明:p
Log.i(TAG,NOPE ...);
} else {
//请求权限
Log.d(TAG,Requested new permission);
ActivityCompat.requestPermissions((Activity)mContext,new String [] {Manifest.permission.ACCESS_FINE_LOCATION},1);
}
}

MainActivity.java

  package com.tutorial.android.location.api; 

导入android.support.v7.app.AppCompatActivity;
导入android.os.Bundle;
导入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 =新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);
}

}
}


解决方案


这个教程看起来像是最有前途的




我只能看到这段代码返回0.0,0.0的GPS坐标,这不是很有用。


这是因为如果 getLastKnownLocation()碰巧返回一个位置。这是不可能的。


在GPSTracker.java中重写但仍然不工作的权限块:


这里有两个问题:


  1. 一项服务。


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





任何人都可以在这里指出正确的方向吗?


抛出所有这些。



FWIW,这里是我的示例应用程序,用于使用 LocationManager API。



配方相当简单:步骤#1:获取 LocationManager 在某些 Context 上调用 getSystemService(Context.LOCATION_SERVICE)。我碰巧在一个片段中做到这一点:

  @Override 
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setRetainInstance(true);

template = getActivity()。getString(R.string.url);
mgr =(LocationManager)getActivity()
.getSystemService(Context.LOCATION_SERVICE);

$ / code>

第二步:调用 requestUpdates() code>,传入一些实现 LocationListener 的东西。在我的情况下,这恰好是片段本身:

  @Override 
@SuppressWarnings({MissingPermission}} )
public void onStart(){
super.onStart();

mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,3600000,
1000,this);

$ / code>

第三步:在 onLocationChanged()你的 LocationListener 的code>,对你得到的 Location 做些什么,在我的情况下是执行 AsyncTask 以获得天气预报:

  @Override 
public void onLocationChanged(Location location){
new FetchForecastTask()。execute(location);

$ / code>

第四步:调用 removeUpdates() code>完成后:

  @Override 
@SuppressWarnings({MissingPermission})
public void onStop(){
mgr.removeUpdates(this);

super.onStop();





$ b就是这样(除了运行时权限的东西,我把它抽象成一个 AbstractPermissionsActivity )。



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


This is my n-th try with the Android Location API, and I just can't seem to get it to work properly. This tutorial seems like the most promising, but I can only seem to get this code to return a GPS coordinate of 0.0, 0.0 which isn't very useful...

There seems to be a clue in that getLocation() returns a java.lang.NullPointerException error, but I'm not sure where I should even start looking for it.

Here's the error:

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

I tried making a new permissions block, pasted at the bottom, but it just gave the same error.

Can anyone please point me in the right direction here?

The code is split over two class-files: MainActivity.java and 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);
        }
    }
}

Rewritten but still not working permissions block in 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");
        }

    }
}

解决方案

This tutorial seems like the most promising

It is truly awful code.

I can only seem to get this code to return a GPS coordinate of 0.0, 0.0 which isn't very useful

That is because it will only ever have a location if getLastKnownLocation() happens to return one. It is unlikely to do so.

Rewritten but still not working permissions block in GPSTracker.java:

There are two problems here:

  1. You cannot request permissions from a service.

  2. This is not a real service. The author of this code elected to create a class that extends Service without actually implementing or using the service properly. This is what is causing your NullPointerException, as this is not a properly initialized Context.

Can anyone please point me in the right direction here?

Throw all of this out.

FWIW, here is my sample app for using the LocationManager API.

The recipe is fairly simple:

Step #1: Get a LocationManager by calling getSystemService(Context.LOCATION_SERVICE) on some Context. I happen to do that in a fragment:

  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setRetainInstance(true);

    template=getActivity().getString(R.string.url);
    mgr=(LocationManager)getActivity()
      .getSystemService(Context.LOCATION_SERVICE);
  }

Step #2: Call requestUpdates(), passing in something that implements LocationListener. In my case, that happens to be the fragment itself:

  @Override
  @SuppressWarnings({"MissingPermission"})
  public void onStart() {
    super.onStart();

    mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER, 3600000,
      1000, this);
  }

Step #3: In onLocationChanged() of your LocationListener, do something with the Location that you get, which in my case is to execute an AsyncTask to get a weather forecast:

  @Override
  public void onLocationChanged(Location location) {
    new FetchForecastTask().execute(location);
  }

Step #4: Call removeUpdates() when you are done:

  @Override
  @SuppressWarnings({"MissingPermission"})
  public void onStop() {
    mgr.removeUpdates(this);

    super.onStop();
  }

And that's it (other than runtime permission stuff, which I abstract out into an AbstractPermissionsActivity).

If you want, use getLastKnownLocation() as an optimization, but do not rely upon it.

这篇关于代码将只返回0.0,0.0 GPS坐标,同时抛出NullPointerException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆