I get the data from API such as printer name, model and status and displaying in the listview in array adapter.In my program I am testing if the printer is idle or not and showing by using green(idle) and red (busy) circles in the listview , but my issue is that the state has to be constantly checked and get updated to display on screen green or red circle, for this case I was checking out into handler and timers and tried to implement it but unsuccessfully - nothing worked. I am unsure which one is better to use and how , since I am using array adapter.
If you have any insights, please let me know.
My adapter class:
public class NsdServiceInfoAdapter extends ArrayAdapter<PrinterNew> {
private Context mContext;
private List<PrinterNew> services;
private InetAddress hostAddress;
//Creating new constructor with parameters such as this class(context), layout id (list item layout Id) and data model.
public NsdServiceInfoAdapter(#NonNull Context context, int layoutId, List<PrinterNew> list) {
super(context, layoutId, list);
mContext = context;
services = list;
}
#NonNull
#Override
public View getView(int position, #Nullable View convertView, #NonNull
ViewGroup parent) {
View listItem = convertView;
//Checking if view is empty then we inflate our list layout.
if (listItem == null)
listItem =
LayoutInflater.from(mContext).inflate(R.layout.list_item, parent, false);
//Getting data's position in the data set.
final PrinterNew currentService = services.get(position);
final ImageView i = listItem.findViewById(R.id.status_circle);
TextView t = listItem.findViewById(R.id.TextView_serviceName);
final TextView r = listItem.findViewById(R.id.TextView_serviceIP);
r.setText(currentService.getPrinterModel());
t.setText(currentService.getPrinterName());
if (currentService.isIdle()) {
i.setColorFilter(Color.rgb(42, 187, 155));
} else {
i.setColorFilter(Color.rgb(240, 52, 52));
}
return listItem;
}
}
My printer class
public PrinterNew() {
}
public String getPrinterName() {
return printerName;
}
public void setPrinterName(String printerName) {
this.printerName = printerName;
}
public String getPrinterModel() {
return printerModel;
}
public String getPrinterInformation() {
return this.printInformation;
}
public void setPrinterInformation(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("API", "Print information" + response);
String temp = response.substring(2, response.length() - 2);
byte msgArray[];
try {
msgArray = temp.getBytes("ISO-8859-1");
state = msgArray[0];
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
printInformation = response;
callback.onSuccess(printInformation);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "Print information nope ");
callback.onFailure(error);
}
}));
}
public String getMenuInformation() {
return menuInformation;
}
public void setMenuInformation(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
String temp = response.substring(2, response.length() - 2);
Log.d("API", "Current menu" + response);
byte msgArray[];
try {
msgArray = temp.getBytes("ISO-8859-1");
currentMenu = msgArray[0];
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
menuInformation = response;
callback.onSuccess(menuInformation);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "Current menu Nope ");
callback.onFailure(error);
}
}));
}
public boolean isIdle() {
if (state == -1 && currentMenu == 0) {
return true;
} else {
return false;
}
}
public void setPrinterService(NsdServiceInfo service) {
this.printerService = service;
}
public NsdServiceInfo getPrinterService() {
return this.printerService;
}
public interface VolleyCallback {
void onSuccess(String result);
void onFailure(Object response);
}
public void setPrinterModel(String url, Context context, final VolleyCallback callback) {
Log.d("API", "Currently calling URL " + url);
RequestQueue queue = Volley.newRequestQueue(context);
queue.add(new StringRequest(Request.Method.GET, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.d("API", "printer model nope ");
callback.onFailure(error);
}
}));
}
}
use recyclerview.
to refresh your list whenever there is data change in the list with recyclerview, you need to user adapter.notifyDataSetChanged()
but catch here is you need to get exact object in the list, the update it then refresh it with above line.
Hope this helps.
Related
I have a query to a mysql database, it asks for all the favorite courses, but first I need to pass the user to it. How could I do that?
file java:
public class FavoritosFragment extends Fragment {
RecyclerView recyclerView;
MyFavoritosRecyclerViewAdapter AdapterFavoritos;
List<Cursos>cursosList;
RequestQueue requestQueue;
// TODO: Customize parameters
private int mColumnCount = 1;
private OnListFragmentInteractionListener mListener;
public FavoritosFragment() {
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.fragment_favoritos_list, container, false);
// Set the adapter
if (view instanceof RecyclerView) {
Context context = view.getContext();
recyclerView = (RecyclerView) view;
if (mColumnCount <= 1) {
recyclerView.setLayoutManager(new LinearLayoutManager(context));
} else {
recyclerView.setLayoutManager(new GridLayoutManager(context, mColumnCount));
}
cursosList=new ArrayList<>();
ejecutarServicio();
obtenerCursos();
//asociamos el adaptador al recyclerview
AdapterFavoritos=new MyFavoritosRecyclerViewAdapter(cursosList, mListener);
recyclerView.setAdapter(AdapterFavoritos);
}
return view;
}
private void ejecutarServicio() {
StringRequest stringRequest = new StringRequest(Request.Method.POST, getResources().getString(R.string.URL_favo) , new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getActivity(), "Error de registro!"+error.toString(), Toast.LENGTH_SHORT).show();
}
}) {
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> params = new HashMap<>();
final String usuario = "avo";
params.put("usu_usuario",usuario);
return params;
}
};
RequestQueue requestQueue= Volley.newRequestQueue(getActivity().getApplicationContext());
requestQueue.add(stringRequest);
}
public void obtenerCursos() {
RequestQueue requestQueue = Volley.newRequestQueue(getActivity().getApplicationContext());
StringRequest stringRequest = new StringRequest(Request.Method.POST, getResources().getString(R.string.URL_favo),
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
try {
JSONObject jsonObject = new JSONObject(response);
JSONArray jsonArray = jsonObject.getJSONArray("Curso");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject jsonObject1 = jsonArray.getJSONObject(i);
boolean add = cursosList.add(
new Cursos(
jsonObject1.getString("id_curso"),
jsonObject1.getString("titulo"),
jsonObject1.getString("descripcion"),
jsonObject1.getString("categoria"),
jsonObject1.getString("imagen")
)
);
}
AdapterFavoritos=new MyFavoritosRecyclerViewAdapter(cursosList, mListener);
recyclerView.setAdapter(AdapterFavoritos);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
}
);
requestQueue.add(stringRequest);
}
#Override
public void onAttach(Context context) {
super.onAttach(context);
if (context instanceof OnListFragmentInteractionListener) {
mListener = (OnListFragmentInteractionListener) context;
} else {
throw new RuntimeException(context.toString()
+ " must implement OnListFragmentInteractionListener");
}
}
#Override
public void onDetach() {
super.onDetach();
mListener = null;
}
public interface OnListFragmentInteractionListener {
// TODO: Update argument type and name
void onListFragmentInteraction(Cursos item);
}
}
this is my php file.
<?php
error_reporting(E_ALL);
ini_set('display_errors', '1');
include 'conexion.php';
$usu_usuario=$_POST['usu_usuario'];
$miDato='';
$consultado="SELECT id_usuario FROM usuario WHERE usu_usuario='".$usu_usuario."'";
$result=mysqli_query($conexion,$consultado);
while($mostrar=mysqli_fetch_array($result)){
$miDato= $mostrar['id_usuario'];
}
// echo $miDato;
$consulta = " SELECT * FROM curso RIGHT JOIN favoritos ON curso.id_curso=favoritos.id_curso WHERE favoritos.id_usuario='".$miDato."'";
$resultado=$conexion->query($consulta);
$datos = array();
while($resultados = $resultado->fetch_assoc()) {
$datos[] = $resultados;
}
//echo json_encode($datos);
echo json_encode(array("Curso" => $datos));
mysqli_query($conexion,$consulta) or die (mysqli_error());
mysqli_close($conexion);
?>
here my two files java and php to the database query ..
I'm desperate you know how angry when the code does not understand me hahaha;)
here my two files java and php to the database query ..
I'm desperate you know how angry when the code does not understand me hahaha;)
what I want is to send the user to the query and volley returns the result, I know how to do it separately but I do not understand how to do that in a single request
I have created a separate class in which I have defined all about volley and in another activity, I have directly pass URL, CONTEXT and Get Response...
but in my NavDrawerActivity.java how do I call the subCategoryJSON(); method without writing my volley code again as I have done with mainCategoryJSON(); method in which I just simply pass the URL, method type.
Also is this a correct approach I am doing or there need to be some modification in the code, what I want is that wherever I am using API in my project and using volley for it, I don't have to write code again and again just simply pass the URL,method type
VolleyResponseListener.java
public interface VolleyResponseListener {
void onResponse(String response, String tag);
void onError(VolleyError error, String tag);
}
CustomStringRequestVolley.java
public class CustomStringRequestVolley {
private String url;
private String tag;
Context ctx;
private VolleyResponseListener volleyResponseListener;
public CustomStringRequestVolley(String url, String tag,Context ctx,VolleyResponseListener volleyResponseListener){
this.url = url;
this.tag = tag;
this.ctx=ctx;
this.volleyResponseListener = volleyResponseListener;
sendRequest();
}
private void sendRequest() {
final ProgressDialog pDialog = new ProgressDialog(ctx);
pDialog.setMessage("Loading ...");
pDialog.show();
StringRequest stringRequest = new StringRequest(Request.Method.GET,url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.e("catresponse", "response " + response);
if (pDialog.isShowing()) {
pDialog.dismiss();
}
volleyResponseListener.onResponse(response, tag);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
stringRequest.setRetryPolicy(new DefaultRetryPolicy(
5000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
VolleySingleton.getInstance(ctx).addToRequestQueue(stringRequest);
}
}
NavDrawerActivity.java
public class NavDrawerActivity extends AppCompatActivity
implements NavigationView.OnNavigationItemSelectedListener, VolleyResponseListener {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_nav_drawer);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
mainCategoryJSON();
subCategoryJSON();
}
private void mainCategoryJSON() {
CustomStringRequestVolley request1 = new CustomStringRequestVolley(URLs.categoryURL, "TAG1", this, this);
}
#Override
public void onResponse(String response, String tag) {
switch (tag) {
case "TAG1":
try {
Log.i("Responseeeeeezaq :", response.toString() + " " + tag);
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("categories");
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
CategoryModelClass categoryModelClass = new CategoryModelClass();
categoryModelClass.setCategoryID(productObject.getInt("Category-Id"));
categoryModelClass.setCategoryName(productObject.getString("Category-Name"));
categoryModelClass.setCategoryImg(productObject.getString("Category-Image"));
categoryArrayList.add(categoryModelClass);
Log.d("zpuyi", String.valueOf(categoryArrayList));
}
categoryAdapter.notifyDataSetChanged();
} catch (Exception e) {
e.printStackTrace();
}
break;
}
}
#Override
public void onError(VolleyError error, String tag) {
VolleyLog.e("Error: ", error.getMessage());
}
private void subCategoryJSON() {
StringRequest stringRequest = new StringRequest(Request.Method.GET, URLs.subcategoryURL,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("subcategoryJsonResponse", response.toString());
try {
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("sub-categories");
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
SubCategoryModelClass subCategoryModelClass = new SubCategoryModelClass();
subCategoryModelClass.setSubCategory_Id(productObject.getInt("Subcategories-Id"));
subCategoryModelClass.setCat_id(productObject.getInt("categories-Id"));
subCategoryModelClass.setSubCategory_Name(productObject.getString("Subcategories-Name"));
subCategoryModelClass.setSubCategory_Img(productObject.getString("Subcategories-Image"));
subCategoryModelClassList.add(subCategoryModelClass);
Log.d("subCategoryArraylist", String.valueOf(subCategoryModelClassList));
}
for (int i = 0; i < subCategoryModelClassList.size(); i++) {
subcategory_id = subCategoryModelClassList.get(i).getSubCategory_Id();
category_id = subCategoryModelClassList.get(i).getCat_id();
subcategory_name = subCategoryModelClassList.get(i).getSubCategory_Name();
// subcategory_desc = subCategoryModelClassList.get(i).getSubCategory_Desc();
subcategory_image = subCategoryModelClassList.get(i).getSubCategory_Img();
Log.d("fdsaff", subcategory_image);
SQLiteDatabase database = dbHelper.getWritableDatabase();
dbHelper.insertSubCategoryProduct(subcategory_id, category_id, subcategory_name, "https://www.ecrm.sample.in/app/img/"+subcategory_image, database);
dbHelper.close();
}
subCategoryAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
VolleySingleton.getInstance(getApplicationContext()).addToRequestQueue(stringRequest);
}
}
You have written the answer correctly but you are not implementing the written custom volley class code in the activity class.
First Define the interface class for the Volley as below,
Now implement the volley interface in the java class where you have written the custom volley class as below:
CustomStringRequestVolley.java
public class CustomStringRequestVolley implements volleyCallback {
public Context context;
public CustomStringRequestVolley(Context context) {
this.context = context;
}
public interface volleyCallback {
void onSuccess(String result);
void onError(String error);
}
public void callGetServer(String URL, final
volleyCallback callback){
if (!checkInternetConnection(context)) {
showNoInternetDialogue(context);
return;
}
RequestQueue requestQueue = Volley.newRequestQueue(context);
StringRequest stringRequest = new StringRequest(Request.Method.GET, URL, new
Response.Listener<String>() {
#Override
public void onResponse(String response) {
callback.onSuccess(response);
}
}, error -> {
if (error.networkResponse == null){
if (error.getClass().equals(TimeoutError.class)){
Toast.makeText(context, "Timeout.Please try again",
Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(NoConnectionError.class)){
Toast.makeText(context, "Timeout.Please try again", Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(NetworkError.class)) {
Toast.makeText(context, "Network Error.Please try again", Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(ParseError.class)){
Toast.makeText(context, "Parse error", Toast.LENGTH_SHORT).show();
}else if (error.getClass().equals(ServerError.class)){
Toast.makeText(context, "Server Error.Please try again", Toast.LENGTH_SHORT).show();
}
else {
parseVolleyError(error);
}
}
}
) {
#Override
protected Map<String, String> getParams() {
return new HashMap<>();
}
#Override
public Map<String, String> getHeaders() {
Map<String, String> headers = new HashMap<>();
headers.put("Content-Type", "application/x-www-form-urlencoded");
return headers;
}
};
//setting up the retry policy for slower connections
int socketTimeout = 120000;//120000 milli seconds - change to what you want
RetryPolicy policy = new DefaultRetryPolicy(socketTimeout,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT);
stringRequest.setRetryPolicy(policy);
requestQueue.add(stringRequest);
}
}
Now use this Custom volley class in every activity you required. It reduces you
boilerplate code
NavDrawerActivity.java
CustomStringRequestVolley customStringRequestVolley;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_starting_point_navigation);
customStringRequestVolley = new CustomStringRequestVolley(this);
}
private void subCategoryJSON() {
customStringRequestVolley.callGetServer(URLs.subcategoryURL,new volleyCallback() {
#Override
public void onSuccess(String result) {
try {
JSONObject obj = new JSONObject(response);
JSONArray productArray = obj.getJSONArray("sub-categories");
for (int i = 0; i < productArray.length(); i++) {
JSONObject productObject = productArray.getJSONObject(i);
SubCategoryModelClass subCategoryModelClass = new SubCategoryModelClass();
subCategoryModelClass.setSubCategory_Id(productObject.getInt("Subcategories-Id"));
subCategoryModelClass.setCat_id(productObject.getInt("categories-Id"));
subCategoryModelClass.setSubCategory_Name(productObject.getString("Subcategories-Name"));
subCategoryModelClass.setSubCategory_Img(productObject.getString("Subcategories-Image"));
subCategoryModelClassList.add(subCategoryModelClass);
Log.d("subCategoryArraylist", String.valueOf(subCategoryModelClassList));
}
for (int i = 0; i < subCategoryModelClassList.size(); i++) {
subcategory_id = subCategoryModelClassList.get(i).getSubCategory_Id();
category_id = subCategoryModelClassList.get(i).getCat_id();
subcategory_name = subCategoryModelClassList.get(i).getSubCategory_Name();
// subcategory_desc = subCategoryModelClassList.get(i).getSubCategory_Desc();
subcategory_image = subCategoryModelClassList.get(i).getSubCategory_Img();
Log.d("fdsaff", subcategory_image);
SQLiteDatabase database = dbHelper.getWritableDatabase();
dbHelper.insertSubCategoryProduct(subcategory_id, category_id, subcategory_name, "https://www.ecrm.sample.in/app/img/"+subcategory_image, database);
dbHelper.close();
}
subCategoryAdapter.notifyDataSetChanged();
} catch (JSONException e) {
e.printStackTrace();
}
}
#Override
public void onError(String error) {
//show error code
}
});
}
Let me know after you try this #Abhishek
I am developing an android app, where I am using Relam as local Database. I have rest api one for all the user information and other is for news information. I have two buttons. one for showing the user information and other is for showing the news information. Now, with my code what is done, after login, I need to click the button at first for user information and news information accordingly and then I can see those images and news. but if I connection off, just after login, the data is not showing in the view. I am explaining my code in detail.Also I am having problem in image loading. How can I Make the funtionality so that user can get all the information just after login.I am reallly sorry for such a long code. It would be really helpful for me if someone tell me how can I modify my code to store all data in background thread, so that user get all information just after login.
The part of the login page where I want to start
private void loginUser(final String mEmail, final String mPassword) {
final GlobalClass globalClass = new GlobalClass();
globalClass.setEmail_info( mEmail );
setFilePath();
RequestQueue queue = Volley.newRequestQueue( LoginPage.this );
StringRequest strReq = new StringRequest( Request.Method.POST,
LOGIN_URL, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d( TAG, "Register Response: " + response.toString() );
//parse your response here
if (response.contains( "overview" )) {
showProgress( true );
globalClass.setImage_urlpath( Constants.HTTP.PHOTO_URL + mEmail);
String str = globalClass.readDatafromStorage();
Log.d("----After Login---",str);
if ( !str.contains("ACTIVATE") ) {
Log.d( "----After Login---", "After Login" );
}
SharedPreferences.Editor editor = sharedpreferences.edit();
editor.putString(KEY_EMAIL, mEmail);
editor.putString(KEY_PASSWORD, mPassword);
editor.commit();
showProgress(false);
Intent loginIntent = new Intent(LoginPage.this, MainOptionPage.class);
loginIntent.putExtra(KEY_EMAIL, mEmail);
startActivity(loginIntent);
} else {
userEmail.setError(getString(R.string.error_incorrect_login));
userEmail.requestFocus();
}
}
}, new Response.ErrorListener() {
#Override
....
Here is my code for User Page
public class MyColleaguesPage extends AppCompatActivity implements ColleagueController.UserCallbackListener {
private List<MyColleagueModel> myColleagueList = new ArrayList<>();
private Realm colleagueRealm;
private RealmResults<MyColleagueModel> colleagueResult;
private List<MyColleagueModel> filteredModelList;
private RealmChangeListener realmListener;
private static final String DIALOG_TAG = "EmployeeDialog";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mycolleagues_layout);
configViews();
}
private void configViews() {
recyclerView = this.findViewById(R.id.colleagues_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(MyColleaguesPage.this));
recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
colleagueRealm = Realm.getDefaultInstance();
RealmResults<MyColleagueModel> results = colleagueRealm.where(MyColleagueModel.class).findAll();
for (int i = 0; i < results.size(); i++) {
myColleagueList.add(results.get(i));
}
adapter = new MyColleaguesAdapter(myColleagueList,getApplicationContext());
//adapter = new MyColleaguesAdapter(myColleagueList,getApplicationContext());
Log.d( "adapter value is"+"", String.valueOf( adapter ) );
recyclerView.setAdapter(adapter);
}
//successful
#Override
public void onFetchStart() {
}
#Override
public void onFetchProgress(ColleagueModel colleague) {
//adapter.addColleague(colleague);
}
#Override
public void onFetchProgress(List<ColleagueModel> colleagueList) {
}
#Override
public void onFetchComplete() {
}
#Override
public void onFetchFailed() {
}
}
Here is my controller class for my colleague page
public class ColleagueController {
private static final String TAG = ColleagueController.class.getSimpleName();
private UserCallbackListener mListener;
private ColleagueResApiManager mApiManager;
Realm myColleague_realm;
public ColleagueController() {
mApiManager = new ColleagueResApiManager();
}
public void startFetching(){
myColleague_realm = Realm.getDefaultInstance();
mApiManager.getColleagueApi().getColleague(new Callback<String>() {
#Override
public void success(String s, Response response) {
Log.d(TAG, "JSON :: " + s);
try {
JSONArray array = new JSONArray(s);
for(int i = 0; i < array.length(); i++) {
JSONObject object = array.getJSONObject(i);
Log.d("-----Start Fetching---", object.optString( "name" ));
myColleague_realm.beginTransaction();
MyColleagueModel mycolleague = myColleague_realm.createObject( MyColleagueModel.class );
mycolleague.setName( object.optString( "name" ) );
.... data ) );
myColleague_realm.commitTransaction();
}
} catch (JSONException e) {
mListener.onFetchFailed();
}
// mListener.onFetchComplete();
}
#Override
public void failure(RetrofitError error) {
Log.d(TAG, "Error :: " + error.getMessage());
if (mListener != null) {
mListener.onFetchComplete();
}
}
});
}
public interface UserCallbackListener{
void onFetchComplete();
void onFetchFailed();
}
}
In the same way I have other page news option page where I am shoing the news data. Here is my news page.
public class NewsPage extends AppCompatActivity{
private RecyclerView recyclerView;
private NewsAdapter adapter;
private Realm newsRealm;
private List<NewsRealmModel> mNewsList;
private List<NewsRealmModel> filteredModelList;
private NewsController mController;
Constant constant;
SharedPreferences app_preferences;
int appTheme;
int themeColor;
int appColor;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView( R.layout.news_page_layout);
configViews();
}
private void configViews() {
recyclerView = this.findViewById(R.id.news_recycler);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(NewsPage.this));
recyclerView.setRecycledViewPool(new RecyclerView.RecycledViewPool());
Realm newsRealm = Realm.getDefaultInstance();
RealmResults<NewsRealmModel> temp = newsRealm.where(NewsRealmModel.class).findAll();
mNewsList = new ArrayList<>();
for (int i = 0; i < temp.size(); i++) {
mNewsList.add(temp.get(i));
}
adapter = new NewsAdapter(mNewsList,getApplicationContext());
Log.d( "adapter value is"+"", String.valueOf( adapter ) );
recyclerView.setAdapter(adapter);
}
}
And the new Controller Class
public class NewsController {
private static final String TAG = NewsController.class.getSimpleName();
private UserCallbackListener mListener;
private NewsRestApiManager mApiManager;
private AppImage appImages;
Realm myNews_realm;
ArrayList<String> title_list = new ArrayList<>();
GlobalClass globalClass = new GlobalClass();
public NewsController(UserCallbackListener listener) {
mListener = listener;
mApiManager = new NewsRestApiManager();
}
public void startFetching() {
myNews_realm = Realm.getDefaultInstance();
mApiManager.getNewsApi().getNews(new Callback<String>() {
#Override
public void success(String s, Response response) {
Log.d(TAG, "JSON :: " + s);
try {
JSONArray array = new JSONArray(s);
for (int i = 0; i < array.length(); i++) {
JSONObject jsonObject = array.getJSONObject(i);
Log.d("-----Start Fetching---", jsonObject.optString("title"));
if (!myNews_realm.isInTransaction()) {
myNews_realm.beginTransaction();
NewsRealmModel news = new NewsRealmModel();
....... data
}
myNews_realm.copyToRealm(news);
myNews_realm.commitTransaction();
mListener.onFetchProgressNews(news);
} else {
myNews_realm.commitTransaction();
}
}
} catch (JSONException e) {
mListener.onFetchFailed();
}
mListener.onFetchComplete();
}
#Override
public void failure(RetrofitError error) {
Log.d(TAG, "Error :: " + error.getMessage());
mListener.onFetchComplete();
}
});
}
public interface UserCallbackListener {
void onFetchProgressNews(NewsRealmModel news);
void onFetchComplete();
void onFetchFailed();
}
}
To do your database processing on a background thread using Volley, you need to extend Request<T> and do the Realm write in parseNetworkResponse method.
public class RealmGsonObjectRequest<T, M extends RealmModel> extends Response<Void> {
...
#Override
protected Response<Void> parseNetworkResponse(
NetworkResponse response) {
try {
String json = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
T data = gson.fromJson(json, clazz);
// write the downloaded data into the Realm on bg thread
try(Realm r = Realm.getDefaultInstance()) {
M model = mapper.toModel(data);
r.executeTransaction((realm) -> {
realm.insertOrUpdate(model);
});
}
return Response.success(null,
HttpHeaderParser.parseCacheHeaders(response)
);
} // handle errors
}
You might need a RealmGsonListRequest as well.
public class RealmGsonListRequest<T, M extends RealmModel> extends Response<Void> {
...
#Override
protected Response<Void> parseNetworkResponse(
NetworkResponse response) {
try {
String json = new String(response.data,
HttpHeaderParser.parseCharset(response.headers));
List<T> data = gson.fromJson(json, new TypeToken<ArrayList<T>>() {}.getType());
// write the downloaded data into the Realm on bg thread
try(Realm r = Realm.getDefaultInstance()) {
M model = mapper.toModel(data);
r.executeTransaction((realm) -> {
realm.insertOrUpdate(model);
});
}
return Response.success(null,
HttpHeaderParser.parseCacheHeaders(response)
);
} // handle errors
}
For more information, refer to the official Volley tutorial on how to create a custom Volley request type.
I've been looking around everywhere in trying to find out why my code was causing an issue. I have a GridView that has an ArrayAdapter which pulls photos down with an AsyncTask. I can see the items being updated but when I try to update the adapter the GridView doesn't seem to update with the new view.
This is the relevant code that does the work...
private void fetchJsonResponse(String url) {
// Pass second argument as "null" for GET requests
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
url + "&api_key=" + API_KEY,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray photos = response.getJSONArray("photos");
for(int i = 0; i < photos.length(); i++){
JSONObject object = photos.getJSONObject(i);
String url = object.getString("img_src");
//String id = object.getString("id");
list.add(new ImageItem(null, "Picture", url));
Log.i("Debug 2", url);
}
Log.i("Debug 2", list.get(0).toString());
if(gridViewAdapter != null){
gridViewAdapter.clear();
gridViewAdapter.addAll(list);
gridViewAdapter.notifyDataSetChanged();
gridView.invalidateViews();
} else {
gridViewAdapter = new GridViewAdapter(getActivity(), R.layout.gridview_item, list);
gridView.setAdapter(gridViewAdapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
/* Add your Requests to the RequestQueue to execute */
mRequestQueue.add(req);
}
private class MyAsyncTask extends AsyncTask<String, Void, Void> {
private ProgressDialog progressDialog;
private Context context;
public MyAsyncTask (Context context){
this.context = context;
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Contacting Rover...");
}
#Override
protected Void doInBackground(String... strings) {
fetchJsonResponse(strings[0]);
return null;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(getActivity(), "In Pre Execute", Toast.LENGTH_SHORT).show();
progressDialog.show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
progressDialog.dismiss();
}
}
I would really appreciate any help if possible. Trying to get the app out before new years :).
Maybe If you could tell me why this happens so It won't cause an issue again and other will see.
EDIT: Added a bit more code which has it refreshing after I click the button twice.
private void fetchJsonResponse(String url) {
// Pass second argument as "null" for GET requests
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
url + "&api_key=" + API_KEY,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray photos = response.getJSONArray("photos");
list.clear();
for(int i = 0; i < photos.length(); i++){
JSONObject object = photos.getJSONObject(i);
String url = object.getString("img_src");
list.add(new ImageItem(null, "Picture", url));
Log.i("Debug 2", url);
}
Log.i("Debug 2", list.get(0).toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
VolleyLog.e("Error: ", error.getMessage());
}
});
/* Add your Requests to the RequestQueue to execute */
mRequestQueue.add(req);
}
private class MyAsyncTask extends AsyncTask<String, Void, Void> {
private ProgressDialog progressDialog;
private Context context;
public MyAsyncTask (Context context){
this.context = context;
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Contacting Rover...");
pictureAdapter = new PictureAdapter(getActivity(), list);
gridView.setAdapter(pictureAdapter);
}
#Override
protected Void doInBackground(String... strings) {
fetchJsonResponse(strings[0]);
return null;
}
#Override
protected void onPreExecute() {
progressDialog.show();
super.onPreExecute();
Toast.makeText(getActivity(), "In Pre Execute", Toast.LENGTH_SHORT).show();
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pictureAdapter.updateItemList(list);
gridView.invalidate();
progressDialog.dismiss();
}
}
Adapter:
public class PictureAdapter extends BaseAdapter {
private ArrayList<ImageItem> items;
private Context context;
private TextView titleText;
private ImageView itemImage;
public PictureAdapter(Context context, ArrayList<ImageItem> items){
this.context = context;
this.items = items;
}
#Override
public int getCount() {
return items.size();
}
#Override
public Object getItem(int position) {
return items.get(position);
}
#Override
public long getItemId(int position) {
return position;
}
#Override
public View getView(int position, View convertView, ViewGroup parent) {
View v = LayoutInflater.from(context).inflate(R.layout.gridview_item, parent, false);
titleText = (TextView) v.findViewById(R.id.text);
itemImage = (ImageView)v.findViewById(R.id.image);
titleText.setText(items.get(position).getTitle());
Picasso.with(context).load(items.get(position).getUrl()).fit().into(itemImage);
return v;
}
public void updateItemList(ArrayList<ImageItem> newItemList){
this.items = newItemList;
notifyDataSetChanged();
}
}
Try the below lines in post execute
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
pictureAdapter.updateItemList(list,gridView);
progressDialog.dismiss();
}
Now in your updateItemList
public void updateItemList(ArrayList<ImageItem> newItemList,GridView gridView){
this.items = newItemList;
gridView.setAdapter(null);
gridView.invalidateViews();
gridView.deferNotifyDataSetChanged();
gridView.setAdapter(list);
}
Why you are calling Volley request from AsyncTask as Volley perform request on NetworkThread.
Remove AsyncTask and directly call Volley.
Just try this. Hope it helps.
private ProgressDialog progressDialog;
protected void onCreate(Bundle savedInstanceState) {
progressDialog = new ProgressDialog(getActivity());
progressDialog.setMessage("Contacting Rover...");
progressDialog.show();
fetchJsonResponse(url);
}
private void fetchJsonResponse(String url) {
// Pass second argument as "null" for GET requests
JsonObjectRequest req = new JsonObjectRequest(Request.Method.GET,
url + "&api_key=" + API_KEY,
null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
progressDialog.dismiss();
try {
JSONArray photos = response.getJSONArray("photos");
list.clear();
for(int i = 0; i < photos.length(); i++){
JSONObject object = photos.getJSONObject(i);
String url = object.getString("img_src");
list.add(new ImageItem(null, "Picture", url));
Log.i("Debug 2", url);
}
pictureAdapter.notifyDataSetChanged();
Log.i("Debug 2", list.get(0).toString());
} catch (JSONException e) {
e.printStackTrace();
}
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
progressDialog.dismiss();
VolleyLog.e("Error: ", error.getMessage());
}
});
/* Add your Requests to the RequestQueue to execute */
mRequestQueue.add(req);
}
I am starting then 4 post after each other. But I catch only response from 3 of the 4 posts.
Can somebody explain to me why? I tried it also with get and it has the same problem. Am I doing the posts to quick after each other?
Resclient class:
public class RestClient {
private static AsyncHttpClient client = new AsyncHttpClient();
public static void post(String url, RequestParams params, AsyncHttpResponseHandler responseHandler) {
client.post(url, params, responseHandler);
}
}
Webservice resolver:
public class WSBeer extends WSBase {
public WSBeer(OnWSRequestCompleted listener, Context context) {
super(listener, context);
}
public void getAll(String date) throws JSONException {
Tools.LOG_DEBUG("GetAllBeer");
RequestParams params = new RequestParams();
params.add("date", date);
RestClient.post(url, params, new JsonHttpResponseHandler() {
#Override
public void onSuccess(JSONObject response) {
Tools.LOG_DEBUG("WSBeer onSucces: " + response);
listener.onRestTaskCompleted(Constants.FUNCTION_DB_BEER, response);
}
#Override
public void onFailure(Throwable e, JSONArray errorResponse) {
Tools.LOG_DEBUG("WSBeer getAll: " + errorResponse);
handleError(e, errorResponse, null);
}
#Override
public void onFailure(Throwable e, JSONObject errorResponse) {
Tools.LOG_DEBUG("WSBeer getAll: " + errorResponse);
handleError(e, null, errorResponse);
}
});
}
}
SyncHandler class:
public class SyncHandler implements OnWSRequestCompleted {
private OnSyncListener listener;
private Context context;
private WSBeer wsBeer;
public SyncHandler(OnSyncListener listener, Context context) {
this.listener = listener;
this.context = context;
}
#Override
public void onRestTaskCompleted(int function, JSONObject response) {
switch (function) {
case Constants.FUNCTION_DB_BEER:
List<Beer> beerList = null;
try {
beerList = ResponseBeer.getAll(response);
} catch (IOException e) {
Tools.LOG_ERROR(e);
}
Tools.LOG_DEBUG("Beers");
if (beerList != null) {
new SaveBeerHelper(listener).execute(beerList.toArray(new Beer[beerList.size()]));
}
break;
}
}
public void syncBeer() {
wsBeer = new WSBeer(this, context);
try {
Tools.LOG_DEBUG("Start loading beer...");
String date = getSyncDate(Constants.FUNCTION_DB_BEER);
wsBeer.getAll(date);
} catch (JSONException e) {
e.printStackTrace();
}
}
private String getSyncDate(int databaseId) {
SyncData syncData = Shared.dbRepo.syncRepository.getById(databaseId);
if (syncData != null) {
Tools.LOG_DEBUG("SyncData: " + syncData.getSyncDate().toString());
return syncData.getSyncDate().toString();
} else {
new SyncData(databaseId).Save(Shared.dbRepo);
}
Tools.LOG_DEBUG("SyncData: ");
return "";
}
}
WEBSERVICE ACTION:
public function bierenAction()
{
$this->view->status = 204; //Nog geen content
if ($this->getRequest()->isPost()){
$date = $this->postParam('date');
if ($date != "") {
$bieren = self::$proxyBier->getBierenByUpdated($date);
} else {
$bieren = self::$proxyBier->getBieren();
}
} else {
$bieren = self::$proxyBier->getBieren();
}
$this->view->data = $bieren;
$this->view->status = 200; //Alles oke
$this->view->ajax();
}
Also you can use this instead https://github.com/leonardoxh/AsyncOkHttpClient this library just use OkHttpClient instead of Apache librarys, and this library is the base codes for Loopj AsyncHttpClient 2.0 (where the library will be re implemented with Square OkHttp)
I used the newer version of async-http library
compile 'com.loopj.android:android-async-http:1.4.5-SNAPSHOT'
and everything works like a charm :)