Приложение не отправляет запрос к интернет-ресурсу android 10+

Пишу парсер погоды на java для android и при тестировании на устройстве с версией android 5 запрос отправляется и приложение получает необходимые данные. Но на android 10 и выше приложение вместо объекта возвращает null.

Код класса, который отправляет запрос и возвращает JSON объект

package com.example.weatherapp;

import android.content.Context;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;


//RemoteFetch отвечает за получение данных о погоде через API сервиса OpenWeather
public class RemoteFetch {
    private static final String OPEN_WEATHER_MAP_API = "http://api.openweathermap.org/data/2.5/weather?q=%s&appid=0b9f2ad4f3628fb953da7636aa67d130&units=metric";
    public static JSONObject getJSON(Context context, String city) throws JSONException {
            // Создаем подключение к сервису OpenWeather
            try{
                URL url = new URL(String.format(OPEN_WEATHER_MAP_API, city));
                HttpURLConnection connection = (HttpURLConnection)url.openConnection();
                // Получаем данные в виде строк
                BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream()));
                StringBuffer json = new StringBuffer(1024);
                String tmp = "";
                // Записываем данные в переменную для последующего перевода в JSON объект
                while((tmp=reader.readLine())!=null){
                    json.append(tmp).append("\n");
                }
                reader.close();
                JSONObject data = new JSONObject(json.toString());
                // Если код ответа не равен 200, то данные не будут получены
                if(data.getInt("cod") != 200){
                    return null;
                }
                return data;
            }catch(Exception e){
                return null;
            }
    }
}

Код фрагмента

package com.example.weatherapp;

import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.os.Handler;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.support.v4.app.Fragment;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import org.json.JSONException;
import org.json.JSONObject;

import java.text.DateFormat;
import java.util.Date;


public class FragmentWeather extends Fragment implements View.OnClickListener {
    // Блок переменных для связи с элементами интерфейса
    TextView city_name_field;
    TextView city_temperature_field;
    TextView city_rain_field;
    TextView city_updated_time_field;
    TextView city_description_field;
    EditText city;
    Button button;

    Handler handler;

    public FragmentWeather(){
        handler = new Handler();
    }

    @Override
    public void onCreate(@Nullable @org.jetbrains.annotations.Nullable Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

    }

    @Override
    public View onCreateView(
            LayoutInflater inflater, ViewGroup container,
            Bundle savedInstanceState
    ) {

        View rootView = inflater.inflate(R.layout.fragment_weather, container, false);
        // Ниже задаются значения переменных для связи с элементами интерфейса
        city_name_field = (TextView)rootView.findViewById(R.id.city_name_field);
        city_updated_time_field= (TextView)rootView.findViewById(R.id.city_updated_time_field);
        city_description_field = (TextView)rootView.findViewById(R.id.city_description_field);
        city_temperature_field = (TextView)rootView.findViewById(R.id.city_temperature_field);
        city_rain_field = (TextView)rootView.findViewById(R.id.city_rain_field);
        button = (Button)rootView.findViewById(R.id.button);
        button.setOnClickListener(this);
        city = (EditText) rootView.findViewById(R.id.input);

        return rootView;

    }
    public static boolean isOnline(Context context)
    {
        ConnectivityManager cm =
                (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnectedOrConnecting())
        {
            return true;
        }
        return false;
    }
    @Override
    public void onDestroyView() {
        super.onDestroyView();
    }
    // Метод updateWeatherData получает в качестве аргумента строку с названием города на английском языке.
    // Используется для получения данных о погоде из класса RemoteFetch.
    private void updateWeatherData(String city){
        // Создаем отдельный поток для получения данных.
        // Если данные получены, то используем метод renderWeather, если нет - выводим высплывающее сообщение об ошибке.
        new Thread(){
            public void run() {
                final JSONObject json;
                try {
                    json = RemoteFetch.getJSON(getActivity(), city);
                    if (json == null) {
                        handler.post(new Runnable() {
                            public void run() {
                                Toast.makeText(getActivity(), getActivity().getString(R.string.city_not_found), Toast.LENGTH_LONG).show();
                            }
                        });
                    } else {
                        handler.post(new Runnable() {
                            public void run() {
                                renderWeather(json);
                            }
                        });
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        }.start();
    }
    // Метод renderWeather используется для отрисовки и изменения интерфейса.
    // В качестве аргумента получает JSON объект с данными о погоде.
    private void renderWeather(JSONObject json){
        try{
            // В этом блоке происходит замена текста элементов интерфейса на данные о погоде, полученные из полей JSON объекта.
            city_name_field.setText(json.getString("name").toUpperCase()+", "+json.getJSONObject("sys").getString("country"));
            JSONObject description = json.getJSONArray("weather").getJSONObject(0);
            JSONObject main = json.getJSONObject("main");
            city_description_field.setText(description.getString("description").toUpperCase()+"\n"+"Влажность: "+main.getString("humidity")+"%"+"\n"+"Давление: "+main.getString("pressure")+"hPa");
            city_temperature_field.setText(String.format("%.2f", main.getDouble("temp"))+"℃");
            DateFormat dateFormat = DateFormat.getDateTimeInstance();
            String updated_time = dateFormat.format(new Date(json.getLong("dt")*1000));
            city_updated_time_field.setText("Последнее обновление: " + updated_time);
            setWeather(description.getInt("id"), json.getJSONObject("sys").getLong("sunrise")*1000, json.getJSONObject("sys").getLong("sunset")*1000);

        }catch(Exception e){
            Log.e("WeatherApp", "Один или несколько полей не были найдены в json");
        }
    }
    // Метод setWeather в качестве аргументов получает три числа: id, время восхода и время заката.
    // Используется для выбора иконки погодных условий
    private void setWeather(Integer actualId, long sunrise, long sunset){
        int id = actualId/100;
        String icon = "";
        if(actualId == 800){
            long currentTime = new Date().getTime();
            if(currentTime>=sunrise && currentTime<sunset){
                icon = getActivity().getString(R.string.sunny);
            }
        }else{
            switch(id){
                case 2:
                    icon = getActivity().getString(R.string.thunder);
                    break;
                case 3:
                    icon = getActivity().getString(R.string.drizzle);
                    break;
                case 5:
                    icon = getActivity().getString(R.string.rainy);
                    break;
                case 6:
                    icon = getActivity().getString(R.string.snowy);
                    break;
                case 7:
                    icon = getActivity().getString(R.string.foggy);
                    break;
                case 8:
                    icon = getActivity().getString(R.string.cloudy);
                    break;
            }
        }
        city_rain_field.setText(icon);
    }
    // В переопределенном методе onClick вызываем метод updateWeatherData для получения и отрисовки данных о погоде.
    @Override
    public void onClick(View v) {
        if ( !isOnline(getContext()) ){
            Toast.makeText(getActivity(), "No internet connection", Toast.LENGTH_LONG).show();
        }else{
            updateWeatherData(city.getText().toString());
        }

    }
}

Ответы (0 шт):