Bonsoir,
Je suis actuellement sur un projet utilisant l'API PokeApi sur "https://pokeapi.co/api/v2/". Je souhaite faire différentes lectures JSON pour récupérer des informations variées sur les pokémons de première génération.
J'en viens à mon problème. Lorsque je lis dans le JSON à l'aide d'un BufferedInputStream, lors de la deuxième lecture successive, une erreur se produit. Cela se produit lorsque je clique sur un pokemon dans mon listView, cette interface utilisateur est censée afficher des détails sur le pokemon. Il s'agit d'une exception globale et je ne peux pas obtenir plus d'informations à ce sujet. Cela se produit dans ma classe 'HttpHandler.java', l.37.
Je n'ai aucune idée de quoi faire : j'ai fermé les connexions après l'ouverture et j'ai essayé d'utiliser 'AsyncTask' pour gérer les connexions.
Voici quelques classes : ListeActivity.java qui me permet d'afficher la liste des pokemons, RecuperationPokemonJSONListe.java qui me permet de récupérer les infos Je veux afficher les pokemons dans la listeView, RecuperationPokemonJSONListe.java qui me permet de récupérer les infos d'un pokemon en particulier .
J'en profite également pour mettre les classes ListeActivity.java et PokemonDetailActivity.java ainsi que les erreurs que je rencontre.
En tout cas merci pour toutes les idées que vous pourrez m'apporter.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93 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); } }); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 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 ); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64 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(); } }
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 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; } }L'erreur :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145 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; } }
Cf. PJ


J'ai essayé d'étendre AsyncTask<> mais cela n'a pas fonctionné et j'ai pris soin de fermer toutes les connexions ouvertes avec des URL. Je n'ai pas d'autre idée.
Bonne fin de journée.
Théo
Partager