Theo
Theo

Reputation: 11

PokeApi JSON read error on Android Studio in Java

Good evening, I'm currently on a project using the PokeApi API at "https://pokeapi.co/api/v2/". I want to do different JSON reads to retrieve varied information about first generation pokemons. I come to my problem. When I read in the JSON using a BufferedInputStream, on the second successive read an error occurs. This happens when I click on a pokemon in my listView, this ui is supposed to display details about the pokemon. This is a global exception and I can't get more information on it. It occurs in my 'HttpHandler.java' class, l.37. I have no idea, I checked: I closed connections after opening and tried to use 'AsyncTask' to manage connections.

Here are some classes: ListeActivity.java which allows me to display the list of pokemons, RecuperationPokemonJSONListe.java which allows me to retrieve the info I want to display the pokemons in the listeView, RecuperationPokemonJSONListe.java allowing me to retrieve info from a particular pokemon.

I also take this opportunity to put the classes ListeActivity.java and PokemonDetailActivity.java as well as the errors that I encounter.

Anyway, thank you for any insights you can give me.

public class ListeActivity extends AppCompatActivity {
    private ListView listePokemons;
    private ArrayList<Pokemon> listePokemon;
    private ProgressDialog progressDialog;

    private SearchView mySearchView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_liste);

        mySearchView = (SearchView)findViewById(R.id.searchView);

        //on définit le texte par defaut de notre barre de recherche
        mySearchView.setQueryHint("Ecrivez un nom de pokemon");

        listePokemons = (ListView) findViewById(R.id.liste_pokemons);

        executeInThread();
    }


    private void executeInThread(){
        onPreExecute();
        RecuperationPokemonJSONListe<Pokemon> getPokemon = new RecuperationPokemonJSONListe();
        Runnable runnable = ()->{
            getPokemon.doInBackground();
            runOnUiThread( ()-> onPostExecute( getPokemon.getItemResult()) );
        };
        Executors.newSingleThreadExecutor().execute( runnable );
    }

    /**
     * This method is called before the asynchronous webConnexion start
     */
    private void onPreExecute() {
        progressDialog = new ProgressDialog(ListeActivity.this);
        progressDialog.setMessage("Accès aux données des pokémons...");
        progressDialog.setCancelable(false);
        progressDialog.show();
    }


    private void onPostExecute(ArrayList<Pokemon> pokemonList) {
        progressDialog.dismiss();

        //on associe la liste de pokemon à la liste de pokemon de la classe
        this.listePokemon = pokemonList;
        // référence pour l'adaptateur de liste complète de Pokemon
        PokemonAdapter fullAdapter = new PokemonAdapter(getApplicationContext(), pokemonList);
        // référence pour l'adaptateur de liste filtrée
        PokemonAdapter filteredAdapter = new PokemonAdapter(getApplicationContext(), pokemonList);

        // Utilisez l'adaptateur de liste complète de Pokemon pour afficher la liste au départ
        listePokemons.setAdapter(fullAdapter);

        // Lorsque l'utilisateur modifie le texte dans la barre de recherche
        mySearchView.setOnQueryTextListener(new SearchView.OnQueryTextListener(){
            @Override
            public boolean onQueryTextSubmit(String s){
                return false;
            }

            @Override
            public boolean onQueryTextChange(String s){
                if (TextUtils.isEmpty(s)) {
                    // Si la barre de recherche est vide, adaptateur de liste complète de Pokemon pour réinitialiser la liste
                    listePokemons.setAdapter(fullAdapter);
                }
                else {
                    // Sinon, adaptateur filtré pour afficher les éléments filtrés
                    filteredAdapter.getFilter().filter(s);
                    listePokemons.setAdapter(filteredAdapter);
                }
                return true;
            }
        });



        listePokemons.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            @Override
            public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                Intent pokemonDetailActivity = new Intent(ListeActivity.this, PokemonDetailActivity.class);
                int idPok = listePokemon.get(position).getId();
                pokemonDetailActivity.putExtra("POKEMON_SELECTION_ID", idPok);
                startActivity(pokemonDetailActivity);
            }
        });

    }
}
public class PokemonDetailActivity extends AppCompatActivity {

