【发布时间】:2015-11-24 05:40:37
【问题描述】:
我要做的就是让用户获得他喜欢的类型的位置列表。例如,如果输入是医院,我的应用程序将使用搜索字符串“医院”打开谷歌地图。但正如文档中所建议的那样,使用geo:0,0?q=hospital uri 之类的地理编码显示坐标 0 纬度和 0 经度附近的所有医院。因此,当我尝试使用以下代码首先获取用户坐标时。
地点解码器.java
package com.kkze.Mappy;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.provider.Settings;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
public class PlacesDecoder extends Activity {
Intent intentThatCalled;
public double latitude;
public double longitude;
public LocationManager locationManager;
public Criteria criteria;
public String bestProvider;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
intentThatCalled = getIntent();
String voice2text = intentThatCalled.getStringExtra("v2txt");
getLocation(voice2text);
}
public static boolean isLocationEnabled(Context context)
{
int locationMode = 0;
String locationProviders;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT)
{
try
{
locationMode = Settings.Secure.getInt(context.getContentResolver(), Settings.Secure.LOCATION_MODE);
} catch (Settings.SettingNotFoundException e) {
e.printStackTrace();
}
return locationMode != Settings.Secure.LOCATION_MODE_OFF;
}
else
{
locationProviders = Settings.Secure.getString(context.getContentResolver(), Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
return !TextUtils.isEmpty(locationProviders);
}
}
public void getLocation(String voice2txt) {
locationManager = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE);
criteria = new Criteria();
bestProvider = String.valueOf(locationManager.getBestProvider(criteria, true)).toString();
Location location = locationManager.getLastKnownLocation(bestProvider);
if (isLocationEnabled(PlacesDecoder.this)) {
Log.e("TAG", "GPS is on");
latitude = location.getLatitude();
longitude = location.getLongitude();
Toast.makeText(PlacesDecoder.this, "latitude:" + latitude + " longitude:" + longitude, Toast.LENGTH_SHORT).show();
searchNearestPlace(voice2txt);
}
else
{
AlertDialog.Builder notifyLocationServices = new AlertDialog.Builder(PlacesDecoder.this);
notifyLocationServices.setTitle("Switch on Location Services");
notifyLocationServices.setMessage("Location Services must be turned on to complete this action. Also please take note that if on a very weak network connection, such as 'E' Mobile Data or 'Very weak Wifi-Connections' it may take even 15 mins to load. If on a very weak network connection as stated above, location returned to application may be null or nothing and cause the application to crash.");
notifyLocationServices.setPositiveButton("Ok, Open Settings", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
Intent openLocationSettings = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
PlacesDecoder.this.startActivity(openLocationSettings);
finish();
}
});
notifyLocationServices.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
notifyLocationServices.show();
}
}
public void searchNearestPlace(String v2txt) {
Log.e("TAG", "Started");
v2txt = v2txt.toLowerCase();
String[] placesS = {"accounting", "airport", "aquarium", "atm", "attraction", "bakery", "bakeries", "bank", "bar", "cafe", "campground", "casino", "cemetery", "cemeteries", "church", "courthouse", "dentist", "doctor", "electrician", "embassy", "embassies", "establishment", "finance", "florist", "food", "grocery", "groceries", "supermarket", "gym", "health", "hospital", "laundry", "laundries", "lawyer", "library", "libraries", "locksmith", "lodging", "mosque", "museum", "painter", "park", "parking", "pharmacy", "pharmacies", "physiotherapist", "plumber", "police", "restaurant", "school", "spa", "stadium", "storage", "store", "synagog", "synagogue", "university", "universities", "zoo"};
String[] placesM = {"amusement park", "animal care", "animal care", "animal hospital", "art gallery", "art galleries", "beauty salon", "bicycle store", "book store", "bowling alley", "bus station", "car dealer", "car rental", "car repair", "car wash", "city hall", "clothing store", "convenience store", "department store", "electronics store", "electronic store", "fire station", "funeral home", "furniture store", "gas station", "general contractor", "hair care", "hardware store", "hindu temple", "home good store", "homes good store", "home goods store", "homes goods store", "insurance agency", "insurance agencies", "jewelry store", "liquor store", "local government office", "meal delivery", "meal deliveries", "meal takeaway", "movie rental", "movie theater", "moving company", "moving companies", "night club", "pet store", "place of worship", "places of worship", "post office", "real estate agency", "real estate agencies", "roofing contractor", "rv park", "shoe store", "shopping mall", "subway station", "taxi stand", "train station", "travel agency", "travel agencies", "veterinary care"};
int index;
for (int i = 0; i <= placesM.length - 1; i++) {
Log.e("TAG", "forM");
if (v2txt.contains(placesM[i])) {
Log.e("TAG", "sensedM?!");
index = i;
Uri gmmIntentUri = Uri.parse("geo:" + latitude + "," + longitude + "?q=" + placesM[index]);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
finish();
}
}
for (int i = 0; i <= placesS.length - 1; i++) {
Log.e("TAG", "forS");
if (v2txt.contains(placesS[i])) {
Log.e("TAG", "sensedS?!");
index = i;
Uri gmmIntentUri = Uri.parse("geo:" + latitude + "," + longitude + "?q=" + placesS[index]);
Intent mapIntent = new Intent(Intent.ACTION_VIEW, gmmIntentUri);
mapIntent.setPackage("com.google.android.apps.maps");
startActivity(mapIntent);
finish();
}
}
}
}
问题是总是和总是位置返回空值。而且我知道一个事实,只要启用了位置,另一个应用程序 Jarvis 就可以轻松完成任务,如果没有,则只是要求用户这样做。但在相同条件下,我的应用程序总是崩溃。
我做了什么:
- 日日夜夜试图解决这个问题。
- 浏览了许多关于该主题的页面。
- 尝试了我自己的不同代码。
它仍然会发生。我是Android的初学者。 请帮帮我。有没有办法解决我的问题?甚至认为其他应用程序以某种方式设法做到了。
这是我的 LogCat。
Process: com.kkze.Mappy, PID: 6742
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.kkze.Mappy/com.kkze.Mappy.PlacesDecoder}: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2658)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2723)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLatitude()' on a null object reference
at com.kkze.Mappy.PlacesDecoder.getLocation(PlacesDecoder.java:62)
at com.kkze.Mappy.PlacesDecoder.onCreate(PlacesDecoder.java:32)
at android.app.Activity.performCreate(Activity.java:6221)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1119)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2611)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2723)
at android.app.ActivityThread.access$900(ActivityThread.java:172)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1422)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:5832)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
还要检查 location!=null 需要 ACCESS_FINE_LOCATION 权限,这会弄乱我的应用程序,导致它始终返回为 null。
【问题讨论】:
-
所以
getLastKnownLocation正在返回 null,据记录可能会发生这种情况:“如果提供程序当前被禁用,则返回 null。”您的代码应该检查并相应地处理它。您说“在相同条件下” - 是当前禁用位置的条件吗?因为如果是这样,真的没有什么可以解释的了。 -
我应该怎么做?在相同的条件下,其他应用程序会这样做。或者有没有办法在不获取用户位置的情况下解决我的问题。请帮忙。
-
很抱歉,如果我向您施加压力或其他什么,但我真的很沮丧,即使在尽我所能搜索 Web 之后,我什至无法解决这么简单的问题。对不起。这边已经半夜了,我还是没办法阻止这个问题的发生。
-
@Jon Skeet 没有打开任何位置。我的应用程序崩溃。它成功了。如果位置已关闭,我们的两个应用程序都会将用户引导至设置页面以将其打开。
-
正确,因此 API 的行为完全按照文档说明。在调用任何方法之前,您应该检查
location是否为null:if (location == null) { /* take appropriate action */ } else { /* use location */ }
标签: java android google-maps nullpointerexception location