实际上我正在开发一个天气预报应用程序,当我试图获取用户最后已知的位置时出现空指针异常

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.

中出现一个很长的错误

getLastKnownLocationjavadoc 状态:

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?