    private int idPokemon;
    private RecuperationDetailPokemonJSON detailsPokemon;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_pokemon_detail);

        idPokemon = getIntent().getIntExtra("POKEMON_SELECTION_ID", -1);


        // on associe l'image du pokemon à l'imageView
        ImageView imagePokemon = findViewById(R.id.imageview_pokemon);
        imagePokemon.setImageBitmap(detailsPokemon.getImagePokemon());

        // on associe le nom du pokemon au textView
        TextView namePokemon = findViewById(R.id.nom_pokmeon);
        namePokemon.setText(getApplicationContext().getString(R.string.nom) + detailsPokemon.getNamePokemon());

        //on associe la postion du pokemon au textView
        TextView positionPokemon = findViewById(R.id.posture_pokemon);
        positionPokemon.setText(getApplicationContext().getString(R.string.posture) + detailsPokemon.getPosturePokemon());

        // on associe la taille du pokemon au textView
        TextView taillePokemon = findViewById(R.id.taille_pokemon);
        taillePokemon.setText(getApplicationContext().getString(R.string.taille) + detailsPokemon.getTaillePokemon());

        // on associe l'habitat du pokemon au textView
        TextView habitatPokemon = findViewById(R.id.habitat_pokemon);
        habitatPokemon.setText(getApplicationContext().getString(R.string.habitat) + detailsPokemon.getHabitatPokemon());

        // on associe les stats du pokemon aux textView
        TextView hpPokemon = findViewById(R.id.hp);
        TextView attaquePokemon = findViewById(R.id.attaque);
        TextView defensePokemon = findViewById(R.id.defense);
        TextView attaqueSpePokemon = findViewById(R.id.attaque_speciale);
        TextView defenseSpePokemon = findViewById(R.id.defense_speciale);
        TextView vitessePokemon = findViewById(R.id.vitesse);

        hpPokemon.setText(getApplicationContext().getString(R.string.hp) + detailsPokemon.getStatsPokemon().get(0).toString());
        attaquePokemon.setText(getApplicationContext().getString(R.string.attaque) + detailsPokemon.getStatsPokemon().get(1).toString());
        defensePokemon.setText(getApplicationContext().getString(R.string.defense) + detailsPokemon.getStatsPokemon().get(2).toString());
        attaqueSpePokemon.setText(getApplicationContext().getString(R.string.attaqueSpe) + detailsPokemon.getStatsPokemon().get(3).toString());
        defenseSpePokemon.setText(getApplicationContext().getString(R.string.defenseSpe) + detailsPokemon.getStatsPokemon().get(4).toString());
        vitessePokemon.setText(getApplicationContext().getString(R.string.vitesse) + detailsPokemon.getStatsPokemon().get(5).toString());

    }

    private void executeInThread(){
        RecuperationDetailPokemonJSON detailsPokemon = new RecuperationDetailPokemonJSON(idPokemon);
        Runnable runnable = ()->{
            detailsPokemon.doInBackground();
        };
        Executors.newSingleThreadExecutor().execute( runnable );
    }

}
public class HttpHandler {

    private static final String TAG = "theo_jessica " + RecuperationPokemonJSONListe.class.getSimpleName();    //Pour affichage en cas d'erreur

    public String makeServiceCall(String reqUrl) {
        HttpURLConnection urlConnection = null;
        String response = null;
        try {
            URL url = new URL(reqUrl);
            urlConnection = (HttpURLConnection) url.openConnection();
            if (!url.getHost().equals(urlConnection.getURL().getHost())) {
                // we were redirected! Kick the user out to the browser to sign on?
                Log.d("ZZZZZZZZZZZZZZZZZZZZZ", "on est redirigé");
            }
            //urlConnection.setRequestMethod("GET");
            // lecture du fichier
            urlConnection.setUseCaches(false);
            //InputStream inputStream = new BufferedInputStream(urlConnection.getInputStream());
            InputStream inputStream;
            if (urlConnection.getResponseCode() != HttpURLConnection.HTTP_OK) {
                inputStream = urlConnection.getErrorStream();
            } else {
                inputStream = urlConnection.getInputStream();
            }
            response = convertStreamToString(inputStream);
        }
        catch (MalformedURLException e) {
            Log.e(TAG, "MalformedURLException: " + e.getMessage());
        } catch (ProtocolException e) {
            Log.e(TAG, "ProtocolException: " + e.getMessage());
        } catch (IOException e) {
            Log.e(TAG, "IOException: " + e.getMessage());
        } catch (Exception e) {
            Log.e(TAG, "Exception: " + e.getMessage());
        }
        finally {
            if(urlConnection != null)
                urlConnection.disconnect();
        }
        return response;
    }

