从 Android 的 LocationManager 请求 getLastKnownLocation 时的空指针
Posted
技术标签:
【中文标题】从 Android 的 LocationManager 请求 getLastKnownLocation 时的空指针【英文标题】:Null Pointer when requesting getLastKnownLocation from Android's LocationManager 【发布时间】:2016-03-22 16:10:33 【问题描述】:我在 android 21 及更高版本上遇到以下错误。
我遇到以下错误,并且该错误对制造商或型号没有限制。
java.lang.NullPointerException: Attempt to invoke virtual method 'java.lang.String[] android.content.pm.PackageManager.getPackagesForUid(int)' on a null object reference
at android.os.Parcel.readException(Parcel.java:1605)
at android.os.Parcel.readException(Parcel.java:1552)
at android.location.ILocationManager$Stub$Proxy.getLastLocation(ILocationManager.java:717)
at android.location.LocationManager.getLastKnownLocation(LocationManager.java:1200)
at [...]
触发错误的调用是以下任一:
mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
我事先检查 mLLocationManager 是否不为空,或者我是否拥有必要的权限。它适用于大多数情况,但我确实有一些崩溃事件。
有谁知道可以做些什么来避免它,或者是否有任何方法可以检测到它会发生所以我不请求位置?
感谢您的关注,
【问题讨论】:
只是为了理解,当您说某些情况时,您是否在同一设备上看到它有时会崩溃而有时会工作? 似乎是下面的***.com/questions/23906926/… 崩溃监控工具正在商店应用程序上检测到它。我开发的时候没有收到。不是那么频繁,但我收到了超过 100 次。 请检查我发布的链接。看来 getLastKnownLocation 并非万无一失。 GPS 的冷启动可能会为设备返回 null。正如另一个答案以及为可靠位置提供的链接中提到的,最好使用 LocationListener 他得到 null 作为方法的响应。我的代码在返回响应之前崩溃了。我认为它们是不同的问题。 Prasunnair,我认为这是一个不同的问题。当没有可用位置时,我的应用处理得很好。 【参考方案1】:使用这个类在android中获取位置
GpsTracker.java
public class GpsTracker extends Service implements LocationListener
private final Context mContext;
// flag for GPS status
boolean isGPSEnabled = false;
// flag for network status
boolean isNetworkEnabled = false;
// flag for GPS status
boolean canGetLocation = false;
Location location; // location
double latitude; // latitude
double longitude; // longitude
// The minimum distance to change Updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters
// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000; // 1 second
// Declaring a Location Manager
protected LocationManager locationManager;
public GpsTracker(Context context)
this.mContext = context;
getLocation();
public Location getLocation()
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
return null;
try
locationManager = (LocationManager) mContext
.getSystemService(LOCATION_SERVICE);
// getting GPS status
isGPSEnabled = locationManager
.isProviderEnabled(LocationManager.GPS_PROVIDER);
// getting network status
isNetworkEnabled = locationManager
.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
if (!isGPSEnabled && !isNetworkEnabled)
// no network provider is enabled
else
this.canGetLocation = true;
// First get location from Network Provider
if (isNetworkEnabled)
locationManager.requestLocationUpdates(
LocationManager.NETWORK_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("Network", "Network");
if (locationManager != null)
location = locationManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
if (location != null)
latitude = location.getLatitude();
longitude = location.getLongitude();
// if GPS Enabled get lat/long using GPS Services
if (isGPSEnabled)
if (location == null)
locationManager.requestLocationUpdates(
LocationManager.GPS_PROVIDER,
MIN_TIME_BW_UPDATES,
MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
Log.d("GPS Enabled", "GPS Enabled");
if (locationManager != null)
location = locationManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (location != null)
latitude = location.getLatitude();
longitude = location.getLongitude();
catch (Exception e)
e.printStackTrace();
return location;
/**
* Stop using GPS listener
* Calling this function will stop using GPS in your app
* */
public void stopUsingGPS()
if (locationManager != null)
if (Build.VERSION.SDK_INT >= 23 &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ContextCompat.checkSelfPermission(mContext, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED)
return ;
locationManager.removeUpdates(GpsTracker.this);
/**
* Function to get latitude
* */
public double getLatitude()
if(location != null)
latitude = location.getLatitude();
// return latitude
return latitude;
/**
* Function to get longitude
* */
public double getLongitude()
if(location != null)
longitude = location.getLongitude();
// return longitude
return longitude;
/**
* Function to check GPS/wifi enabled
* @return boolean
* */
public boolean canGetLocation()
return this.canGetLocation;
/**
* Function to show settings alert dialog
* On pressing Settings button will lauch Settings Options
* */
public void showSettingsAlert()
AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);
// Setting Dialog Title
alertDialog.setTitle("GPS settings");
// Setting Dialog Message
alertDialog.setMessage("GPS is not enabled. Do you want to go to settings menu?");
// On pressing Settings button
alertDialog.setPositiveButton("Settings", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog,int which)
Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
mContext.startActivity(intent);
((Activity)mContext).finish();
);
// on pressing cancel button
alertDialog.setNegativeButton("Cancel", new DialogInterface.OnClickListener()
public void onClick(DialogInterface dialog, int which)
dialog.cancel();
);
// Showing Alert Message
alertDialog.show();
@Override
public void onLocationChanged(Location location)
this.location = location;
@Override
public void onProviderDisabled(String provider)
@Override
public void onProviderEnabled(String provider)
@Override
public void onStatusChanged(String provider, int status, Bundle extras)
@Override
public IBinder onBind(Intent arg0)
return null;
【讨论】:
感谢您的回复,但我的代码已经完成了所有这些检查。在等待接收位置时,我什至会做更多的事情。问题是在完成所有这些检查之后,当我执行以下调用时:'location = locationManager .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);'我仍然有错误,不经常但我确实收到了,不管所有这些检查。答案是否应该只是做一个 try-catch 异常并忽略错误?我真的很想避免它。 您的班级,在用户关闭手机然后再打开手机之前可以正常工作。我在我的应用程序中使用了那个类,我遇到了这个问题。 @呃。拉克什·普拉贾帕特 @Coeus 请检查相应的权限。 完成!我在互联网上找到了该课程,但正如我所说,我遇到了这个问题。以上是关于从 Android 的 LocationManager 请求 getLastKnownLocation 时的空指针的主要内容,如果未能解决你的问题,请参考以下文章