Code will only return 0.0, 0.0 GPS coordinate while throwing NullPointerException(代码只会返回 0.0, 0.0 GPS 坐标,同时抛出 NullPointerException)
问题描述
这是我对 Android Location API 的第 n 次尝试,但我似乎无法让它正常工作.本教程似乎是最有前途的,但我似乎只能让这段代码返回 0.0、0.0 的 GPS 坐标,这不是很有用......
getLocation() 返回 java.lang.NullPointerException 错误似乎有一个线索,但我什至不确定应该从哪里开始寻找它.
这是错误:
W/System.err: java.lang.NullPointerExceptionW/System.err:在 android.content.ContextWrapper.checkPermission(ContextWrapper.java:557)
我尝试制作一个新的权限块,粘贴在底部,但它给出了同样的错误.
任何人都可以在这里指出正确的方向吗?
代码分为两个类文件:MainActivity.java 和 GPSTracker.java.
GPSTracker.java
包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 扩展服务实现 LocationListener {私有字符串 TAG = "¤¤";私有最终上下文 mContext;公共 GPSTracker(上下文 mContext){this.mContext = mContext;this.getLocation();}布尔 isGPSEnabled = false;布尔 isNetworkEnabled = false;boolean canGetLocation = false;位置位置;双纬度;双经度;私有静态最终长 MIN_DISTANCE_CHANGE_FOR_UPDATE = 10;//10 米私有静态最终 long MIN_TIME_BW_UPDATES = 1000 * 60 * 1;//30 秒受保护的位置管理器位置管理器;公共位置 getLocation() {尝试 {如果(位置管理器 == 空){locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);}if(isGPSEnabled != true) {isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);}如果(isNetworkEnabled != true){isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);}if (!isGPSEnabled && !isNetworkEnabled) {//未启用提供程序:pLog.e(TAG, "getLocation() 没有提供者:(");} 别的 {this.canGetLocation = true;//获取网络位置如果(isNetworkEnabled){//权限块:if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {//TODO: 考虑调用//ActivityCompat#requestPermissions//这里请求丢失的权限,然后覆盖//public void onRequestPermissionsResult(int requestCode, String[] 权限,//int[] grantResults)//处理用户授予权限的情况.请参阅文档//对于 ActivityCompat#requestPermissions 了解更多详细信息.//返回待办事项;} 别的 {Log.e(TAG, "getLocation() 权限被拒绝");}locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATE,这个);如果(位置管理器!= null){位置 = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);如果(位置!= null){纬度 = location.getLatitude();经度 = location.getLongitude();}}}//获取GPS位置如果(是GPS启用){如果(位置 == 空){locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATE,这个);Log.d(TAG, "getLocation() GPS 已启用");如果(位置管理器!= null){位置 = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);如果(位置!= null){纬度 = location.getLatitude();经度 = location.getLongitude();}}}}}} 捕捉(异常 e){Log.e(TAG, "getLocation() 错误...:" + e);e.printStackTrace();}返回位置;}公共双getLatitude(){如果(位置!= null){纬度 = location.getLatitude();}返回纬度;}公共双getLongitude(){如果(位置!= null){经度 = location.getLongitude();}返回经度;}@Nullable@覆盖公共IBinder onBind(意图意图){返回空值;}@覆盖公共无效onLocationChanged(位置位置){}@覆盖public void onStatusChanged(String provider, int status, Bundle extras) {}@覆盖公共无效onProviderEnabled(字符串提供者){//GPS 开启Log.d(TAG, "GPS 开启");}@覆盖公共无效onProviderDisabled(字符串提供者){//GPS 关闭Log.d(TAG, "GPS 关闭");}//GPS 对话框公共布尔canGetLocation(){返回 this.canGetLocation;}//测试时不需要这个公共无效 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});//嗯...}});alertDialog.show();}公共无效停止使用GPS(){如果(位置管理器!= 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)) {//解释:pLog.i(TAG, "NOpe...");} 别的 {//请求权限Log.d(TAG, "请求新权限");ActivityCompat.requestPermissions((Activity) mContext, new String[] {Manifest.permission.ACCESS_FINE_LOCATION}, 1);}}
MainActivity.java
包com.tutorial.android.location.api;导入android.support.v7.app.AppCompatActivity;导入android.os.Bundle;导入android.util.Log;公共类 MainActivity 扩展 AppCompatActivity {字符串标签 = "¤";GPSTracker 全球定位系统;@覆盖protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);gps = new GPSTracker(this);如果(gps.canGetLocation()){Log.i(TAG, "onCreate() GPS 开启");Log.i(TAG, "onCreate() " + gps.getLatitude()+ ", " + gps.getLongitude());} 别的 {Log.d(TAG, "onCreate() GPS 已关闭");}}}
这个教程似乎是最有前途的
这真是糟糕的代码.
<块引用>我似乎只能让这段代码返回 0.0、0.0 的 GPS 坐标,这不是很有用
这是因为只有当
<块引用>getLastKnownLocation()
碰巧返回一个位置时,它才会有一个位置.不太可能这样做.在 GPSTracker.java 中重写但仍然不能工作的权限块:
这里有两个问题:
您不能向服务请求权限.
这不是真正的服务.此代码的作者选择创建一个扩展
Service
的类,而无需实际实现或正确使用该服务.这就是导致您的NullPointerException
的原因,因为这不是正确初始化的Context
.<块引用>
任何人都可以在这里指出正确的方向吗?
把这一切都扔掉.
FWIW,这里是 我的示例应用,用于使用LocationManager
API.
配方相当简单:
第 1 步:通过在某些 Context
上调用 getSystemService(Context.LOCATION_SERVICE)
来获取 LocationManager
.我碰巧在片段中这样做:
@Override公共无效 onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);设置保留实例(真);模板=getActivity().getString(R.string.url);经理=(位置管理器)getActivity().getSystemService(Context.LOCATION_SERVICE);}
第 2 步:调用 requestUpdates()
,传入实现 LocationListener
的内容.就我而言,这恰好是片段本身:
@Override@SuppressWarnings({"MissingPermission"})公共无效 onStart() {super.onStart();mgr.requestLocationUpdates(LocationManager.GPS_PROVIDER,3600000,1000,这个);}
第 3 步:在 LocationListener
的 onLocationChanged()
中,对获得的 Location
执行某些操作,在我的例子中是执行 AsyncTask
以获取天气预报:
@Override公共无效onLocationChanged(位置位置){新的 FetchForecastTask().execute(location);}
第 4 步:完成后调用 removeUpdates()
:
@Override@SuppressWarnings({"MissingPermission"})公共无效 onStop() {mgr.removeUpdates(this);超级.onStop();}
就是这样(除了运行时权限的东西,我将其抽象为 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 yourNullPointerException
, as this is not a properly initializedContext
.
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的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:代码只会返回 0.0, 0.0 GPS 坐标,同时抛出 NullPointerException
基础教程推荐
- 在螺旋中写一个字符串 2022-01-01
- Spring Boot Freemarker从2.2.0升级失败 2022-01-01
- 如何使用 Eclipse 检查调试符号状态? 2022-01-01
- 首次使用 Hadoop,MapReduce Job 不运行 Reduce Phase 2022-01-01
- 如何强制对超级方法进行多态调用? 2022-01-01
- 由于对所需库 rt.jar 的限制,对类的访问限制? 2022-01-01
- Java 中保存最后 N 个元素的大小受限队列 2022-01-01
- 如何在不安装整个 WTP 包的情况下将 Tomcat 8 添加到 Eclipse Kepler 2022-01-01
- 如何使用 Stream 在集合中拆分奇数和偶数以及两者的总和 2022-01-01
- 如何对 HashSet 进行排序? 2022-01-01