Why do I get a blank answer when an Android app accesses my API on my server?

I have an Android app that calls information and shows it as a list.

I have a counter, when you select a date from the counter, you get information related to this date.

In the first download of the application, it automatically calls information today.

this is the code that I use in my main action to create my counter and fill it with elements and process clicks on each element:

// Spinner element spinner = (Spinner) v.findViewById(R.id.spinner); // Spinner click listener spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { public void onItemSelected(AdapterView<?> parent, View view, int position, long id) { // On selecting a spinner item //String item = parent.getItemAtPosition(position).toString(); switch(position){ case 3: if (JsonUtils.isNetworkAvailable(getActivity())) { list.clear(); new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=-1"); } else { Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show(); } break; case 4: if (JsonUtils.isNetworkAvailable(getActivity())) { list.clear(); new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=0"); } else { Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show(); } break; case 5: if (JsonUtils.isNetworkAvailable(getActivity())) { list.clear(); new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=1"); } else { Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show(); } break; default: if (JsonUtils.isNetworkAvailable(getActivity())) { list.clear(); new MyTask().execute(Config.SERVER_URL + "/banko_api.php?d_o=0"); } else { Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show(); } break; } } @Override public void onNothingSelected(AdapterView<?> parent) { } }); Calendar calendar = Calendar.getInstance(); Date today = calendar.getTime(); calendar.add(Calendar.DAY_OF_YEAR, -1); Date yesterday = calendar.getTime(); calendar = Calendar.getInstance(); calendar.add(Calendar.DAY_OF_YEAR, 1); Date tomorrow = calendar.getTime(); DateFormat dateFormat = new SimpleDateFormat("dd/MM EEE"); String todayAsString = dateFormat.format(today); String tomorrowAsString = dateFormat.format(tomorrow); String yesterdayAsString = dateFormat.format(yesterday); // Spinner Drop down elements List<String> categories = new ArrayList<String>(); categories.add(yesterdayAsString); categories.add(todayAsString); categories.add(tomorrowAsString); // Creating adapter for spinner ArrayAdapter<String> dataAdapter = new ArrayAdapter<String>(getContext(), R.layout.spinner_item, categories); dataAdapter.setDropDownViewResource(R.layout.spinner_dropdown_item); // attaching data adapter to spinner spinner.setAdapter(dataAdapter); spinner.setSelection(4); 

Problem: The first download of the application is to call today's data (which is the default choice in my counter) without any problems. if I select another item in the counter, it will also call related data without problems. Now, if I want to select the item back today in the counter, the data will not be transferred from the server, even when the application, when it starts, it calls the data from the same link and receives it.

I get this message in my log: W/System.err: org.json.JSONException: Value [] of type org.json.JSONArray cannot be converted to JSONObject