    //Conversion flux en String
    private String convertStreamToString(InputStream inputStream) {
        BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));
        StringBuilder stringBuilder = new StringBuilder();
        String line;
        try {
            while ((line = reader.readLine()) != null) {
                stringBuilder.append(line).append('\n');
                Log.e(TAG,line);
            }
        }
        catch (IOException e) {  e.printStackTrace();   }
        finally {
            try {
                inputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return stringBuilder.toString();
    }
}
public class RecuperationPokemonJSONListe<T> extends AsyncTask<Void, Void, ArrayList<T>> {

    private static final String TAG = "theo_jessica " + RecuperationPokemonJSONListe.class.getSimpleName();
    private ArrayList<T> itemList;
    private HttpHandler webService;

    private String urlPokemons = "https://pokeapi.co/api/v2/generation/1/";
    private String URLImages = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/";

    public RecuperationPokemonJSONListe() {
        webService = new HttpHandler();
        this.itemList = new ArrayList<>();
    }

    @Override
    protected ArrayList<T> doInBackground(Void... voids) {
        HttpURLConnection connection = null;
        String jsonStr = webService.makeServiceCall(urlPokemons);
        Log.d(TAG, "URL_ADDR liste pok :    " + urlPokemons);
        Log.d(TAG, "Response from url liste pok :    " + jsonStr);

        if (jsonStr != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr);
                JSONArray pokemonSpecies = jsonObj.getJSONArray("pokemon_species");

                for (int i = 0; i < pokemonSpecies.length(); i++) {
                    JSONObject pokemon = pokemonSpecies.getJSONObject(i);
                    String namePokemon = pokemon.getString("name");
                    String urlPokemon = pokemon.getString("url");
                    String[] urlSplit = urlPokemon.split("/");
                    int idPokemon = Integer.parseInt(urlSplit[urlSplit.length - 1]);
                    String imagePokemon = URLImages + idPokemon + ".png";

                    URL imageUrl = new URL(imagePokemon);
                    connection = (HttpURLConnection) imageUrl.openConnection();
                    connection.setDoInput(true);
                    connection.connect();
                    InputStream inputStream = connection.getInputStream();
                    Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                    Bitmap bitmapImagePokemon = Bitmap.createScaledBitmap(bitmap, 200, 200, true);

                    itemList.add((T) new Pokemon(bitmapImagePokemon, namePokemon, idPokemon));
                }
            } catch (JSONException e) {
                throw new RuntimeException(e);
            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } finally {
                if (connection != null) {
                    Log.d("$$$$$$$$$$$$$$$$$$$$$$$$", "ON PASSE ET ON DECONNECTE");
                    connection.disconnect();
                }
            }
        }
        return itemList;
    }

    @Override
    protected void onPostExecute(ArrayList<T> itemList) {
        super.onPostExecute(itemList);
        // Mettez à jour l'interface utilisateur ou appelez une méthode avec itemList
    }

    public ArrayList<T> getItemResult() {
        return itemList;
    }
}
public class RecuperationDetailPokemonJSON extends AsyncTask<Void, Void, Void> {

    private static final String TAG = "theo_jessica " + RecuperationPokemonJSONListe.class.getSimpleName();
    private String urlPokemonDetails1 = "https://pokeapi.co/api/v2/pokemon-species/";
    private String urlPokemonDetails2 = "https://pokeapi.co/api/v2/pokemon/";
    private int idPokemon;
    private HttpHandler webService;
    private String URLImages = "https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/";

    private Bitmap imagePokemon;
    private String namePokemon;
    private String posturePokemon;
    private int taillePokemon;
    private String habitatPokemon;
    private ArrayList<Integer> statsPokemon;

    public RecuperationDetailPokemonJSON(int idPokemon) {
        webService = new HttpHandler();
        this.idPokemon = idPokemon;
        this.urlPokemonDetails1 += idPokemon + "/";
        this.urlPokemonDetails2 += idPokemon + "/";
        statsPokemon = new ArrayList<>();
    }

