I have json data from webservice that should be stored in two lists, String list and Integer List. the one for strings stores the data fine but the one for the integers doesn't. it prompts error saying java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
here is the complete code
public class Setup extends AppCompatActivity {
Button save;
EditText schoolPK;
String schoolname, classname, cityname, school_id,class_id;
ImageView logout;
GridView grid;
String cityid,classid;
int schoolid;
ArrayList<String> CityName, CityId;
private List<Integer> classID=new ArrayList<Integer>();
private List<String> listschools = new ArrayList<String>();
private List<String> listclasses = new ArrayList<String>();
Spinner schoolspinner;
public static final String MyPREFERENCES = "MyPrefs" ;
public static final String classnames = "classname";
public static final String schoolnames = "schoolname";
public static final String Email = "emailKey";
SharedPreferences sharedpreferences;
String saved_letter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.setup2);
CityName=new ArrayList<>();
CityId = new ArrayList<>();
//classID = new ArrayList<>();
// schoolID = new ArrayList<>();
schoolPK = (EditText) findViewById(R.id.schoolPK);
final Spinner city = (Spinner) findViewById(R.id.city);
final Spinner classspinner = (Spinner) findViewById(R.id.classname);
String URL_countries="http://192.168.0.148/Election/api/school";
JsonArrayRequest items = new JsonArrayRequest(URL_countries, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0;i<response.length();i++){
try {
JSONObject obj = response.getJSONObject(i);
String country=obj.getString("name_Ar");
String cityid = obj.getString("pK_ID");
CityId.add(cityid);
CityName.add(country);
}
catch (JSONException e) {
e.printStackTrace();
}
city.setAdapter(new ArrayAdapter<String>(Setup.this, android.R.layout.select_dialog_item, CityName));
}
//to get me the
}
}, new Response.ErrorListener(){
#Override
public void onErrorResponse(VolleyError error) {
AlertDialog.Builder add = new AlertDialog.Builder(Setup.this);
add.setMessage(error.getMessage()).setCancelable(true);
AlertDialog alert = add.create();
alert.setTitle("error");
alert.show();
}
} );
Controller.getInstance(Setup.this).addToRequestque(items);
city.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
cityname = parent.getItemAtPosition(position).toString();
cityid = CityId.get(position).toString();
//CityId.clear();
listclasses.clear();
getclasses();
} // to close the onItemSelected
public void onNothingSelected(AdapterView<?> parent) {
}
});
classspinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
classname = parent.getItemAtPosition(position).toString();
class_id = classID.get(position).toString();
}
// to close the onItemSelected
public void onNothingSelected(AdapterView<?> parent) {
}
});
save = (Button) findViewById(R.id.save);
save.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
sharedpreferences = getSharedPreferences("Settings", Context.MODE_PRIVATE);
SharedPreferences.Editor editor = sharedpreferences.edit();
Intent intent = new Intent(getApplicationContext(), Vote.class);
editor.putString("schoolname", cityname);
editor.putString("schoolid", cityid);
editor.putString("classname", classname);
editor.putString("classid", class_id);
editor.apply();
}
});
}
public void getschools(){
try {
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
String URL = "http://192.168.0.148/Election/api/School";
JSONObject jsonBody = new JSONObject();
// jsonBody.put("tblRegisteredUsers_nickName", username.getText().toString().trim());
jsonBody.put("cityFK_ID", cityid);
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//my response later should be changed
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
})
{
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString;
String json = null;
try {
json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
responseString = String.valueOf(json).trim();
ArrayList<Schoolresponse> list_response = new ArrayList<Schoolresponse>();
Type listType = new TypeToken<List<Schoolresponse>>() {}.getType();
list_response = new Gson().fromJson(responseString, listType);
// schoolID= new ArrayList<>();
for (int i = 0; i < list_response.size(); i++) {
School listItemData = new School();
listItemData.setName(list_response.get(i).getNameAr());
listItemData.setId(list_response.get(i).getPKID());
//schoolID.add(listItemData.getId());
listschools.add(listItemData.getName());
}
// i should have this piece of code for methods that are running in the background
runOnUiThread(new Runnable() {
#Override
public void run() {
schoolspinner.setAdapter(new ArrayAdapter<String>(Setup.this, android.R.layout.select_dialog_item, listschools));
}
});
return Response.success(list_response.toString(), HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
public void getclasses(){
final Spinner classspinner = (Spinner) findViewById(R.id.classname);
try {
RequestQueue requestQueue = Volley.newRequestQueue(getApplicationContext());
String URL = "http://192.168.0.148/Election/api/classes";
JSONObject jsonBody = new JSONObject();
// jsonBody.put("tblRegisteredUsers_nickName", username.getText().toString().trim());
jsonBody.put("SchoolFK_ID", cityid);
final String requestBody = jsonBody.toString();
StringRequest stringRequest = new StringRequest(Request.Method.POST, URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
//my response later should be changed
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("VOLLEY", error.toString());
}
})
{
#Override
public String getBodyContentType() {
return "application/json; charset=utf-8";
}
#Override
public byte[] getBody() throws AuthFailureError {
try {
return requestBody == null ? null : requestBody.getBytes("utf-8");
} catch (UnsupportedEncodingException uee) {
VolleyLog.wtf("Unsupported Encoding while trying to get the bytes of %s using %s", requestBody, "utf-8");
return null;
}
}
#Override
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString;
String json = null;
try {
json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
responseString = String.valueOf(json).trim();
ArrayList<ClassResponse> list_response = new ArrayList<ClassResponse>();
Type listType = new TypeToken<List<ClassResponse>>() {}.getType();
list_response = new Gson().fromJson(responseString, listType);
for (int i = 0; i < list_response.size(); i++) {
School listItemData = new School();
listItemData.setName(list_response.get(i).getNameAr());
listItemData.setId(list_response.get(i).getPKID());
classID.add(listItemData.getId());
listclasses.add(listItemData.getName());
}
// i should have this piece of code for methods that are running in the background
runOnUiThread(new Runnable() {
#Override
public void run() {
classspinner.setAdapter(new ArrayAdapter<String>(Setup.this, android.R.layout.select_dialog_item, listclasses));
}
});
// String Check = yourModel.getMessagetitle();
return Response.success(list_response.toString(), HttpHeaderParser.parseCacheHeaders(response));
}
};
requestQueue.add(stringRequest);
} catch (JSONException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
and here is the area I'm talking about
where only the string list (listclasses) is storing data while the integer (classID) list does not
protected Response<String> parseNetworkResponse(NetworkResponse response) {
String responseString;
String json = null;
try {
json = new String(response.data, HttpHeaderParser.parseCharset(response.headers));
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
responseString = String.valueOf(json).trim();
ArrayList<ClassResponse> list_response = new ArrayList<ClassResponse>();
Type listType = new TypeToken<List<ClassResponse>>() {}.getType();
list_response = new Gson().fromJson(responseString, listType);
for (int i = 0; i < list_response.size(); i++) {
School listItemData = new School();
listItemData.setName(list_response.get(i).getNameAr());
listItemData.setId(list_response.get(i).getPKID());
classID.add(listItemData.getId());
listclasses.add(listItemData.getName());
}
// i should have this piece of code for methods that are running in the background
runOnUiThread(new Runnable() {
#Override
public void run() {
classspinner.setAdapter(new ArrayAdapter<String>(Setup.this, android.R.layout.select_dialog_item, listclasses));
}
});
// String Check = yourModel.getMessagetitle();
return Response.success(list_response.toString(), HttpHeaderParser.parseCacheHeaders(response));
}
};
hope I get right answer
thanks in advance
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
means that your Array is empty and you are trying to access array element from an empty array.
You can put a condition to check if array length is more than 0 and then proceed using it like:
if(array != null && array.length > 0){
// do parsing
}
Make sure your class School contains variable with name pK_ID. Look carefully on the upper/lower cases in the variable name.
If the variable name is not matching with JSON tag then this will result in empty fetching from JSON, even if you are getting valid JSON from URL as per your comment.
Related
server data
android data
I am passing arraylist of srid of all element and post to server using volley request.enter image description here
here is the code
public class AttendenceShowStdList extends AppCompatActivity {
ActivityAttendenceShowStdListBinding AttendenceShowStdList;
ArrayList<AttStdListModel> userlist = new ArrayList<>();
ArrayList<AllStdListsrIdAdmIdModel> list= new ArrayList<>();
ArrayList<AllStdListModel> stdlist = new ArrayList<>();
AttStdListAdapter adapter;
private DatePickerDialog datePickerDialog;
private String date,clid,sectionId,yrId,instId,usid,usType,attdate;
SharedPreferences sharedPreferences_teach;//staff shareprefferece for profile fetch
private static final String SHARED_PREF_NAME_TEACH="myprefteach";
private static final String Key_USID_TEACH = "techusid";
private static final String Key_INSTID_TEACH = "techinstid";
private static final String Key_USTYPE_TEACH = "techustype";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
AttendenceShowStdList= ActivityAttendenceShowStdListBinding.inflate(getLayoutInflater());
setContentView(AttendenceShowStdList.getRoot());
sharedPreferences_teach =getSharedPreferences(SHARED_PREF_NAME_TEACH, Context.MODE_PRIVATE);
instId=sharedPreferences_teach.getString(Key_INSTID_TEACH,null);
usid=sharedPreferences_teach.getString(Key_USID_TEACH,null);
usType=sharedPreferences_teach.getString(Key_USTYPE_TEACH,null);
//getting data from TakeAttendenceAdapter cardview
clid=getIntent().getExtras().getString("ClassId");
sectionId=getIntent().getExtras().getString("sectionId");
Log.d("cliddd",clid);
yrId=getIntent().getExtras().getString("YearId");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
date = sdf.format(new Date());
Log.d("dttt",date);
userlist = (ArrayList<AttStdListModel>) getModel(false);
adapter = new AttStdListAdapter(this,userlist);
AttendenceShowStdList.rvstdlist.setAdapter(adapter);
AttendenceShowStdList.rvstdlist.setLayoutManager(new LinearLayoutManager(getApplicationContext(), LinearLayoutManager.VERTICAL, false));
// recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
// recyclerView.setHasFixedSize(true);
getData();
//toolbar
setSupportActionBar(AttendenceShowStdList.toolbar);
Objects.requireNonNull(getSupportActionBar()).setDisplayShowHomeEnabled(true);
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
AttendenceShowStdList.submit.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
submitAttendence();
// Intent intent = new Intent(AttendenceShowStdList.this,SubmitAttendenceActivity.class);
// startActivity(intent);
}
});
}
private List<AttStdListModel> getModel(boolean isSelect){
List<AttStdListModel> list = new ArrayList<>();
for(int i = 0; i < list.size(); i++){
AttStdListModel model = new AttStdListModel();
model.setSelected(isSelect);
// model.setStud_name(String.valueOf(list.get(i)));
model.setAdmi_id(String.valueOf(list.get(i)));
list.add(model);
}
return list;
}
private void getData() {
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url1="https://comzent.in/wonderschoolerp/apis/teacher/get_studteachers_att.php";
StringRequest request = new StringRequest(Request.Method.POST, url1, new com.android.volley.Response.Listener<String>() {
#SuppressLint("NotifyDataSetChanged")
#Override
public void onResponse(String response) {
// Toast.makeText(getContext(), "Data added to API", Toast.LENGTH_SHORT).show();
try {
JSONObject respObj = new JSONObject(response);
JSONArray jsonArray5=respObj.getJSONArray("studatt_details");
Log.d("std details",jsonArray5.toString());
for(int i=0;i<jsonArray5.length();i++){
JSONObject jsonObject=jsonArray5.getJSONObject(i);
String sr_id=jsonObject.optString("sr_id");
String admi_id=jsonObject.optString("admi_id");
String stud_name=jsonObject.optString("stud_name");
String stud_phone=jsonObject.optString("stud_phone");
String stud_email=jsonObject.optString("stud_email");
String attd_status=jsonObject.optString("attd_status");
String attd_reason=jsonObject.optString("attd_reason");
userlist.add(new AttStdListModel(sr_id,admi_id,stud_name,stud_phone,stud_email,
attd_status,attd_reason));
Log.d("s", String.valueOf(userlist));
list.add(new AllStdListsrIdAdmIdModel(sr_id,admi_id,stud_name,stud_phone,stud_email,
attd_status,attd_reason));
}
} catch (JSONException e) {
e.printStackTrace();
}
adapter=new AttStdListAdapter(getApplicationContext(),userlist);
AttendenceShowStdList.rvstdlist.setAdapter(adapter);
adapter.notifyDataSetChanged();
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Fail to get response = " + error, Toast.LENGTH_SHORT).show();
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("get_studattd","1");
params.put("us_id",usid);
params.put("inst_id",instId);
params.put("class_id",clid);
params.put("sec_id",sectionId);
params.put("ay_id",yrId);
params.put("stud_attend_date",date);
return params;
}
};
queue.add(request);
}
//submit attendence
private void submitAttendence() {
RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
String url1="https://comzent.in/wonderschoolerp/apis/teacher/take_studteacher_att.php";
StringRequest request = new StringRequest(Request.Method.POST, url1, new com.android.volley.Response.Listener<String>() {
#Override
public void onResponse(String response) {
// Toast.makeText(getContext(), "Data added to API", Toast.LENGTH_SHORT).show();
try {
JSONObject respObj = new JSONObject(response);
String msg=respObj.getString("message");
Toast.makeText(AttendenceShowStdList.this, msg, Toast.LENGTH_LONG).show();
Log.d("response msg",msg);
if(msg.equals("Attendance Generated Successfully..!")){
finish();
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "Fail to get response = " + error, Toast.LENGTH_LONG).show();
Log.d("error msg", String.valueOf(error));
}
}) {
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
ArrayList<String> allstdsrid = new ArrayList<String>();
for(int i=0; i < list.size(); i++) {
allstdsrid.add(String.valueOf(list.get(i).getSr_id()));
}
params.put("sr_id", String.valueOf(allstdsrid));
Log.d("params", String.valueOf(params));
Log.d("allstudentsrid", String.valueOf(allstdsrid));
ArrayList<String> allstdadmid = new ArrayList<String>();
for(int i=0; i < list.size(); i++) {
allstdadmid.add(list.get(i).getAdmi_id());
params.put("admission_id", String.valueOf(allstdadmid));
}
Log.d("allstudentsadmid", String.valueOf(allstdadmid));
///selected student list
ArrayList<String> attstd = new ArrayList<String>();
for (int i = 0; i < AttStdListAdapter.userlist.size(); i++) {
if (AttStdListAdapter.userlist.get(i).getSelected()) {
attstd.add(AttStdListAdapter.userlist.get(i).getAdmi_id());
}
}
params.put("student_attend_submit","1");
params.put("class_id",clid);
params.put("sec_id",sectionId);
params.put("ay_id",yrId);
params.put("att_status", String.valueOf(attstd));
Log.d("params", String.valueOf(params));
params.put("stud_attend_date",date);
params.put("inst_id",instId);
params.put("us_id",usid);
params.put("us_type",usType);
return params;
}
};
queue.add(request);
}
//toolbar back to home
public boolean onOptionsItemSelected(#NonNull MenuItem item) {
if(item.getItemId()==android.R.id.home){
finish();
}
return super.onOptionsItemSelected(item);
}
}
After submitting attendance, values of array of srid and admid retrive at server correctly ,problem is that only first record's srid and admid sets to '0' value.There is no problem when same Api is fetch on postman.
I am new in android I work on a webservice application and the backend in laravel ,I want to read the trades and according to the job I find the tasks but I can not display the data it shows me this error msg ..
"org.json.JSONArray cannot be converted to JSONObject"
public static final String TacheNamearray = "libelle_tache";
public static final String TacheName = "libelle_tache";
public static final String JSON_ARRAY_TACHE = "result";
public static final String MetierNamearray = "libelle_metier";
public static final String MetierName = "libelle_metier";
public static final String JSON_ARRAY = "result";
private JSONArray result;
private ArrayList<String> arrayListTache;
TextView tacheename;
Spinner spinner_tache;
Spinner spinner;
Button button;
private GpsTracker gpsTracker;
private TextView tvLatitude,tvLongitude;
String URL_Post = "http://192.168.1.233/projet/public/api/getmetier";
private ArrayList<String> arrayList;
TextView employeename;
private TextView tvUsername, tvEmail;
private UserInfo userInfo;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_recherche);
spinner= (Spinner) findViewById(R.id.spnrEmployee);
spinner_tache= (Spinner) findViewById(R.id.spnrTache);
tacheename= (TextView) findViewById(R.id.tvTache);
employeename= (TextView) findViewById(R.id.tvName);
button = (Button) findViewById(R.id.button);
tvLatitude = (TextView)findViewById(R.id.latitude);
tvLongitude = (TextView)findViewById(R.id.longitude);
arrayListTache = new ArrayList<String>();
userInfo = new UserInfo(this);
tvEmail = (TextView)findViewById(R.id.key_email);
String email = userInfo.getKeyEmail();
tvEmail.setText(email);
arrayList = new ArrayList<String>();
getMetiers();
spinner.setOnItemSelectedListener(new
AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int
position, long id) {
//Setting the values to textviews for a selected item
String metier= arrayList.get(position);
getTaches(metier);
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
employeename.setText("");
}
});
}
private void getMetiers() {
StringRequest stringRequest = new
StringRequest("http://192.168.1.233/projet/public/api/getmetier",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
j = new JSONObject(response);
result = j.getJSONArray(JSON_ARRAY);
empdetails(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void empdetails(JSONArray j) {
for (int i = 0; i < j.length(); i++) {
try {
JSONObject json = j.getJSONObject(i);
arrayList.add(json.getString(MetierNamearray));
} catch (JSONException e) {
e.printStackTrace();
}
}
// arrayList.add(0,"Select Employee");
spinner.setAdapter(new ArrayAdapter<String>(RechercheActivity.this,
android.R.layout.simple_spinner_dropdown_item, arrayList));
}
//Method to get student name of a particular position
private String getemployeeName(int position){
String name="";
try {
//Getting object of given index
JSONObject json = result.getJSONObject(position);
//Fetching name from that object
name = json.getString(MetierName);
} catch (JSONException e) {
e.printStackTrace();
}
//Returning the name
return name;
}
public void getLocation(View view){
gpsTracker = new GpsTracker(RechercheActivity.this);
insert();
if(gpsTracker.canGetLocation()){
double latitude = gpsTracker.getLatitude();
double longitude = gpsTracker.getLongitude();
tvLatitude.setText(String.valueOf(latitude));
tvLongitude.setText(String.valueOf(longitude));
}else{
gpsTracker.showSettingsAlert();
}
Intent intent = new Intent(RechercheActivity.this,
TechnicienActivity.class);
startActivity(intent);
}
public void insert(){
StringRequest stringRequest = new StringRequest(Request.Method.POST,
URL_Post, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Toast.makeText(getApplication(),response,Toast.LENGTH_LONG).show();
}
}, new ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(RechercheActivity.this,error+"",Toast.LENGTH_LONG).show();
}
}
){
#Override
protected Map<String,String>getParams()throws AuthFailureError {
Map<String,String> params = new HashMap<String,String>();
String text1 = spinner.getSelectedItem().toString();
String lon = tvLongitude.getText().toString().trim();
String lat = tvLatitude.getText().toString().trim();
params.put("libelle_metier",text1);
return params;
}
};
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void getTaches(String metier) {
StringRequest stringRequest = new
StringRequest("http://192.168.1.233/projet/public/api/gettaches",
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
j = new JSONObject(response);
result= j.getJSONArray(JSON_ARRAY_TACHE);
tachedetails(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void tachedetails(JSONArray j) {
for (int i = 0; i < j.length(); i++) {
try {
JSONObject json = j.getJSONObject(i);
arrayListTache.add(json.getString(TacheNamearray));
} catch (JSONException e) {
e.printStackTrace();
}
// arrayListTache.add(0,"Select Employee");
spinner_tache.setAdapter(new ArrayAdapter<String>
(RechercheActivity.this,
android.R.layout.simple_spinner_dropdown_item, arrayListTache));
}
//Method to get student name of a particular position
private String gettacheName(int position){
String libelle_tache="";
try {
//Getting object of given index
JSONObject json = result.getJSONObject(position);
//Fetching name from that object
libelle_tache = json.getString(TacheName);
} catch (JSONException e) {
e.printStackTrace();
}
//Returning the name
return libelle_tache;
}
and the JSON part gives me that ..
[{"id":1,"libelle_metier":"metier 1","deleted_at":null,"created_at":"2018-04-03 09:12:37","updated_at":"2018-04-03 09:12:37"},{"id":2,"libelle_metier":"metier 2","deleted_at":null,"created_at":"2018-04-03 09:12:44","updated_at":"2018-04-03 09:12:44"},{"id":3,"libelle_metier":"metier 4","deleted_at":null,"created_at":"2018-04-03 09:46:36","updated_at":"2018-04-04 14:15:06"}]
and my PHP code and
class TechniciensController extends Controller
{
public function GetTechniciens()
{
return Technicien::all();
}
return json_encode(Technicien::all());
then you can use json_decode.
this line :
j = new JSONObject(response);
update it:
JSONArray jsonarray = new JSONArray(response);
i think it's works.
I am new to android. I need to pass values from the spinner to asynctask as an parameter and till now I am successful in showing the results in spinner successfully. Now i need to pass the selected value from the spinner to another activity on a button click (as an parameter to asynctask). Below is the code. Thanks in advance.
BackgroundFetchWorker.java:
public class BackgroundFetchWorker extends AsyncTask<String,Void,String> {
String json_string;
ProgressDialog progressDialog;
Context context;
BackgroundFetchWorker(Context ctx)
{
context = ctx;
}
#Override
protected String doInBackground(String... params) {
String type2 = params[0];
String student_fetch_url = "http://pseudoattendance.pe.hu/studentFetch.php";
if (type2.equals("fetchSubject")) {
try {
String semester = params[1];
String stream = params[2];
URL url = new URL(student_fetch_url);
HttpURLConnection httpURLConnection = (HttpURLConnection) url.openConnection();
httpURLConnection.setRequestMethod("POST");
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoOutput(true);
OutputStream outputStream = httpURLConnection.getOutputStream();
BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(outputStream, "UTF-8"));
String post_data = URLEncoder.encode("semester", "UTF-8") + "=" + URLEncoder.encode(semester, "UTF-8")
+ URLEncoder.encode("stream","UTF-8")+"="+URLEncoder.encode(stream,"UTF-8");
bufferedWriter.write(post_data);
bufferedWriter.flush();
bufferedWriter.close();
outputStream.close();
InputStream inputStream = httpURLConnection.getInputStream();
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(inputStream, "iso-8859-1"));
String result = " ";
String line = "";
while ((line = bufferedReader.readLine()) != null) {
result += line;
}
bufferedReader.close();
inputStream.close();
httpURLConnection.disconnect();
return result;
} catch (IOException e) {
e.printStackTrace();
}
}
return null;
}
#Override
protected void onPreExecute() {
progressDialog = new ProgressDialog(context);
progressDialog.setTitle("Fetching Data....");
progressDialog.setMessage("This may take a while..");
progressDialog.show();
}
#Override
protected void onPostExecute(String result) {
progressDialog.dismiss();
String s = result.trim();
if(s.equals("{\"result\":[]}")){
Toast.makeText(context, "ERROR OCCURED", Toast.LENGTH_SHORT).show();
}
else {
json_string = result;
Intent i = new Intent(context, TakeAttendanceActivity.class);
i.putExtra("studentdata", json_string);
context.startActivity(i);
Toast.makeText(context, "Success", Toast.LENGTH_SHORT).show();
}
}
#Override
protected void onProgressUpdate(Void... values) {
super.onProgressUpdate(values);
}
}
FacultyWelcomeActivity.java:
public class FacultyWelcomeActivity extends AppCompatActivity implements Spinner.OnItemSelectedListener{
String JSON_STRING;
JSONObject jsonObject;
JSONArray jsonArray;
ContactAdapter contactAdapter;
ListView listView;
//Declaring an Spinner
private Spinner spinner;
private Spinner spinner1;
//An ArrayList for Spinner Items
private ArrayList<String> students;
private ArrayList<String> stream;
//JSON Array
private JSONArray result;
private JSONArray result1;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_faculty_welcome);
//Initializing the ArrayList
students = new ArrayList<String>();
stream = new ArrayList<String>();
//Initializing Spinner
spinner = (Spinner) findViewById(R.id.spinner);
spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
String semesters= parent.getItemAtPosition(position).toString();
String stream= parent.getItemAtPosition(position).toString();
}
#Override
public void onNothingSelected(AdapterView<?> parent) {
}
});
spinner1 = (Spinner) findViewById(R.id.spinner1);
//Adding an Item Selected Listener to our Spinner
//As we have implemented the class Spinner.OnItemSelectedListener to this class iteself we are passing this to setOnItemSelectedListener
getData();
getData1();
listView = (ListView) findViewById(R.id.lectureList);
contactAdapter = new ContactAdapter(this, R.layout.rowlayout);
listView.setAdapter(contactAdapter);
JSON_STRING = getIntent().getExtras().getString("JSON Data");
try {
jsonObject = new JSONObject(JSON_STRING);
jsonArray = jsonObject.getJSONArray("result");
int count = 0;
String sub1, sub2, sub3, sub4;
while (count < jsonArray.length()) {
JSONObject JO = jsonArray.getJSONObject(count);
sub1 = JO.getString("fname");
sub2 = JO.getString("lname");
sub3 = JO.getString("id");
sub4 = JO.getString("email");
Contacts contacts = new Contacts(sub1, sub2, sub3, sub4);
contactAdapter.add(contacts);
count++;
}
} catch (JSONException e) {
e.printStackTrace();
}
}
public void fetchSubject(View view) {
String type2 = "fetchSubject";
String spinnerdata = spinner.getSelectedItem().toString();
String spinner1data = spinner1.getSelectedItem().toString();
BackgroundFetchWorker background = new BackgroundFetchWorker(this);
background.execute(type2,spinnerdata,spinner1data);
}
private void getData1(){
StringRequest stringRequest = new StringRequest(Config2.DATA_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
//Storing the Array of JSON String to our JSON Array
result1 = j.getJSONArray(Config2.JSON_ARRAY);
getStudents1(result1);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void getData(){
StringRequest stringRequest = new StringRequest(Config.DATA_URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
JSONObject j = null;
try {
//Parsing the fetched Json String to JSON Object
j = new JSONObject(response);
result = j.getJSONArray(Config.JSON_ARRAY);
getStudents(result);
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
RequestQueue requestQueue = Volley.newRequestQueue(this);
requestQueue.add(stringRequest);
}
private void getStudents(JSONArray j){
for(int i=0;i<j.length();i++){
try {
//Getting json object
JSONObject json = j.getJSONObject(i);
students.add(json.getString(Config.TAG_SEMESTER));
} catch (JSONException e) {
e.printStackTrace();
}
}
spinner.setAdapter(new ArrayAdapter<String>(FacultyWelcomeActivity.this, android.R.layout.simple_spinner_dropdown_item, students));
}
private void getStudents1(JSONArray j){
//Traversing through all the items in the json array
for(int i=0;i<j.length();i++){
try {
//Getting json object
JSONObject json = j.getJSONObject(i);
//Adding the name of the student to array list
stream.add(json.getString(Config2.TAG_STREAM));
} catch (JSONException e) {
e.printStackTrace();
}
}
spinner1.setAdapter(new ArrayAdapter<String>(FacultyWelcomeActivity.this, android.R.layout.simple_spinner_dropdown_item, stream));
}
#Override
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
//check which spinner triggered the listener
}
#Override
public void onNothingSelected(AdapterView<?> parent) {}}
You are passing parameters to doInBackground() this way:
background.execute("your string");
Now the string "your string" will be the parameter within doInBackground() callback:
#Override
protected String doInBackground(String... params) {
String type2 = params[0]; // type2 == "your string"
...
}
See docs for more info.
I'm posting "id" value (which i pass to this activity via getintent)
Uid = getIntent().getStringExtra("id");
to server and retrieving the corresponding jsonobjects.
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", Uid);
return params;
}
When my jsonarray is empty, my app crashes. I want to toast"Error" when jsonarray is empty. How can I fix this?
Here is my code:
public class kill extends FragmentActivity {
GridView grid1;
CustomGrid_Album adapter;
private ProgressDialog pDialog;
String Uid,Disp;
public String category;
public String selected;
public static String imagename;
Button Alb_sel;
ArrayList<Item_album> gridArray = new ArrayList<Item_album>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.album_display);
grid1 = (GridView) findViewById(R.id.gridView2);
Uid = getIntent().getStringExtra("id");
Disp = getIntent().getStringExtra("disp");
Alb_sel=(Button)findViewById(R.id.album_to_select);
pDialog = new ProgressDialog(kill.this);
pDialog.setMessage("Loading...");
pDialog.show();
//fetching JSONArray
final RequestQueue queue = Volley.newRequestQueue(getApplicationContext());
StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.POST, AppConfig.URL_Gallery4,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Datas.imageIds = new String[response.length()];
JSONArray arr = null;
try {
arr = new JSONArray(response);
} catch (JSONException e1) {
e1.printStackTrace();
}
int i=0;
for (i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
category = obj.getString("category_name");
selected = obj.getString("album_id");
imagename = obj.getString("org_image_name");
Datas.imageIds[i] = AppConfig.URL_IMAGE_temp+obj.getString("album_image").substring(3);
gridArray.add(new Item_album(Datas.imageIds[i]));
} catch (JSONException e) {
e.printStackTrace();
}
}
final int xl = i;
adapter = new CustomGrid_Album(kill.this,xl,gridArray);
adapter.notifyDataSetChanged();
grid1.setAdapter(adapter);
pDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "No images in this gallery", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
})
{
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", Uid);
return params;
}
};
queue.add(stringRequest);
}
}
apply the check in onResponse
if(response.length()==0){
// error message
}else{
// your rest of the code
}
This looks problematic.
Datas.imageIds = new String[response.length()];
You don't want an array with the size of the string. You want an array of the size of the JSONArray within the response.
public void onResponse(String response) {
JSONArray arr = null;
try {
arr = new JSONArray(response);
Datas.imageIds = new String[arr.length()];
} catch (JSONException e1) {
e1.printStackTrace();
}
However, your code is going to continue on if an exception is thrown there, then you'll end up with a NullPointerException, so you should move the for-loop into the try-catch as well.
Realistically, though, you should just use a JSONArrayRequest if you're going to be expecting a JSONArray.
i want to toast"Error" when jsonarray is empty
Simple enough.
arr = new JSONArray(response);
if (arr.length() == 0) {
// TODO: Toast
}
I would simply add two checks to your onResponse method:
...
public void onResponse(String response) {
// Check if the response itself is an empty string or null
if(TextUtils.isEmpty(response)) {
// Show your user feedback
return;
}
Datas.imageIds = new String[response.length()];
JSONArray arr = null;
try {
arr = new JSONArray(response);
// Check if your JSON has no elements in it
if(arr.length == 0) {
// Show your user feedback
return;
}
} catch (JSONException e1) {
e1.printStackTrace();
}
...
You have declared JSONArray arr = null;
After that you assign the server's JSON to that JSONArray.
Add a line after getting that
if(arr==null)
{
//toast
}
else
{
//whatever you want to do with JSON
}
StringRequest stringRequest = new StringRequest(com.android.volley.Request.Method.POST, AppConfig.URL_Gallery4,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(response.length()==0){
Toast.makeText(getActivity(),"no data found",Toast.LENGTH_SHORT).show();
}
else{
Datas.imageIds = new String[response.length()];
JSONArray arr = null;
try {
arr = new JSONArray(response);
} catch (JSONException e1) {
e1.printStackTrace();
}
if(arr.length()>0){
int i=0;
for (i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
category = obj.getString("category_name");
selected = obj.getString("album_id");
imagename = obj.getString("org_image_name");
Datas.imageIds[i] = AppConfig.URL_IMAGE_temp+obj.getString("album_image").substring(3);
gridArray.add(new Item_album(Datas.imageIds[i]));
} catch (JSONException e) {
e.printStackTrace();
}
}
final int xl = i;
adapter = new CustomGrid_Album(kill.this,xl,gridArray);
adapter.notifyDataSetChanged();
grid1.setAdapter(adapter);
}else{
Toast.makeText(getActivity(),"no data found",Toast.LENGTH_SHORT).show();
}
}
pDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), "No images in this gallery", Toast.LENGTH_SHORT).show();
error.printStackTrace();
}
})
{
#Override
protected Map<String, String> getParams() {
Map<String, String> params = new HashMap<String, String>();
params.put("id", Uid);
return params;
}
};
Use the below code to check whether response is null or not and in object check whether it is having key or data with key is not null
if(response!=null){
try {
Datas.imageIds = new String[response.length()];
JSONArray arr = new JSONArray(response);
for (int i = 0; i < arr.length(); i++) {
try {
JSONObject obj = arr.getJSONObject(i);
if(obj!=null){
if(obj.has("category_name") && !obj.isNull("category_name"){
category = obj.getString("category_name");
}
if(obj.has("album_id") && !obj.isNull("album_id"){
selected = obj.getString("album_id");
}
if(obj.has("org_image_name") && !obj.isNull("org_image_name"){
imagename = obj.getString("org_image_name");
}
if(obj.has("album_image") && !obj.isNull("album_image"){
Datas.imageIds[i] = AppConfig.URL_IMAGE_temp+obj.getString("album_image").substring(3);
gridArray.add(new Item_album(Datas.imageIds[i]));
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
final int xl = i;
adapter = new CustomGrid_Album(kill.this,xl,gridArray);
adapter.notifyDataSetChanged();
grid1.setAdapter(adapter);
pDialog.dismiss();
} catch (JSONException e1) {
e1.printStackTrace();
}
}
You are using StringRequest, instead of that use JsonArrayRequest to make request as below, so you will get response in onResponse methode when there is a valid JSONArray in response, and if there is no data then you will get response in onError method
JsonArrayRequest rReq = new JsonArrayRequest(Request.Method.GET,"url", new JSONObject(), new Response.Listener() {
#Override
public void onResponse(JSONArray response) {
Log.e(TAG, "onResponse: "+response.toString() );
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e(TAG, "onErrorResponse: "+error.getMessage() );
}
})
in my cache mechanism after add the request to the RequestQueue and try to fetch data from server, my cache method return multi duplicate result from server return json string
RequestQueue queue = Volley.newRequestQueue(this);
String url = Globals.getHostAddress() + "/get_latest_video";
items.clear();
CacheRequest cacheRequest = new CacheRequest(0, url, new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
try {
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
Log.e("allVideos", jsonString);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
// Add the request to the RequestQueue.
queue.add(cacheRequest);
server return this result:
{"id":12,"channel_id":7,"category_id":8}
Cache mechanism return :
{"id":12,"channel_id":7,"category_id":8},{"id":12,"channel_id":7,"category_id":8}
whats my code problem to cache data and using that?
CacheRequest class content:
public class CacheRequest extends Request<NetworkResponse> {
private final Response.Listener<NetworkResponse> mListener;
private final Response.ErrorListener mErrorListener;
public CacheRequest(int method, String url, Response.Listener<NetworkResponse> listener, Response.ErrorListener errorListener) {
super(method, url, errorListener);
this.mListener = listener;
this.mErrorListener = errorListener;
}
#Override
protected Response<NetworkResponse> parseNetworkResponse(NetworkResponse response) {
Cache.Entry cacheEntry = HttpHeaderParser.parseCacheHeaders(response);
if (cacheEntry == null) {
cacheEntry = new Cache.Entry();
}
final long cacheHitButRefreshed = 3 * 60 * 1000; // in 3 minutes cache will be hit, but also refreshed on background
final long cacheExpired = 24 * 60 * 60 * 1000; // in 24 hours this cache entry expires completely
long now = System.currentTimeMillis();
final long softExpire = now + cacheHitButRefreshed;
final long ttl = now + cacheExpired;
cacheEntry.data = response.data;
cacheEntry.softTtl = softExpire;
cacheEntry.ttl = ttl;
String headerValue;
headerValue = response.headers.get("Date");
if (headerValue != null) {
cacheEntry.serverDate = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
headerValue = response.headers.get("Last-Modified");
if (headerValue != null) {
cacheEntry.lastModified = HttpHeaderParser.parseDateAsEpoch(headerValue);
}
cacheEntry.responseHeaders = response.headers;
return Response.success(response, cacheEntry);
}
#Override
protected void deliverResponse(NetworkResponse response) {
mListener.onResponse(response);
}
#Override
protected VolleyError parseNetworkError(VolleyError volleyError) {
return super.parseNetworkError(volleyError);
}
#Override
public void deliverError(VolleyError error) {
mErrorListener.onErrorResponse(error);
}
}
UPDATED POST:
public class ActivityBootstrap extends Activity implements AdapterView.OnItemClickListener {
#InjectView(R.id.drawer_list)
ListView drawer_list;
#InjectView(R.id.drawer_layout)
DrawerLayout drawer_layout;
#InjectView(R.id.listView)
AsymmetricGridView listView;
private List<DrawerItem> drawer_items = new ArrayList<DrawerItem>();
private List<VideoItems> items = new ArrayList<>();
private DrawerAdatper drawer_adatper = null;
private boolean mDrawerState = false;
private VideoAdapter adapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ButterKnife.inject(this);
RequestQueue queue = Volley.newRequestQueue(this);
String url = Globals.getHostAddress() + "/get_latest_video";
items.clear();
CacheRequest cacheRequest = new CacheRequest(0, url, new Response.Listener<NetworkResponse>() {
#Override
public void onResponse(NetworkResponse response) {
try {
final String jsonString = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
Log.e("allVideos", jsonString);
JSONArray jsonArray = new JSONArray(jsonString);
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject video_single_item = jsonArray.getJSONObject(i);
int video_id = video_single_item.getInt("id");
String video_thumbnail = video_single_item.getString("thumbnail");
int colSpan = Math.random() < 0.2f ? 2 : 1;
int rowSpan = colSpan;
VideoItems item = new VideoItems(colSpan, rowSpan, video_thumbnail,video_id);
items.add(item);
}
setUpListView(items);
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
// Add the request to the RequestQueue.
queue.add(cacheRequest);
}
private void setUpListView(List video_array_items) {
final List<AsymmetricItem> items = new ArrayList<>();
adapter = new VideoListAdapter(this, video_array_items);
AsymmetricGridViewAdapter asymmetricAdapter =
new AsymmetricGridViewAdapter<>(this, listView, adapter);
listView.setAdapter(asymmetricAdapter);
listView.setRequestedColumnCount(3);
listView.setAdapter(getNewAdapter());
listView.setOnItemClickListener(this);
listView.setAllowReordering(true);
listView.isAllowReordering();
}
private AsymmetricGridViewAdapter<?> getNewAdapter() {
return new AsymmetricGridViewAdapter<>(this, listView, adapter);
}
#Override
public void onItemClick(AdapterView<?> adapterView, View view, int position, long id) {
int video_position = items.get(position).getVideo_id();
Intent intent = new Intent(ActivityBootstrap.this, ActivitySHowVideoDetaile.class);
intent.putExtra("video_id", video_position);
startActivity(intent);
}
}
UPDATED POST 2)
Result of Log.e("allVideos", jsonString); is :
10-28 09:51:46.016 17872-17872/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
10-28 09:51:47.249 17872-17872/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
Result of server response i'm test it with browser:
[{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
UNFORTUNATELY this duplicate result is random(NOT duplicate every time)
UPDATE 3:
10-28 13:14:52.322 16129-16129/pishguy.ir.asrebidree E/Test: onCreate called
10-28 13:14:52.513 16129-16129/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
10-28 13:14:53.206 16129-16129/pishguy.ir.asrebidree E/allVideos: [{"id":12,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"},{"id":10,"thumbnail":"1445615983c92d10f1f3ee907150be1fdb8184ca893178682-360p__19106.png"}]
Because I have commented too many lines and I cannot re-produce "duplication behavior" as your current issue, so I post my answer here, hope this helps!
Inside CacheDispatcher class, you will find the following:
if (!entry.refreshNeeded()) {
// Completely unexpired cache hit. Just deliver the response.
mDelivery.postResponse(request, response);
} else {
// Soft-expired cache hit. We can deliver the cached response,
// but we need to also send the request to the network for
// refreshing.
request.addMarker("cache-hit-refresh-needed");
request.setCacheEntry(entry);
// Mark the response as intermediate.
response.intermediate = true;
// Post the intermediate response back to the user and have
// the delivery then forward the request along to the network.
mDelivery.postResponse(request, response, new Runnable() {
#Override
public void run() {
try {
mNetworkQueue.put(request);
} catch (InterruptedException e) {
// Not much we can do about this.
}
}
});
}
IMO, it is possible the softTtl that is causing this duplication behavior.
I suggest that you use the following line to setRetryPolicy for your request:
cacheRequest.setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 2, 0, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
// Add the request to the RequestQueue.
queue.add(cacheRequest);