The onPostExcute of my Asynktask contains this code:

 @Override protected void onPostExecute(String result) { super.onPostExecute(result); if (null != progressDialog && progressDialog.isShowing()) { progressDialog.dismiss(); } if (null == result || result.length() == 0) { Toast.makeText(getActivity(), getResources().getString(R.string.failed_connect_network), Toast.LENGTH_SHORT).show(); } else { try { Log.d("resultTT",result); JSONObject mainJson = new JSONObject(result); JSONArray jsonArray = mainJson.getJSONArray(JsonConfig.CATEGORY_ARRAY_NAME); JSONObject objJson = null; for (int i = 0; i < jsonArray.length(); i++) { objJson = jsonArray.getJSONObject(i); ItemMatch objItem = new ItemMatch(); objItem.setMatchId(objJson.getString(JsonConfig.Match_ID)); objItem.setMatchTournamentName(objJson.getString(JsonConfig.Match_LEAGUE_NAME)); objItem.setMatchTime(objJson.getString(JsonConfig.Match_TIME)); objItem.setMatchStatus(objJson.getString(JsonConfig.Match_STATUS)); objItem.setMatchLocalTeamName(objJson.getString(JsonConfig.Match_LOCALTEAM_NAME)); objItem.setMatchVisitorTeamName(objJson.getString(JsonConfig.Match_VISITORTEAM_NAME)); objItem.setMatchLocalTeamGoals(objJson.getString(JsonConfig.Match_LOCALTEAM_GOALS)); objItem.setMatchVisitorTeamGoals(objJson.getString(JsonConfig.Match_VISITORTEAM_GOALS)); objItem.setMatchBestOddPercent(objJson.getString(JsonConfig.Match_BEST_ODD_PERCENT)); objItem.setMatchBestOddResult(objJson.getString(JsonConfig.Match_BEST_ODD_RESULT)); list.add(objItem); } } catch (JSONException e) { e.printStackTrace(); } for (int j = 0; j < list.size(); j++) { object = list.get(j); array_match_id.add(String.valueOf(object.getMatchId())); str_match_id = array_match_id.toArray(str_match_id); array_league_name.add(String.valueOf(object.getMatchTournamentName())); str_league_name = array_league_name.toArray(str_league_name); array_match_time.add(String.valueOf(object.getMatchTime())); str_match_time = array_match_time.toArray(str_match_time); array_match_status.add(String.valueOf(object.getMatchStatus())); str_match_status = array_match_status.toArray(str_match_status); array_match_localteam_name.add(object.getMatchLocalTeamName()); str_match_localteam_name = array_match_localteam_name.toArray(str_match_localteam_name); array_match_visitorteam_name.add(object.getMatchVisitorTeamName()); str_match_visitorteam_name = array_match_visitorteam_name.toArray(str_match_visitorteam_name); array_match_localteam_goals.add(object.getMatchLocalTeamGoals()); str_match_localteam_goals = array_match_localteam_goals.toArray(str_match_localteam_goals); array_match_visitorteam_goals.add(object.getMatchVisitorTeamGoals()); str_match_visitorteam_goals = array_match_visitorteam_goals.toArray(str_match_visitorteam_goals); array_match_best_odd_percent.add(object.getMatchBestOddPercent()); str_match_best_odd_percent = array_match_best_odd_percent.toArray(str_match_best_odd_percent); array_match_best_odd_result.add(object.getMatchBestOddResult()); str_match_best_odd_result = array_match_best_odd_result.toArray(str_match_best_odd_result); } setAdapterToListView(); } 

In the try section of this code, you can see that I am doing a result log to see what is happening from the server, I just get the following: D/resultTT: []

and, as you see, the attempt is inside the else section, so in the if statement of this section I check whether the result is null or empty; but the code passes it and enters the else statement, but still shows that the returned array of results is empty.

I need help finding the reason for this empty returned array, even if it loads normally at startup. why can't it get information after I select some element in the spinner and then return to the default element (today)?

UPDATE: this is my third-party php server api

 <?php include_once ('includes/variables.php'); DEFINE ('DB_HOST', $host); DEFINE ('DB_USER', $user); DEFINE ('DB_PASSWORD', $pass); DEFINE ('DB_NAME', $database); $mysqli = @mysql_connect (DB_HOST, DB_USER, DB_PASSWORD) OR die ('Could not connect to MySQL'); @mysql_select_db (DB_NAME) OR die ('Could not select the database'); ?> <?php mysql_query("SET NAMES 'utf8'"); $date_offset = mysql_real_escape_string($_GET[d_o]); //$date_offset = 0; if(empty($date_offset) || $date_offset == "0") { $date_offset_value = "0"; $query="SELECT a.*, m.match_id, m.match_time, m.en_tournament_name FROM app_banko a inner join matches_of_comments m on m.match_id = a.match_id where a.date_offset = $date_offset_value limit 20"; $resouter = mysql_query($query); } else { $date_offset_value = $date_offset; $query="SELECT a.*, m.match_id, m.match_time, m.en_tournament_name FROM app_banko a inner join matches_of_comments m on m.match_id = a.match_id where a.date_offset = $date_offset_value limit 20"; $resouter = mysql_query($query); } $set = array(); $total_records = mysql_num_rows($resouter); if($total_records >= 1){ while ($link = mysql_fetch_array($resouter, MYSQL_ASSOC)){ $set['NewsApp'][] = $link; } } echo $val= str_replace('\\/', '/', json_encode($set)); ?> 
+5
source share
5 answers

The result string is an empty array. but not an empty string . An empty array is represented as the following line:

 String result = "[]"; 

In this case, result.length() is 2 .

When parsing JSON, you need to know if the object in question is of type Object or of type Array . The first one is wrapped in brackets {} , the later with square brackets [] .

So the following line:

 JSONObject mainJson = new JSONObject(result); 

Must be:

 JSONArray mainJson = new JSONArray(result); 

But I cannot stress that you need to know what your API returns if you want to parse it correctly.

EDIT:

Well, json_encode will be hard to determine if it should create a JSON Array or JSON Object from an empty array created using $set = array(); .
Adding objects to the array, as in your loop, makes it obvious to json_encode that it should create a JSON Object .
I don't know if you can force json_encode behavior, but in the worst case you can check yourself if the array is empty and return "" or null if the array is empty.

 $set = array(); $total_records = mysql_num_rows($resouter); if ($total_records >= 1) { while ($link = mysql_fetch_array($resouter, MYSQL_ASSOC)) { $set['NewsApp'][] = $link; } echo $val= str_replace('\\/', '/', json_encode($set)); } else { echo $val=""; } 
+4
source

If you get an array while waiting for an object, maybe something is wrong with the API request. One way is to figure out how to configure Wireshark on a development machine to sniff and filter traffic. Then you can find out if your request is defective.

+4
source

It is possible that the value of the response argument from the onPostExecute method contains a string JSONArray , not a JSONObject .

You can always check it with

 try: JSONArray jsonArray = new JSONArray(result); catch(JSONException e) { // String `result` is not an array. Parse it as a regular JSONObject. } 

Testing string string - an empty json array (depending on its formatting, especially if it can contain several white characters), checking its length can be a pretty bad idea.

It all depends on how the API endpoints that you call are defined.

One more tip at the end. If you plan to use the REST API, I highly recommend using:

  • Modernization - this allows you to easily define interfaces for accessing the API,
  • GSON - automatic response conversion for Java models.
+4
source

please put the result of the .isEmpty () check in your try block state, this may solve your problem.

+4
source

you cannot directly get the answer in a row. it can use JSONObject and JSONArray.

+4
source

Source: https://habr.com/ru/post/1246957/


All Articles