简体   繁体   中英

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);
}

and this is what I'm getting in the 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)

What did I do wrong? I have watched videos regarding this and they had the exact same code and it worked perfectly for them.

When I run the app it opens and asks for the user's location and when I give the access to the location, there's a long error in the Logcat.

The javadoc for getLastKnownLocation states:

Returns: the last known location for the given provider, or null if not available.

It is returning null ... and you are calling getLongitude() on the null .

Solution: change your code to deal with the situation where there is no "last known location" available.

If the location should be available, check that you are requesting the correct permissions, and that the device's (or emulator's) location services are working. But even so, your code ought to check that the location is not null and act appropriately... rather than crashing.


This might also be helpful:

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM