代码将只返回0.0,0.0 GPS坐标,同时抛出NullPointerException [英] Code will only return 0.0, 0.0 GPS coordinate while throwing 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中重写但仍然不工作的权限块:
这里有两个问题:
-
一项服务。
-
这不是真正的服务。此代码的作者选择创建一个扩展 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:
You cannot request permissions from a service.
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屋!