    @Override
    protected Void doInBackground(Void... voids) {
        HttpURLConnection connection = null;
        // get the jsonStr to parse
        String jsonStr1 = webService.makeServiceCall(urlPokemonDetails1);
        Log.d(TAG, "URL_ADDR detail pok :    " + urlPokemonDetails1);
        Log.d(TAG, "Response from url detail pok :    " + jsonStr1);
        //parse jsonStr
        if (jsonStr1 != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr1);

                //get the image of the pokemon
                URL imageUrl = new URL(URLImages + idPokemon + ".png");
                connection = (HttpURLConnection) imageUrl.openConnection();
                connection.setDoInput(true);
                connection.connect();
                InputStream inputStream = connection.getInputStream();
                Bitmap bitmapImagePokemon = BitmapFactory.decodeStream(inputStream);

                //get the name of the pokemon
                String namePokemon = jsonObj.getString("name");

                // get the living area of the pokemon
                JSONObject habitat = jsonObj.getJSONObject("habitat");
                String habitatPokemon = habitat.getString("name");

                // get the shape of the pokemon
                JSONObject shape = jsonObj.getJSONObject("shape");
                String shapePokemon = shape.getString("name");

                this.imagePokemon = bitmapImagePokemon;
                this.namePokemon = namePokemon;
                this.habitatPokemon = habitatPokemon;
                this.posturePokemon = shapePokemon;

            } catch (MalformedURLException e) {
                throw new RuntimeException(e);
            } catch (IOException e) {
                throw new RuntimeException(e);
            } catch (JSONException e) {
                throw new RuntimeException(e);
            } finally {
                if (connection != null) {
                    connection.disconnect();
                }
            }
        }

        String jsonStr2 = webService.makeServiceCall(urlPokemonDetails2);
        Log.d(TAG, "URL_ADDR detail pok2 :    " + urlPokemonDetails2);
        Log.d(TAG, "Response from url detail pok2 :    " + jsonStr2);
        //parse jsonStr
        if (jsonStr2 != null) {
            try {
                JSONObject jsonObj = new JSONObject(jsonStr2);

                // get the height of the pokemon
                int heightPokemon = jsonObj.getInt("height");

                // get the stats of the pokemon
                JSONArray stats = jsonObj.getJSONArray("stats");
                JSONObject stat = stats.getJSONObject(0);
                JSONObject stat1 = stats.getJSONObject(1);
                JSONObject stat2 = stats.getJSONObject(2);
                JSONObject stat3 = stats.getJSONObject(3);
                JSONObject stat4 = stats.getJSONObject(4);
                JSONObject stat5 = stats.getJSONObject(5);
                int hp = stat.getInt("base_stat");
                int attack = stat1.getInt("base_stat");
                int defense = stat2.getInt("base_stat");
                int specialAttack = stat3.getInt("base_stat");
                int specialDefense = stat4.getInt("base_stat");
                int speed = stat5.getInt("base_stat");

                this.taillePokemon = heightPokemon;
                this.statsPokemon.add(hp);
                this.statsPokemon.add(attack);
                this.statsPokemon.add(defense);
                this.statsPokemon.add(specialAttack);
                this.statsPokemon.add(specialDefense);
                this.statsPokemon.add(speed);

            } catch (JSONException e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }


    @Override
    protected void onPostExecute(Void aVoid) {
        super.onPostExecute(aVoid);
        // Mettez à jour l'interface utilisateur ou appelez une méthode avec les résultats obtenus
    }

    public Bitmap getImagePokemon() {
        return imagePokemon;
    }

    public String getNamePokemon() {
        return namePokemon;
    }

    public String getPosturePokemon() {
        return posturePokemon;
    }

    public int getTaillePokemon() {
        return taillePokemon;
    }

    public String getHabitatPokemon() {
        return habitatPokemon;
    }

    public ArrayList<Integer> getStatsPokemon() {
        return statsPokemon;
    }
}

The errors :

error

I tried to extends AsyncTask<> but that didn't worked and take care to close all the connections open with urls. I have no other idea.

Upvotes: 1

Views: 136

Answers (0)

Related Questions