Volley passing URL - java

final ProgressDialog pDialog = new ProgressDialog(this);
pDialog.setMessage("Loading...");
pDialog.show();
StringRequest strReq = new StringRequest(Request.Method.GET,
"http://example.com/", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Document document = Jsoup.parse(response);
Elements elementss = document.select("div.category > li");
for (Element element : elements) {
Elements naslov = el.select("div.text > li.headline);
}
pDialog.hide();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "Greška", Toast.LENGTH_SHORT).show();
pDialog.hide();
}
});
AppController.getInstance().addToRequestQueue(strReq);
How could I pass URL parameter, instead of creating new StringRequest everytime i want to parse data, because different URLs have the same HTML structure, could I pass URL parameter when adding StringRequest to RequestQueue, something like:
AppCore.getInstance("http://example.com/").addToRequestQueue(strReq);
And use the same StringRequest several times, but with different URLs?
Also, here's my AppCore.java:
package app.android.volley;
import android.app.Application;
import android.text.TextUtils;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.toolbox.ImageLoader;
import com.android.volley.toolbox.Volley;
public class AppCore extends Application {
public static final String TAG = AppCore.class
.getSimpleName();
private RequestQueue mRequestQueue;
private static AppCore mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppCore getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
Basically what I'm trying to do is using one StringRequest multiple times, but with different URLs.
Thanks in advance.

You can try the following way (of course, you can replace JSONArray request by JSONObject request or String request):
VolleyResponseListener listener = new VolleyResponseListener() {
#Override
public void onError(String message) {
// do something...
}
#Override
public void onResponse(Object response) {
// do something...
}
};
makeJsonArrayRequest(context, Request.Method.POST, url, requestBody, listener);
Body of makeJsonArrayRequest can be as the following:
public void makeJsonArrayRequest(Context context, int method, String url, String requestBody, final VolleyResponseListener listener) {
JSONObject jsonRequest = null;
try {
...
if (requestBody != null) {
jsonRequest = new JSONObject(requestBody);
}
...
} catch (JSONException e) {
e.printStackTrace();
}
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(method, url, jsonRequest, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray jsonArray) {
listener.onResponse(jsonArray);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
listener.onError(error.toString());
}
});
// Access the RequestQueue through singleton class.
MySingleton.getInstance(context).addToRequestQueue(jsonArrayRequest);
}
VolleyResponseListener interface as the following:
public interface VolleyResponseListener {
void onError(String message);
void onResponse(Object response);
}

Related

How to make concurrent GET calls using Volley?

