实际上我正在开发一个天气预报应用程序,当我试图获取用户最后已知的位置时出现空指针异常
Actually I'm working on a weather forecast app and I'm getting a null pointer exception when I'm trying to get the user last known location
private ProgressBar loadingPb;
private TextView cityNameTV ,conditionTV, temperatureTV;
private TextInputEditText cityEdt;
private RecyclerView weatherRV;
private ImageView backIV , iconIV , searchIV;
private ArrayList<WeatherRVmodel> weatherRVmodels;
private WeatherRVAdapter weatherRVAdapter;
private LocationManager locationManager;
private int PERMISSION_CODE = 1;
private String cityName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
homeRL = findViewById(R.id.idRLHome);
loadingPb = findViewById(R.id.idPBLoading);
cityNameTV = findViewById(R.id.idTVCityName);
conditionTV = findViewById(R.id.idTVCondition);
temperatureTV = findViewById(R.id.idTVTemperature);
weatherRV = findViewById(R.id.idRvWeather);
cityEdt = findViewById(R.id.idEdtCity);
backIV = findViewById(R.id.idIVback);
iconIV = findViewById(R.id.idIVIcon);
searchIV = findViewById(R.id.idIVSearch);
weatherRVmodels = new ArrayList<>();
weatherRVAdapter = new WeatherRVAdapter(this,weatherRVmodels);
weatherRV.setAdapter(weatherRVAdapter);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_CODE);
}
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
cityName = getCityName(location.getLongitude(),location.getLatitude());
getWeatherInfo(cityName);
searchIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String city = cityEdt.getText().toString();
if(city.isEmpty()){
Toast.makeText(MainActivity.this, "Please enter a City Name", Toast.LENGTH_SHORT).show();
}
else {
cityNameTV.setText(cityName);
getWeatherInfo(city);
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==PERMISSION_CODE){
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this, "Permission granted!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(MainActivity.this, "Please provide the permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private String getCityName(double longitude, double latitude){
String cityName = "Not found";
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
try{
List<Address> addressList = gcd.getFromLocation(latitude,longitude,10);
for(Address adr : addressList){
if(adr!=null){
String city = adr.getLocality();
if(city!=null && !city.equals("")){
cityName = city;
}
else{
Log.d("this","CITY NOT FOUND");
Toast.makeText(this, "User City not found..", Toast.LENGTH_SHORT).show();
}
}
}
}catch (IOException e){
e.printStackTrace();
}
return cityName;
}
private void getWeatherInfo(String cityName){
String url = "http://api.weatherapi.com/v1/forecast.json?key=3444b7679ba94113ab592316222401 &q="+ cityName +"&days=1&aqi=yes&alerts=yes";
cityNameTV.setText(cityName);
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
loadingPb.setVisibility(View.GONE);
homeRL.setVisibility(View.VISIBLE);
weatherRVmodels.clear();
try {
String temperature = response.getJSONObject("current").getString("temp_c");
temperatureTV.setText(temperature+"°C");
int isDay = response.getJSONObject("current").getInt("is_day");
String condition = response.getJSONObject("current").getJSONObject("condition").getString("text");
String conditionIcon = response.getJSONObject("current").getJSONObject("condition").getString("icon");
Picasso.get().load("http:".concat(conditionIcon)).into(iconIV);
conditionTV.setText(condition);
if(isDay == 1){
//Morning
Picasso.get().load("https://wallpapertops.com/walldb/original/c/a/1/485443.jpg").into(backIV);
}
else{
Picasso.get().load("https://www.mordeo.org/files/uploads/2018/10/Milky-Way-Starry-Sky-Night-4K-Ultra-HD-Mobile-Wallpaper.jpg").into(backIV);
}
JSONObject forecastobj = response.getJSONObject("forecast");
JSONObject forecastO = forecastobj.getJSONArray("forecastday").getJSONObject(0);
JSONArray hourArray = forecastO.getJSONArray("hour");
for(int i=0 ; i<hourArray.length();i++){
JSONObject hourObj = hourArray.getJSONObject(i);
String time = hourObj.getString("time");
String temper = hourObj.getString("temp_c");
String img = hourObj.getJSONObject("condition").getString("icon");
String wind = hourObj.getString("wind_kph");
weatherRVmodels.add(new WeatherRVmodel(time,temper,img,wind));
}
weatherRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Please enter valid city name", Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(jsonObjectRequest);
}
这就是我在 Logcat.
中得到的
2022-01-24 23:55:50.068 10835-10835/com.example.weatherupdates E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.weatherupdates, PID: 10835
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.weatherupdates/com.example.weatherupdates.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLongitude()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLongitude()' on a null object reference
at com.example.weatherupdates.MainActivity.onCreate(MainActivity.java:88)
at android.app.Activity.performCreate(Activity.java:8051)
at android.app.Activity.performCreate(Activity.java:8031)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)
我做错了什么?我看过有关这方面的视频,他们有完全相同的代码,而且非常适合他们。
当我 运行 应用程序打开并询问用户的位置时,当我授予该位置的访问权限时,Logcat.
中出现一个很长的错误
getLastKnownLocation
的 javadoc 状态:
Returns: the last known location for the given provider, or null
if not available.
正在返回 null
...而您正在 null
上呼叫 getLongitude()
。
解决方案:更改您的代码以处理没有可用的“最后已知位置”的情况。
如果位置应该可用,请检查您请求的权限是否正确,以及设备(或模拟器)的位置服务是否正常工作。但即使如此,您的代码也应该检查该位置是否 null
并采取适当的行动……而不是崩溃。
这也可能有帮助:
- What is the simplest and most robust way to get the user's current location on Android?
private ProgressBar loadingPb;
private TextView cityNameTV ,conditionTV, temperatureTV;
private TextInputEditText cityEdt;
private RecyclerView weatherRV;
private ImageView backIV , iconIV , searchIV;
private ArrayList<WeatherRVmodel> weatherRVmodels;
private WeatherRVAdapter weatherRVAdapter;
private LocationManager locationManager;
private int PERMISSION_CODE = 1;
private String cityName;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS,WindowManager.LayoutParams.FLAG_LAYOUT_NO_LIMITS);
homeRL = findViewById(R.id.idRLHome);
loadingPb = findViewById(R.id.idPBLoading);
cityNameTV = findViewById(R.id.idTVCityName);
conditionTV = findViewById(R.id.idTVCondition);
temperatureTV = findViewById(R.id.idTVTemperature);
weatherRV = findViewById(R.id.idRvWeather);
cityEdt = findViewById(R.id.idEdtCity);
backIV = findViewById(R.id.idIVback);
iconIV = findViewById(R.id.idIVIcon);
searchIV = findViewById(R.id.idIVSearch);
weatherRVmodels = new ArrayList<>();
weatherRVAdapter = new WeatherRVAdapter(this,weatherRVmodels);
weatherRV.setAdapter(weatherRVAdapter);
locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
if(ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)!= PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_COARSE_LOCATION)!= PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.ACCESS_FINE_LOCATION,Manifest.permission.ACCESS_COARSE_LOCATION},PERMISSION_CODE);
}
Location location = locationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
cityName = getCityName(location.getLongitude(),location.getLatitude());
getWeatherInfo(cityName);
searchIV.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
String city = cityEdt.getText().toString();
if(city.isEmpty()){
Toast.makeText(MainActivity.this, "Please enter a City Name", Toast.LENGTH_SHORT).show();
}
else {
cityNameTV.setText(cityName);
getWeatherInfo(city);
}
}
});
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode==PERMISSION_CODE){
if(grantResults.length>0 && grantResults[0]==PackageManager.PERMISSION_GRANTED){
Toast.makeText(MainActivity.this, "Permission granted!", Toast.LENGTH_SHORT).show();
}
else{
Toast.makeText(MainActivity.this, "Please provide the permission", Toast.LENGTH_SHORT).show();
finish();
}
}
}
private String getCityName(double longitude, double latitude){
String cityName = "Not found";
Geocoder gcd = new Geocoder(getBaseContext(), Locale.getDefault());
try{
List<Address> addressList = gcd.getFromLocation(latitude,longitude,10);
for(Address adr : addressList){
if(adr!=null){
String city = adr.getLocality();
if(city!=null && !city.equals("")){
cityName = city;
}
else{
Log.d("this","CITY NOT FOUND");
Toast.makeText(this, "User City not found..", Toast.LENGTH_SHORT).show();
}
}
}
}catch (IOException e){
e.printStackTrace();
}
return cityName;
}
private void getWeatherInfo(String cityName){
String url = "http://api.weatherapi.com/v1/forecast.json?key=3444b7679ba94113ab592316222401 &q="+ cityName +"&days=1&aqi=yes&alerts=yes";
cityNameTV.setText(cityName);
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
@Override
public void onResponse(JSONObject response) {
loadingPb.setVisibility(View.GONE);
homeRL.setVisibility(View.VISIBLE);
weatherRVmodels.clear();
try {
String temperature = response.getJSONObject("current").getString("temp_c");
temperatureTV.setText(temperature+"°C");
int isDay = response.getJSONObject("current").getInt("is_day");
String condition = response.getJSONObject("current").getJSONObject("condition").getString("text");
String conditionIcon = response.getJSONObject("current").getJSONObject("condition").getString("icon");
Picasso.get().load("http:".concat(conditionIcon)).into(iconIV);
conditionTV.setText(condition);
if(isDay == 1){
//Morning
Picasso.get().load("https://wallpapertops.com/walldb/original/c/a/1/485443.jpg").into(backIV);
}
else{
Picasso.get().load("https://www.mordeo.org/files/uploads/2018/10/Milky-Way-Starry-Sky-Night-4K-Ultra-HD-Mobile-Wallpaper.jpg").into(backIV);
}
JSONObject forecastobj = response.getJSONObject("forecast");
JSONObject forecastO = forecastobj.getJSONArray("forecastday").getJSONObject(0);
JSONArray hourArray = forecastO.getJSONArray("hour");
for(int i=0 ; i<hourArray.length();i++){
JSONObject hourObj = hourArray.getJSONObject(i);
String time = hourObj.getString("time");
String temper = hourObj.getString("temp_c");
String img = hourObj.getJSONObject("condition").getString("icon");
String wind = hourObj.getString("wind_kph");
weatherRVmodels.add(new WeatherRVmodel(time,temper,img,wind));
}
weatherRVAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
@Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Please enter valid city name", Toast.LENGTH_SHORT).show();
}
});
requestQueue.add(jsonObjectRequest);
}
这就是我在 Logcat.
中得到的2022-01-24 23:55:50.068 10835-10835/com.example.weatherupdates E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.weatherupdates, PID: 10835
java.lang.RuntimeException: Unable to start activity ComponentInfo{com.example.weatherupdates/com.example.weatherupdates.MainActivity}: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLongitude()' on a null object reference
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3635)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:3792)
at android.app.servertransaction.LaunchActivityItem.execute(LaunchActivityItem.java:103)
at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135)
at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2210)
at android.os.Handler.dispatchMessage(Handler.java:106)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'double android.location.Location.getLongitude()' on a null object reference
at com.example.weatherupdates.MainActivity.onCreate(MainActivity.java:88)
at android.app.Activity.performCreate(Activity.java:8051)
at android.app.Activity.performCreate(Activity.java:8031)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1329)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:3608)
我做错了什么?我看过有关这方面的视频,他们有完全相同的代码,而且非常适合他们。
当我 运行 应用程序打开并询问用户的位置时,当我授予该位置的访问权限时,Logcat.
中出现一个很长的错误getLastKnownLocation
的 javadoc 状态:
Returns: the last known location for the given provider, or
null
if not available.
正在返回 null
...而您正在 null
上呼叫 getLongitude()
。
解决方案:更改您的代码以处理没有可用的“最后已知位置”的情况。
如果位置应该可用,请检查您请求的权限是否正确,以及设备(或模拟器)的位置服务是否正常工作。但即使如此,您的代码也应该检查该位置是否 null
并采取适当的行动……而不是崩溃。
这也可能有帮助:
- What is the simplest and most robust way to get the user's current location on Android?