I have 3 API GET calls. The problem I'm facing with my approach is, the app is able to fetch the data successfully from two APIs and I'm able to display it on UI as well. But, for the third API call, due to the below error, the data that is being shown previously disappears which is bad.
D/Volley: [380] BasicNetwork.logSlowRequests: HTTP response for request=<[ ] http://example.com/api/search/getTwitterData?limit=10&tag=JavaScript 0x865f5dc2 NORMAL 3> [lifetime=6683], [size=10543], [rc=200], [retryCount=0]
How do I make concurrent API GET calls using Volley without losing the data on UI. Could anyone please guide me?
Here are excerpts from my code.
public class StaggeredSearchActivity extends AppCompatActivity {
...
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_staggered_search);
requestQueue = Volley.newRequestQueue(this);
Intent intent = getIntent();
String searchText = intent.getStringExtra("searchText");
// Three concurrent API GET Calls
getMediumData(searchText);
getExampleData(searchText);
getGoogleData(searchText);
recyclerView = findViewById(R.id.staggered_recycler_view);
staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
}
ArrayList<StaggeredCustomCard> dataset = new ArrayList<>();
private void getMediumData(String searchText) {
progressBar = findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
String url = UrlConstants.getUrl() + searchText;
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
progressBar.setVisibility(View.INVISIBLE);
JSONArray array = response.getJSONArray("mediumposts");
...
dataset.add(new StaggeredCustomCard(user, userpost, postdate));
}
staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
recyclerView.setAdapter(staggeredGridAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
progressBar.setVisibility(View.INVISIBLE);
}
});
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonObjectRequest);
}
private void getExampleData(String searchText) {
...
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
...
dataset.add(new StaggeredCustomCard(user, userpost, postdate));
staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
recyclerView.setAdapter(staggeredGridAdapter);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
...
}
});
jsonArrayRequest.setRetryPolicy(new DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonArrayRequest);
}
private void getGoogleData(String searchText) {
...
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
...
dataset.add(new StaggeredCustomCard(user, userpost, postdate));
}
staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
recyclerView.setAdapter(staggeredGridAdapter);
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
...
}
});
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonObjectRequest);
}
}
The problem is that you are initializing Adapter every time that's why your data will be lost once a new API call. I prefer below approach so that can help you,
Add Data in ArrayList and notify adapter,
Add this line in onCreate,
staggeredGridAdapter = new StaggeredGridAdapter(StaggeredSearchActivity.this, dataset);
recyclerView.setAdapter(staggeredGridAdapter);
Changes in API Callback Response :
...
dataset.add(new StaggeredCustomCard(user, userpost, postdate));
After loop add below line
staggeredGridAdapter.notifyDataSetChanged();
Changes in Adapter
private ArrayList<StaggeredCustomCard> dataSet;
private Context context;
public MyAdapter(ArrayList<StaggeredCustomCard> dataSet, Context context) {
this.data = data;
this.context = context;
}
Note : Don't create new object on adapter.
The approach just doesn't make a lot of sense.
Once you get a response from one of the three endpoints, you seem to create a new Adapter and attach it to the recycler with a random "notifyDataSetChanged" every time...
Maybe look at using a ViewModel with a service layer and network layer that deal with the business login.
The ViewModel updates/posts a MutableLiveData> when a callback from one of the Network methods responds from the endpoints...merging the three pieces of data.
The activity just observes the ViewModel's MutableLiveData and uses a DiffUtil to update the look/cards in the recycler.
The best way is to register your LiveData in the StaggeredSearchActivity in onCreate method and listen for db changes like you did. In the each success responce save its result to db without LiveData. LiveData in onCreate method will be triggered.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main2);
ViewModel viewModel = ViewModelProviders.of(this, factory).get(ViewModel.class);
viewModel.getEntity().observe(this, entity -> {
if (entity != null) {
adapter.notifyDataSetChanged(entity );
}
});
requestQueue = Volley.newRequestQueue(this);
Intent intent = getIntent();
String searchText = intent.getStringExtra("searchText");
// Three concurrent API GET Calls
getMediumData(searchText);
getExampleData(searchText);
getGoogleData(searchText);
recyclerView = findViewById(R.id.staggered_recycler_view);
staggeredGridLayoutManager = new StaggeredGridLayoutManager(2, LinearLayoutManager.VERTICAL);
recyclerView.setLayoutManager(staggeredGridLayoutManager);
}
ArrayList<StaggeredCustomCard> dataset = new ArrayList<>();
private void getMediumData(String searchText) {
progressBar = findViewById(R.id.progressBar);
progressBar.setVisibility(View.VISIBLE);
String url = UrlConstants.getUrl() + searchText;
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
StaggeredCustomCardDAO.insert();
// TODO just insert to dataBase
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
// TODO: Handle error
progressBar.setVisibility(View.INVISIBLE);
}
});
jsonObjectRequest.setRetryPolicy(new
DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonObjectRequest);
}
private void getExampleData(String searchText) {
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest
(Request.Method.GET, url, null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
try {
// TODO just insert to dataBase
StaggeredCustomCardDAO.insert();
} catch (
JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
jsonArrayRequest.setRetryPolicy(new DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonArrayRequest);
}
private void getGoogleData(String searchText) {
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest
(Request.Method.GET, url, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
// TODO just insert to dataBase
StaggeredCustomCardDAO.insert();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
}
});
jsonObjectRequest.setRetryPolicy(new DefaultRetryPolicy(
DefaultRetryPolicy.DEFAULT_TIMEOUT_MS * 15,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
requestQueue.add(jsonObjectRequest);
}
class ViewModel extends androidx.lifecycle.ViewModel {
private LiveData<StaggeredCustomCard> entity;
public ViewModel(Repository repository) {
entity = repository.getNetworkData();
}
public LiveData<StaggeredCustomCard> getEntity() {
return entity;
}
}
class Repository {
LiveData<StaggeredCustomCard> getNetworkData() {
LiveData<StaggeredCustomCard> localeData = StaggeredCustomCardDAO .getLocaleData();//... todo Read from data base
return localeData;
}
#Dao
public interface StaggeredCustomCardDAO {
#Query("Select * from tbl_staggeredCustomCard ")
LiveData<StaggeredCustomCard> getLocaleData();
#Insert(onConflict = OnConflictStrategy.REPLACE)
void insert(List<StaggeredCustomCard> items);
}
}
The data should not disappear due to that error. First thing first I would suggest you to check maybe you clear your dataset somewhere or your screen is getting recreated.
Secondly I would recommend you to move from Volley since it is quite outdated from modern techniques library that requires a lot of attention to details. Use Retrofit - it is modern, powerful and community approved library. Using it you will be sure that all the requests you want to be async are async and all the responses are handled well.
Also I would suggest you not to create adapter each time you load data but use one adapter and add data to it and them use notifyDataSetChanged() to reload list with relevant data.
First way : firstly i would suggest you to make a central request queue.
public class AppController extends Application {
public static final String TAG = AppController.class
.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
// set the default tag if tag is empty
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}
then add your desired requests to the queue
// Adding request to request queue
AppController.getInstance().addToRequestQueue(jsonObjReq);
Second way :
Create a Generic Volley class and a Interface, Use the interface to get success and failure responds.
Step 1 Create a separate Volley class
Step 2 Create a interface for accessing the response from volley class
Step 3 create new object for the class and send required parameters
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this(interfcae), "Submit", url, params);
Context of the class
Interface for sending Success and failure responds
Type of request to identify on success
url (mandatory)
Param (optional) for GET no need
Generic volley class
public class PostVolleyJsonRequest {
private String type;
private Activity act;
private VolleyJsonRespondsListener volleyJsonRespondsListener;
private String networkurl;
private JSONObject jsonObject = null;
private JSONObject params;
public PostVolleyJsonRequest(Activity act, VolleyJsonRespondsListener volleyJsonRespondsListener, String type, String netnetworkUrl,JSONObject params) {
this.act = act;
this.volleyJsonRespondsListener = volleyJsonRespondsListener;
this.type = type;
this.networkurl = netnetworkUrl;
this.params = params;
sendRequest();
}
private void sendRequest() {
Log.d("url", "url" + networkurl);
JsonObjectRequest jsObjRequest = new JsonObjectRequest(Request.Method.POST,networkurl,params,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
Log.e("response", "response " + response);
volleyJsonRespondsListener.onSuccessJson(response, type);
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
try {
NetworkResponse response = error.networkResponse;
Log.e("response", "response " + response);
if (response != null) {
int code = response.statusCode;
String errorMsg = new String(response.data);
Log.e("response", "response" + errorMsg);
try {
jsonObject = new JSONObject(errorMsg);
} catch (JSONException e) {
e.printStackTrace();
}
String msg = jsonObject.optString("message");
volleyJsonRespondsListener.onFailureJson(code, msg);
} else {
String errorMsg = error.getMessage();
volleyJsonRespondsListener.onFailureJson(0, errorMsg);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
jsObjRequest.setRetryPolicy(new DefaultRetryPolicy(
600000,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES,
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
RequestQueue requestqueue = Volley.newRequestQueue(act);
requestqueue.add(jsObjRequest);
}
}
Use the interface to get responds message
public interface VolleyJsonRespondsListener {
public void onSuccessJson(JSONObject result, String type);
public void onFailureJson(int responseCode, String responseMessage);
}
In your class where you want to include multiple request
public class TestVolley extends AppCompatActivity implements VolleyJsonRespondsListener{
//Your class code goes here
//network request
try {
//parameters
//Context,Interface,Type(to indentify your responds),URL,parameter for your request
//request 1
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "Submit", url, params);
//request 2
new PostVolleyJsonRequest(TestVolley.this, TestVolley.this, "AccessData", url_2, params_2);
} catch (Exception e) {
e.printStackTrace()
}
//Methods from Interface
#Override
public void onSuccessJson(JSONObject result, String type) {
//Based on the Type you send get the responds and parse it
switch (type) {
case "Submit":
try {
parseSubmit(result);
} catch (Exception e) {

What would be the simplest way of posting data using Volley?

I am trying to use Volley to send 3 strings to a php script that sends it to a localhost server. I have this so far;
RegisterRequest;
public class RegisterRequest extends StringRequest {
private static final String REGISTER_REQUEST_URL = "http://192.168.*.*:80/phptesting/Register.php";
private Map<String, String> params;
public RegisterRequest(String username, String password,String isAdmin,
Response.Listener<String> listener,
Response.ErrorListener errListener){
super(Method.POST, REGISTER_REQUEST_URL,listener,errListener);
params = new HashMap<>();
params.put("username",username);
params.put("password",password);
params.put("isAdmin",isAdmin+"");
}
public Map<String, String> getparams() {
return params;
}
}
This is CreateUser;
public class CreateUser extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_create_user);
this.setTitle("Create User");
final EditText username1 = findViewById(R.id.Createusername);
final EditText password1 = findViewById(R.id.CreatePassword);
final Switch isAdmin = findViewById(R.id.isadmin);
final Button createuser = findViewById(R.id.createuserbtn);
if (getIntent().hasExtra("com.example.northlandcaps.crisis_response")){
isAdmin.setVisibility(View.GONE);
}
createuser.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
final String username = username1.getText().toString();
final String password = password1.getText().toString();
final String isadmin = isAdmin.getText().toString();
Response.Listener<String> responseListener = new Response.Listener<String>() {
#Override
public void onResponse(String response) {
Log.d("Response Value: ", response);
if (response.equals("success")){
Intent intent = new Intent(CreateUser.this, MainActivity.class);
CreateUser.this.startActivity(intent);
}else{
AlertDialog.Builder builder = new AlertDialog.Builder(CreateUser.this);
builder.setMessage("Register Failed")
.setNegativeButton("Retry",null)
.create()
.show();
}
}
};Response.ErrorListener errorListener = new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(), String.valueOf(error), Toast.LENGTH_SHORT).show();
}
};
RegisterRequest registerRequest = new RegisterRequest(username,password,isadmin,responseListener,errorListener);
RequestQueue queue = Volley.newRequestQueue(CreateUser.this);
queue.add(registerRequest);
}
});
}
Now, the only error im getting is an Undefined index. And thats because Volley isnt sending data to the php script. The php script does work properly when data is sent to it, so my question is this; what changes do i have to make to my script for it to send the 3 strings over?
Never mess with code or else it will be confusing for you to handle things properly.
So just make another class and use it in your activity.
Have a look at this class I have written, you can use it anywhere and for any type of data request.
public class SendData {
private Context context;
private String url;
private HashMap<String, String> data;
private OnDataSent onDataSent;
public void setOnDataSent(OnDataSent onDataSent) {
this.onDataSent = onDataSent;
}
public SendData(Context context, String url, HashMap<String, String> data) {
this.context = context;
this.url = url;
this.data = data;
}
public void send(){
StringRequest stringRequest = new StringRequest(Request.Method.POST, url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
if(onDataSent != null){
onDataSent.onSuccess(response);
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if(onDataSent != null){
onDataSent.onFailed(error.toString());
}
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
map.putAll(data);
return map;
}
};
stringRequest.setRetryPolicy(new DefaultRetryPolicy(0, 0, 0));
RequestQueue requestQueue = Volley.newRequestQueue(context);
requestQueue.add(stringRequest);
}
public interface OnDataSent{
void onSuccess(String response);
void onFailed(String error);
}
}
And now you can easily use it from any activity. Just give data in the constructor and use the interface to track the events this way
HashMap<String, String> data = new HashMap<>();
data.put("username", "");//define the value
data.put("password", "");//define the value
data.put("is_admin", "");//define the value
SendData sendData = new SendData(this, "", data); //defie the context and url properly
sendData.setOnDataSent(new SendData.OnDataSent() {
#Override
public void onSuccess(String response) {
//parse the response
}
#Override
public void onFailed(String error) {
//something went wrong check the error
}
});
sendData.send();

Volley Request from another class not activity

I am making a volley String request from a separate class and return the result to main activity
public class FetchFlages {
Context context;
String
placeurl="https://maps.googleapis.com/maps/api/place/textsearch/json
query=";
String myapi = "&key=AIzaSyBuI5wpF733jBS8s7HzjybE1rYAp1hA5tA";
RequestQueue requestQueue;
String abc=null;
public FetchFlages(Context context) {
this.context = context;
requestQueue = Volley.newRequestQueue(context);
}
public String getPhotoReference(){
String url = placeurl +"China"+myapi;
StringRequest objectRequest = new StringRequest(Request.Method.GET, url,
new Listener<String>() {
#Override
public void onResponse(String response) {
abc = response;
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volly Error",error.toString());
}
});
requestQueue.add(objectRequest);
return abc;
}
}
and in main Class
FetchFlages fetchFlages = new FetchFlages(this);
flag = fetchFlages.getPhotoReference();
String g = flag;
But i can't get any value from that...the value of abc always return null
and
When i run debugger then debugger not comes neither on Volley on Response Listener method and nor on Error Listener Method...Please help me..
This is because as soon as getPhotoReference() is called, its returning the value. The network call is still running. Create a listener and call the listener method on onRespose
Sample pseudo code:
CustomListener.java
public interface CustomListener{
void onVolleyResponse(String response);
}
FetchFlages.java
public class FetchFlages {
Context context;
String placeurl="https://maps.googleapis.com/maps/api/place/textsearch/jsonquery=";
String myapi = "&key=AIzaSyBuI5wpF733jBS8s7HzjybE1rYAp1hA5tA";
RequestQueue requestQueue;
CustomListener listener = null; //Your listener instance
public FetchFlages(Context context, CustomListener listener) {
this.context = context;
this.listener = listener;
requestQueue = Volley.newRequestQueue(context);
}
public void getPhotoReference(){
String url = placeurl +"China"+myapi;
StringRequest objectRequest = new StringRequest(Request.Method.GET, url,
new Listener<String>() {
#Override
public void onResponse(String response) {
listener.onVolleyResponse(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volly Error",error.toString());
}
});
requestQueue.add(objectRequest);
}
}
Now in your main activity,
FetchFlages fetchFlages = new FetchFlages(this, new CustomListener() {
#Override
public void onVolleyResponse(String response) {
//response is your response
}
});
fetchFlages.getPhotoReference()
Use interface Method like:
public class FetchFlages {
Context context;
String placeurl = "https://maps.googleapis.com/maps/api/place/textsearch/json?query=";
String myapi = "&key=AIzaSyBuI5wpF733jBS8s7HzjybE1rYAp1hA5tA";
RequestQueue requestQueue;
IResult result;
public FetchFlages(Context context, IResult result) {
this.context = context;
requestQueue = Volley.newRequestQueue(context);
this.result = result;
}
public void getPhotoReference() {
String url = placeurl + "China" + myapi;
StringRequest objectRequest = new StringRequest(Request.Method.GET, url,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
result.notifySuccess(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volly Error", error.toString());
result.notifyError(error);
}
});
requestQueue.add(objectRequest);
}
public interface IResult {
public void notifySuccess(String response);
public void notifyError(VolleyError error);
}
and call it:
FetchFlages fetchFlages = new FetchFlages(this, new IResult() {
#Override
public void notifySuccess(String response) {
//response here
Log.e("responce",response);
}
#Override
public void notifyError(VolleyError error) {
//error here
}
});
fetchFlages.getPhotoReference()

How to send POST request in JSON using StringRequest

I am trying send post request in Json using StringRequest.I desing Jersey Servlet in java and I created android project in android studio.
I can send json object with Poster Plugin in Chrome but I cant android client.
Please help me.
Jersey Servlet:
#Path("/register")
public class RegisterServlet {
#POST
#Path("/add")
#Consumes(MediaType.APPLICATION_JSON)
public Response addUser(UserDTO user){
if((user.getUsername()=="") || (user.getEmail()=="") || (user.getPassword()=="")){
Logger.getLogger(RegisterServlet.class).info("Name or Email or Password is empty");
return Response.status(200).entity("empty").build();
}
if(Service.getInstance().addUser(user)){
Logger.getLogger(RegisterServlet.class).info("Added User --> username: "+user.getUsername()+"email: "+user.getEmail());
return Response.status(200).entity("add").build();
}else{
Logger.getLogger(RegisterServlet.class).info("Error Add User");
return Response.status(200).entity("error").build();
}
}
}
Android Code ;
private void postUser(final String username,final String email,
final String password,final String dep_name){
String tag_string_req = "req_register";
StringRequest strReq = new StringRequest(Method.POST,
"http://192.168.56.1:8080/ServerApp/register/add", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
hideDialog();
try {
JSONObject jObj = new JSONObject(response);
} catch (Exception e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(getApplicationContext(),
error.getMessage(), Toast.LENGTH_LONG).show();
hideDialog();
}
}) {
#Override
protected Map<String, String> getParams() {
// Posting params to register url
Map<String, String> params = new HashMap<String, String>();
params.put("name", username);
params.put("email", email);
params.put("password", password);
params.put("dep_name", dep_name);
return params;
}
};
AppController.getInstance().addToRequestQueue(strReq, tag_string_req);
}
AppController in Android;
public class AppController extends Application {
public static final String TAG = AppController.class.getSimpleName();
private RequestQueue mRequestQueue;
private static AppController mInstance;
#Override
public void onCreate() {
super.onCreate();
mInstance = this;
}
public static synchronized AppController getInstance() {
return mInstance;
}
public RequestQueue getRequestQueue() {
if (mRequestQueue == null) {
mRequestQueue = Volley.newRequestQueue(getApplicationContext());
}
return mRequestQueue;
}
public <T> void addToRequestQueue(Request<T> req, String tag) {
req.setTag(TextUtils.isEmpty(tag) ? TAG : tag);
getRequestQueue().add(req);
}
public <T> void addToRequestQueue(Request<T> req) {
req.setTag(TAG);
getRequestQueue().add(req);
}
public void cancelPendingRequests(Object tag) {
if (mRequestQueue != null) {
mRequestQueue.cancelAll(tag);
}
}
}

Custom Async Http Client in Android

I use https://github.com/loopj/android-async-http but I think this can be applied to an Async Task (native one)
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new AsyncHttpResponseHandler() {
#Override
public void onStart() {
// called before request is started
//Some debugging code here
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
//here is the interesting part
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
//Some debugging code here, show retry dialog, feedback etc.
}
#Override
public void onRetry(int retryNo) {
//Some debugging code here-------
}
});
I use it alot in lots of separate classes. The onStart, onFailure and onRetry are the same everywhere, just copy-paste, just the onSuccess is different.
I want to keep my code as clean as possible and to reuse what I've already written, so my question is, how do I make this custom, in a separate "file", and just reuse it. I need just the "OnSuccess" function. Thank you
---------------------------------------
SOLUTION for GET & POST (Thanks to furkan3ayraktar)
1st file RequestListener
package com.classicharmony.krakenmessages.utils.AsyncHttp;
import org.apache.http.Header;
public interface RequestListener {
public void onSuccess(int statusCode, Header[] headers, byte[] response);
}
2nd file RequestHandler
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.util.Log;
import com.loopj.android.http.AsyncHttpClient;
import com.loopj.android.http.AsyncHttpResponseHandler;
import org.apache.http.Header;
import org.apache.http.entity.StringEntity;
import java.io.UnsupportedEncodingException;
public class RequestHandler {
private static RequestHandler instance;
private AsyncHttpClient client;
private static final boolean SHOW_DEBUG_ALERT_DIALOG = true;
private RequestHandler() {
client = new AsyncHttpClient();
}
public static RequestHandler getInstance() {
if (instance == null) {
instance = new RequestHandler();
}
return instance;
}
public void make_get_Request(final Context context, final String url, final RequestListener listener) {
client.get(url, new AsyncHttpResponseHandler() {
#Override
public void onStart() {
Log.v("▒▒▒▒▒▒▒ GET ", url);
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
listener.onSuccess(statusCode, headers, response);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
Log.e("▒▒▒▒▒▒▒ GET FAILED ", url);
Log.e("▒▒▒▒▒▒▒ GET FAILED ", e.getLocalizedMessage());
if (DUtils.isDebuggable(context) && SHOW_DEBUG_ALERT_DIALOG) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("▒▒▒▒▒ ERROR ▒▒▒▒▒");
String error_msg;
if (errorResponse != null) {
try {
error_msg = String.valueOf(new String(errorResponse, "UTF-8"));
} catch (UnsupportedEncodingException e1) {
error_msg = e.getLocalizedMessage();
}
} else {
error_msg = e.getLocalizedMessage();
}
builder.setMessage(context.getClass().getSimpleName() + " -> " + error_msg)
.setCancelable(true)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
#Override
public void onRetry(int retryNo) {
Log.e("▒▒▒▒▒▒▒ RETRYING ", "....." + String.valueOf(retryNo));
}
});
}
public void make_post_Request(final Context context, final StringEntity entity, final String url, final RequestListener listener) {
client.post(context, url, entity, "application/json", new AsyncHttpResponseHandler() {
#Override
public void onStart() {
Log.v("▒▒▒▒▒▒▒ POST ", url);
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
listener.onSuccess(statusCode, headers, response);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
Log.e("▒▒▒▒▒▒▒ POST FAILED ", url);
Log.e("▒▒▒▒▒▒▒ POST FAILED ", context.getClass().getSimpleName() + " -> " + e.getLocalizedMessage());
if (DUtils.isDebuggable(context) && SHOW_DEBUG_ALERT_DIALOG) {
AlertDialog.Builder builder = new AlertDialog.Builder(context);
builder.setTitle("▒▒▒▒▒ ERROR ▒▒▒▒▒");
String error_msg;
if (errorResponse != null) {
try {
error_msg = String.valueOf(new String(errorResponse, "UTF-8"));
} catch (UnsupportedEncodingException e1) {
error_msg = e.getLocalizedMessage();
}
} else {
error_msg = e.getLocalizedMessage();
}
builder.setMessage(context.getClass().getSimpleName() + " -> " + error_msg)
.setCancelable(true)
.setPositiveButton("OK", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int id) {
dialog.dismiss();
}
});
AlertDialog alert = builder.create();
alert.show();
}
}
#Override
public void onRetry(int retryNo) {
Log.e("▒▒▒▒▒▒▒ RETRYING ", "....." + String.valueOf(retryNo));
}
});
}
}
3rd "utility" to show the dialog or not.
public static boolean isDebuggable(Context ctx) {
boolean debuggable = false;
X500Principal DEBUG_DN = new X500Principal("CN=Android Debug,O=Android,C=US");
try {
PackageInfo pinfo = ctx.getPackageManager().getPackageInfo(ctx.getPackageName(), PackageManager.GET_SIGNATURES);
Signature signatures[] = pinfo.signatures;
CertificateFactory cf = CertificateFactory.getInstance("X.509");
for (int i = 0; i < signatures.length; i++) {
ByteArrayInputStream stream = new ByteArrayInputStream(signatures[i].toByteArray());
X509Certificate cert = (X509Certificate) cf.generateCertificate(stream);
debuggable = cert.getSubjectX500Principal().equals(DEBUG_DN);
if (debuggable)
break;
}
} catch (PackageManager.NameNotFoundException e) {
//debuggable variable will remain false
} catch (CertificateException e) {
//debuggable variable will remain false
}
return debuggable;
}
Example how to call it for POST:
JSONObject jsonParams = new JSONObject();
StringEntity entity;
try {
jsonParams.put("from_user_id", "dan");
jsonParams.put("to_user_id", "vili");
jsonParams.put("message", "hello world");
entity = new StringEntity(jsonParams.toString());
} catch (JSONException e) {
e.printStackTrace();
return;
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
return;
}
RequestHandler handler = RequestHandler.getInstance();
handler.make_post_Request(getActivity(), entity, "http://your_server/api/etc", new RequestListener() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
try {
String server_response = String.valueOf(new String(response, "UTF-8"));
Log.v("Server response",server_response);
} catch (UnsupportedEncodingException e1) {
}
}
});
You could create your own, empty version of AsyncHttpResponseHandler, which doesn't implement the onSuccess method.
public abstract class OWADVLHttpResponseHandler extends AsyncHttpResponseHandler {
#Override
public void onStart() {}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {}
#Override
public void onRetry(int retryNo) {}
}
Your code would then look like:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new OWADVLHttpResponseHandler() {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
....
}
});
Obviously, you can fill in some contents in the non-overrided methods in the base class.
First you make an abstract base class that implements the behavior that is common. Something like this:
public abstract class AsyncHttpResponesHandlerBase implements AsyncHttpResponseHandler {
#Override
public void onStart() {
// called before request is started
// Some debugging code here
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
//Some debugging code here, show retry dialog, feedback etc.
}
#Override
public void onRetry(int retryNo) {
//Some debugging code here-------
}
}
Then per url you inherited from the base class and implement the onSuccess() method to handle the response.
public class GoogleGetHandler extends AsyncHttpResponesHandlerBase {
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// called when response HTTP status is "200 OK"
// do the Google specific handling
}
}
And you make the HTTP request as follows:
AsyncHttpClient client = new AsyncHttpClient();
client.get("http://www.google.com", new GoogleGetHandler());
So if you want to make calls to more urls, just keep making new subclasses based off of the base class so you inherit the common failure handling.
Create common request handler and listener. You can also create different request methods like makeRequest for each request you want, and also create different listeners. Here is a simple pattern I mostly use,
public class RequestHandler{
private static RequestHandler instance;
private AsyncHttpClient client;
private RequestHandler(){
client = new AsyncHttpClient();
}
public static RequestHandler getInstance(){
if(instance == null){
instance = new RequestHandler();
}
return instance;
}
// You can add more parameters if you need here.
public void makeRequest(String url, RequestListener listener){
client.get(url, new AsyncHttpResponseHandler() {
#Override
public void onStart() {
// called before request is started
//Some debugging code here
}
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
listener.onSuccess(statusCode, headers, response);
}
#Override
public void onFailure(int statusCode, Header[] headers, byte[] errorResponse, Throwable e) {
// called when response HTTP status is "4XX" (eg. 401, 403, 404)
//Some debugging code here, show retry dialog, feedback etc.
}
#Override
public void onRetry(int retryNo) {
//Some debugging code here-------
}
});
}
}
public interface RequestListener{
public void onSuccess(int statusCode, Header[] headers, byte[] response);
}
Then use as following in anywhere you want.
RequestHandler handler = RequestHandler.getInstance();
handler.makeRequest("http://www.google.com", new RequestListener(){
#Override
public void onSuccess(int statusCode, Header[] headers, byte[] response) {
// do whatever you want here.
}
});
*********************************************
Calling Api USing Retrofit
*********************************************
**Dependancies** :-
implementation 'com.android.support:recyclerview-v7:27.1.1'
implementation 'com.squareup.picasso:picasso:2.5.2'
implementation 'com.android.support:cardview-v7:27.1.1'
implementation 'com.loopj.android:android-async-http:1.4.9'
implementation 'com.google.code.gson:gson:2.2.4'
enter code here
**Model**
use the Pozo class
**Api Call**
-> getLogin() // use the method
//API call for Login
private void getLogin()
{
getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
AsyncHttpClient client = new AsyncHttpClient();
RequestParams requestParams = new RequestParams();
requestParams.put("email_id", edit_email.getText().toString());
requestParams.put("password", edit_password.getText().toString());
Log.e("", "LOGIN URL==>" + Urls.LOGIN + requestParams);
Log.d("device_token", "Device_ Token" + FirebaseInstanceId.getInstance().getToken());
client.post(Urls.LOGIN, requestParams, new JsonHttpResponseHandler() {
#Override
public void onStart() {
super.onStart();
ShowProgress();
}
#Override
public void onFinish() {
super.onFinish();
Hideprogress();
}
#Override
public void onSuccess(int statusCode, Header[] headers, JSONObject response) {
super.onSuccess(statusCode, headers, response);
Log.e("", "Login RESPONSE-" + response);
Login login = new Gson().fromJson(String.valueOf(response), Login.class);
edit_email.setText("");
edit_password.setText("");
if (login.getStatus().equals("true")) {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("User Login Successfully!"),
MDToast.LENGTH_SHORT, MDToast.TYPE_SUCCESS);
mdToast.show();
Utils.WriteSharePrefrence(SignInActivity.this, Util_Main.Constant.EMAIL, login.getData().getEmailId());
Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERID, login.getData().getId());
Utils.WriteSharePrefrence(SignInActivity.this, Constant.USERNAME, login.getData().getFirstName());
Utils.WriteSharePrefrence(SignInActivity.this, Constant.PROFILE, login.getData().getProfileImage());
hideKeyboard(SignInActivity.this);
Intent intent = new Intent(SignInActivity.this, DashboardActivity.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
} else {
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
MDToast mdToast = MDToast.makeText(SignInActivity.this, String.valueOf("Login Denied"),
MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
mdToast.show();
}
}
#Override
public void onFailure(int statusCode, Header[] headers, String responseString, Throwable throwable) {
super.onFailure(statusCode, headers, responseString, throwable);
Log.e("", throwable.getMessage());
getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
MDToast mdToast = MDToast.makeText(SignInActivity.this, "Something went wrong",
MDToast.LENGTH_SHORT, MDToast.TYPE_ERROR);
mdToast.show();
}
});
}
implements LocationListener {
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private String vendorId, vendorName, vendorPhone, vendorImg, vendorDistance, vendorStar, vendorRate, vendorAddress, vendorSummary, vendorOtherService;
LocationManager locationManager;
private FusedLocationProviderClient mFusedLocationProviderClient;
private boolean mLocationPermissionGranted;
private Location mLastKnownLocation;
init()
{
mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
}
#Click
public void lnrCurrentLocation() {
getLocationPermission();
getDeviceLocation();
}
private void getDeviceLocation() {
try {
if (mLocationPermissionGranted)
{
final Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
locationResult.addOnCompleteListener(this, new OnCompleteListener<Location>() {
#Override
public void onComplete(#NonNull Task<Location> task) {
MarkerOptions markerOptions = new MarkerOptions();
if (task.isSuccessful()) {
mLastKnownLocation = task.getResult();
if(mLastKnownLocation!=null)
{
Double lat = mLastKnownLocation.getLatitude();
Double lng = mLastKnownLocation.getLongitude();
Geocoder geocoder;
List<Address> addresses;
geocoder = new Geocoder(AddAddressActivity.this, Locale.getDefault());
try {
Log.e("latitude", "inside latitude--" + lat);
addresses = geocoder.getFromLocation(lat, lng, 1);
if (addresses != null && addresses.size() > 0) {
String address = addresses.get(0).getAddressLine(0);
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
String knownName = addresses.get(0).getFeatureName();
edtAddress.setText(address );
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (lat != null && lng != null) {
fastSave.saveString(Constant.CURR_LAT, String.valueOf(mLastKnownLocation.getLatitude()));
fastSave.saveString(Constant.CURR_LON, String.valueOf(mLastKnownLocation.getLongitude()));
} else {
getDeviceLocation();
}
}
}
}
});
}
else {
Log.d("#permision","======== Permision not found =========");
}
} catch (SecurityException e) {
Log.e("Exception: %s", e.getMessage());
}
}
private void getLocationPermission() {
if (ContextCompat.checkSelfPermission(this.getApplicationContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION)
== PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
} else {
}
}
#Override
public void onRequestPermissionsResult(int requestCode,
#NonNull String permissions[],
#NonNull int[] grantResults) {
mLocationPermissionGranted = false;
switch (requestCode) {
case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0
&& grantResults[0] == PackageManager.PERMISSION_GRANTED) {
mLocationPermissionGranted = true;
}
}
}
}
void getLocation() {
try {
locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 5000, 5, this);
}
catch(SecurityException e) {
e.printStackTrace();
}
}
#Override
public void onLocationChanged(Location location) {
}
#Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
#Override
public void onProviderEnabled(String provider) {
}
#Override
public void onProviderDisabled(String provider) {
}
}
"GOOGLE MAP IN ANDROID"
implementation 'com.android.support:design:28.0.0'
implementation 'com.google.android.gms:play-services-maps:11.8.0'
implementation 'com.github.pedroSG94:AutoPermissions:1.0.3'
<meta-data
android:name="#string/permissions_loader_meta_key"
android:value="android.permission.WRITE_EXTERNAL_STORAGE, android.permission.CAMERA,android.permission.ACCESS_FINE_LOCATION,android.permission.ACCESS_COARSE_LOCATION" />
<meta-data
android:name="com.google.android.geo.API_KEY"
android:value="#string/google_maps_key" />
implements OnMapReadyCallback, AutoPermissionsListener {
private GoogleMap mMap;
AutoPermissions.Companion.loadActivityPermissions(DashboardActivity.this, 1);
SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
.findFragmentById(R.id.map);
mapFragment.getMapAsync(this);
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
AutoPermissions.Companion.parsePermissions(DashboardActivity.this, requestCode, permissions, this);
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
LatLng sydney = new LatLng(0.0, 0.0);
mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in India"));
mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}
#Override
public void onDenied(int i, String[] strings) {
}
#Override
public void onGranted(int i, String[] strings) {
}
-----------------------------------------------------
LATEST Calling Api USing Retrofit
Api Call USING RETROFIT With GET & POST
-----------------------------------------------------
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
implementation "com.android.support:cardview-v7:28.0.0"
implementation 'com.android.support:recyclerview-v7:28.0.0'
implementation 'com.squareup.picasso:picasso:2.71828'
implementation 'com.google.code.gson:gson:2.8.5'
implementation 'com.squareup.retrofit2:retrofit:2.4.0'
implementation 'com.squareup.retrofit2:converter-gson:2.4.0'
1] GET API WITH DISPLAY DATA IN RECYCLERVIEW :-
ApiInterface
import retrofit2.Call;
import retrofit2.http.GET;
public interface ApiInterface
{
#GET("/photos")
Call<List<RetroPhoto>> getAllPhotos();
}
RestApiClient
mport retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RestApiClient {
private static Retrofit retrofit;
private static final String BASE_URL = "https://jsonplaceholder.typicode.com";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new retrofit2.Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
MainActivity
public class MainActivity extends AppCompatActivity {
private CustomAdapter adapter;
private RecyclerView recyclerView;
ProgressDialog progressDoalog;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressDoalog = new ProgressDialog(MainActivity.this);
progressDoalog.setMessage("Loading....");
progressDoalog.show();
/*Create handle for the RetrofitInstance interface*/
ApiInterface service = RestApiClient.getRetrofitInstance().create(ApiInterface.class);
Call<List<RetroPhoto>> call = service.getAllPhotos();
call.enqueue(new Callback<List<RetroPhoto>>() {
#Override
public void onResponse(Call<List<RetroPhoto>> call, Response<List<RetroPhoto>> response) {
progressDoalog.dismiss();
generateDataList(response.body());
}
#Override
public void onFailure(Call<List<RetroPhoto>> call, Throwable t) {
progressDoalog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
}
});
}
/*Method to generate List of data using RecyclerView with custom adapter*/
private void generateDataList(List<RetroPhoto> photoList) {
recyclerView = findViewById(R.id.customRecyclerView);
adapter = new CustomAdapter(this, photoList);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(MainActivity.this);
recyclerView.setLayoutManager(layoutManager);
recyclerView.setAdapter(adapter);
}
}
activity_main
<android.support.v7.widget.RecyclerView
android:layout_width="match_parent"
android:id="#+id/customRecyclerView"
android:layout_height="match_parent"
/>
custom_row
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="horizontal"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content">
<ImageView
android:id="#+id/coverImage"
android:layout_width="80dp"
android:layout_height="80dp" />
<TextView
android:id="#+id/title"
android:textSize="15dp"
android:gravity="center_vertical"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
</LinearLayout>
RetroPhoto
import com.google.gson.annotations.SerializedName;
public class RetroPhoto {
#SerializedName("albumId")
private Integer albumId;
#SerializedName("id")
private Integer id;
#SerializedName("title")
private String title;
#SerializedName("url")
private String url;
#SerializedName("thumbnailUrl")
private String thumbnailUrl;
public RetroPhoto(Integer albumId, Integer id, String title, String url, String thumbnailUrl) {
this.albumId = albumId;
this.id = id;
this.title = title;
this.url = url;
this.thumbnailUrl = thumbnailUrl;
}
public Integer getAlbumId() {
return albumId;
}
public void setAlbumId(Integer albumId) {
this.albumId = albumId;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getThumbnailUrl() {
return thumbnailUrl;
}
public void setThumbnailUrl(String thumbnailUrl) {
this.thumbnailUrl = thumbnailUrl;
}
}
CustomAdapter
import android.content.Context;
import android.support.v7.widget.RecyclerView;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.TextView;
import com.squareup.picasso.Picasso;
import java.util.List;
public class CustomAdapter extends RecyclerView.Adapter<CustomAdapter.CustomViewHolder> {
private List<RetroPhoto> dataList;
private Context context;
public CustomAdapter(Context context,List<RetroPhoto> dataList){
this.context = context;
this.dataList = dataList;
}
class CustomViewHolder extends RecyclerView.ViewHolder {
public final View mView;
TextView txtTitle;
private ImageView coverImage;
CustomViewHolder(View itemView) {
super(itemView);
mView = itemView;
txtTitle = mView.findViewById(R.id.title);
coverImage = mView.findViewById(R.id.coverImage);
}
}
#Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
LayoutInflater layoutInflater = LayoutInflater.from(parent.getContext());
View view = layoutInflater.inflate(R.layout.custom_row, parent, false);
return new CustomViewHolder(view);
}
#Override
public void onBindViewHolder(CustomViewHolder holder, int position) {
holder.txtTitle.setText(dataList.get(position).getTitle());
Picasso.get().load(dataList.get(position).getThumbnailUrl()).into(holder.coverImage);
// Picasso.Builder builder = new Picasso.Builder(context);
// builder.downloader(new OkHttp3Downloader(context));
// builder.build().load(dataList.get(position).getThumbnailUrl())
// .placeholder((R.drawable.ic_launcher_background))
// .error(R.drawable.ic_launcher_background)
// .into(holder.coverImage);
}
#Override
public int getItemCount() {
return dataList.size();
}
}
2] POST API WITH LOGIN :-
ApiInterface
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.http.FieldMap;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.GET;
import retrofit2.http.POST;
public interface ApiInterface
{
#FormUrlEncoded
#POST("/login")
// void Login(#FieldMap Map<String, String> map, Callback<Login> callback);
Call<Login> Login(#FieldMap Map<String, String> map);
}
RestApiClient
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RestApiClient {
private static Retrofit retrofit;
private static final String BASE_URL = "http://wwwdemo.com/api/";
public static Retrofit getRetrofitInstance() {
if (retrofit == null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
progressDoalog = new ProgressDialog(MainActivity.this);
progressDoalog.setMessage("Loading....");
progressDoalog.show();
Map<String, String> map = new HashMap<>();
map.put("email", edit_email.getText().toString());
map.put("password", edit_password.getText().toString());
map.put("device_type", "android");
map.put("device_token", "dfgdf");
ApiInterface service = RestApiClient.getRetrofitInstance().create(ApiInterface.class);
Call<Login> call = service.Login(map);
call.enqueue(new Callback<Login>() {
#Override
public void onResponse(Call<Login> call, Response<Login> response) {
progressDoalog.dismiss();
if (response.body().getStatus().equals("success")) {
Toast.makeText(MainActivity.this, "Login Successfully", Toast.LENGTH_SHORT).show();
Log.d("login", "===== Success ====");
} else {
Toast.makeText(MainActivity.this, "Login Denied!", Toast.LENGTH_SHORT).show();
Log.d("login", "===== Fail ====");
}
}
#Override
public void onFailure (Call < Login > call, Throwable t){
progressDoalog.dismiss();
Toast.makeText(MainActivity.this, "Something went wrong...Please try later!", Toast.LENGTH_SHORT).show();
Log.d("login", "===== Failure ====");
}
});
}
OTHER TIP
1 pass header is require token only.
#Header("Authorization") String Authorization
2 to pass parameter vie Hasmap
Map<String, String> map = new HashMap<>();
#FieldMap Map<String, String> map
3 image upload with input
#Multipart
#POST("api")
Call<Upload> uploadapi(#Header("Authorization") String token, #Part List<MultipartBody.Part> files, #PartMap Map<String, RequestBody> map);
ArrayList<MultipartBody.Part> multipart = new ArrayList<>();
Map<String, RequestBody> map = new HashMap<>();
map.put("key", RequestBody.create(MediaType.parse("text/plain"), value));
multipart.add(Utility.prepareFilePart(Activity.this, "document_file", picturePath));
public static MultipartBody.Part prepareFilePart(Context context, String partName, String filePath) {
if(filePath!=null) {
File file = new File(filePath);
Log.d("TAG", "prepareFilePart: " + filePath);
// RequestBody requestBody = RequestBody.create(MediaType.parse(getContentResolver().getType(Uri.fromFile(file))), file);
// Libaray Required
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
// Multipart Camera and Gallery
// RequestBody requestBody = RequestBody.create(MediaType.parse(context.getContentResolver().getType(FileProvider.getUriForFile(context, "com.sine.provider", file))), file);
return MultipartBody.Part.createFormData(partName, file.getName(), requestBody);
}
else {
return MultipartBody.Part.createFormData(partName,"");
}
}
4] void Login(#FieldMap Map<String, String> map, Callback<Login> callback);
RetrofitClient.getInstance().getmRestClient().Login(map, new Callback<Login>() {
#Override
public void success(Login loginResponse, Response response) {
}
}
#Override
public void failure(RetrofitError error) {
}
});
public class RetrofitClient {
private final static String TAG = RetrofitClient.class.getSimpleName();
private static final Object LOCK = new Object();
private static FinalWrapper<RetrofitClient> helperWrapper;
private final RestClient mRestClient;
private RetrofitClient() {
// Rest client without basic authorization
mRestClient = ServiceGenerator.createService(RestClient.class);
}
public static RetrofitClient getInstance() {
FinalWrapper<RetrofitClient> wrapper = helperWrapper;
if (wrapper == null) {
synchronized (LOCK) {
if (helperWrapper == null) {
helperWrapper = new FinalWrapper<>(new RetrofitClient());
}
wrapper = helperWrapper;
}
}
return wrapper.value;
}
public RestClient getmRestClient() {
return mRestClient;
}
ServiceGenerator
public class ServiceGenerator {
private ServiceGenerator() {
}
public static <S> S createService(Class<S> serviceClass) {
final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(Constant.CONNECTION_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(Constant.CONNECTION_TIMEOUT, TimeUnit.SECONDS);
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(Constant.BASE_URL)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(okHttpClient));
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
public static <S> S createService(Class<S> serviceClass, String username, String password) {
final OkHttpClient okHttpClient = new OkHttpClient();
okHttpClient.setReadTimeout(Constant.CONNECTION_TIMEOUT, TimeUnit.SECONDS);
okHttpClient.setConnectTimeout(Constant.CONNECTION_TIMEOUT, TimeUnit.SECONDS);
RestAdapter.Builder builder = new RestAdapter.Builder()
.setEndpoint(Constant.BASE_URL_USERS)
.setLogLevel(RestAdapter.LogLevel.FULL)
.setClient(new OkClient(okHttpClient));
if (username != null && password != null) {
// concatenate username and password with colon for authentication
final String credentials = username + ":" + password;
builder.setRequestInterceptor(new RequestInterceptor() {
#Override
public void intercept(RequestFacade request) {
// create Base64 encodet string
String string = "Basic " + Base64.encodeToString(credentials.getBytes(), Base64.NO_WRAP);
request.addHeader("Accept", "application/json");
request.addHeader("Authorization", string);
}
});
}
RestAdapter adapter = builder.build();
return adapter.create(serviceClass);
}
public class FinalWrapper<T> {
public final T value;
public FinalWrapper(T value) {
this.value = value;
}
}
5
#GET("/place/autocomplete/json?")
void getplacesLocationList(#Query("input") String str_input,#Query("radius") String radius, #Query("key") String key, Callback<PlacesLocation> callback);
6 pass fist above only post method
interface
#Headers("Content-Type:application/json;charset=UTF-8")
#POST("api/")
Call<Response> get(#Body RequestBody requestBody);
Apiclient
public class ApiClient {
public static final String Tag = "ApiClient";
private static final int CONNECTION_TIMEOUT = 30; //seconds
private static final int READ_TIMEOUT = 20; //seconds
private static final int WRITE_TIMEOUT = 20; //seconds
private static MediaType MEDIA_TYPE_TEXT = MediaType.parse("text/plain");
private static MediaType MEDIA_TYPE_IMAGE = MediaType.parse("image/*");
private static Retrofit retrofit = null;
private static Gson gson;
public static Retrofit getClient() {
if (retrofit == null) {
OkHttpClient okHttpClient;
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
okHttpClient = new OkHttpClient().newBuilder().connectTimeout
(CONNECTION_TIMEOUT,
TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS).writeTimeout(WRITE_TIMEOUT,
TimeUnit.SECONDS).addInterceptor(interceptor).build();
} else {
okHttpClient = new OkHttpClient().newBuilder().connectTimeout
(CONNECTION_TIMEOUT,
TimeUnit.SECONDS)
.readTimeout(READ_TIMEOUT, TimeUnit.SECONDS).writeTimeout(WRITE_TIMEOUT,
TimeUnit.SECONDS).build();
}
retrofit = new Retrofit.Builder()
.client(okHttpClient)
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create())
.baseUrl(BASE_URL)
.build();
}
return retrofit;
}
#NonNull
public static RequestBody makeTextRequestBody(Object stringData) {
return RequestBody.create(MEDIA_TYPE_TEXT, String.valueOf(stringData));
}
#NonNull
public static RequestBody makeGSONRequestBody(Object jsonObject) {
if (gson == null) {
gson = new Gson();
}
return RequestBody.create(MEDIA_TYPE_TEXT, gson.toJson(jsonObject));
}
#NonNull
public static String JSONResponse(Object jsonObject) {
if (gson == null) {
gson = new Gson();
}
String params = gson.toJson(jsonObject);
return params;
}
#NonNull
public static RequestBody makeJSONRequestBody(JSONObject jsonObject) {
String params = jsonObject.toString();
return RequestBody.create(MEDIA_TYPE_TEXT, params);
}
public static JSONObject JSONObject(Object jsonObject) {
if (gson == null) {
gson = new Gson();
}
try {
return new JSONObject(String.valueOf(gson.toJsonTree(jsonObject)
.getAsJsonObject()));
} catch (JSONException e) {
AppLog.handleException(Tag, e);
}
return null;
}
}
try{
JSONObject jsonObject = new JSONObject();
jsonObject.put(key, "");
jsonObject.put(key, "");
jsonObject.put(key, "");
jsonObject.put(key, "");
} catch (JSONException e) {
}
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
Call<Response> aaa = apiInterface.apiname(ApiClient
.makeJSONRequestBody(jsonObject));
aaa.enqueue(new Callback<Response>() {
#Override
public void onResponse(Call<Response> call, Response<Response> response) {
}
}
#Override
public void onFailure(Call<Response> call, Throwable t)
{
}
});

Categories

Resources