I'm trying to make an application to work with the SMS distribution
service API. To send a message, I need to complete a curl request
https://email:api_key#gate.smsaero.ru/v2/sms/send?numbers[]=79990000000&numbers[]=79990000001&text=your+text&sign=SMS Aero&channel=DIRECT
How can this be implemented in Android?
This may works
public void send(String url) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(url)
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
call.cancel();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
}
});
}
Related
I can't save data loaded from okhttp. What is wrong in my code. When I try to load data on Log app crashes. Please Help.
public class MainActivity extends AppCompatActivity {
private static final String URL = "https://chroniclingamerica.loc.gov/search/titles/results/?terms=michigan&format=json&page=5";
private String data;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
loadData();
Log.d("DATA", data);
}
private void loadData() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
data = response.body().string();
}
});
}
}
Explanation
The problem is around how your code is being executed (i.e sync vs async).
You call the method loadData() which will not set the class attribute data as you're expecting - it will set the attribute data once it gets a response however that function loadData will not wait for the response (i.e it doesn't block the current thread or execution code.) . Which means on the next line LOG.d("Data", data);, data has not been set, thus is null (and will crash your app).
Solution
If you just want to LOG data, then just move your log statement after you assign it on your onResponse callback.
private void loadData() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URL)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
// Some error has occurred
}
#Override
public void onResponse(Call call, Response response) throws IOException {
processData(response.body().string());
}
});
}
private void processData(String data) {
Log.d("DATA", data);
// To other stuff here given your value data.
}
I want to send a message from Android okhttp3 websocket client, not just echoing the messages coming from the server. here is my websocket class:
// Websocket
public final class EchoWebSocketListener extends WebSocketListener {
private static final int NORMAL_CLOSURE_STATUS = 1000;
#Override
public void onOpen(WebSocket webSocket, Response response) {
webSocket.send(message);
}
#Override
public void onMessage(WebSocket webSocket, String text) {
printer("text");
}
#Override
public void onClosing(WebSocket webSocket, int code, String reason) {
webSocket.close(NORMAL_CLOSURE_STATUS, null);
}
#Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
}
public void send(WebSocket webSocket) {
webSocket.send(finalMessage);
}
}
And here is how I call it from the onCreate method:
client= new OkHttpClient();
Request request = new Request.Builder().url(Url).build();
EchoWebSocketListener listener = new EchoWebSocketListener();
webso = myClient.newWebSocket(request, listener);
client.dispatcher().executorService().shutdown();
I tried to make an object to the class and call a function I named it 'send':
EchoWebSocketListener object = new EchoWebSocketListener ()
object.send(webso)
But that's not working?
recommend you this way RxWebSocket
My interface
#POST("/insert.php")
void login(Callback<Response> callback);
Java code
Retrofit adapter = new Retrofit.Builder()
.baseUrl(ROOT_URL) //Setting the Root URL
.addConverterFactory(GsonConverterFactory.create())
.build(); //Finally building the adapter
Register_Retrofit api = adapter.create(Register_Retrofit.class);
api.login( new Callback<Response>() {
public void onResponse(Call<Response> call, Response<Response> response) {
}
public void onFailure(Call<Response> call, Throwable t) {
}
});
Your login method return void, so you need to define it like this:
#POST("/insert.php")
Call<Void> login();
Then, to call the login method try this:
Retrofit adapter = new Retrofit.Builder()
.baseUrl(ROOT_URL) //Setting the Root URL
.addConverterFactory(GsonConverterFactory.create())
.build(); //Finally building the adapter
Register_Retrofit api = adapter.create(Register_Retrofit.class);
Call<Void> loginCall = api.login();
loginCall.enqueue(new Callback<Void>() {
public void onResponse(Call<Void> call, Response<Void> response) {
...
}
public void onFailure(Call<Void> call, Throwable t) {
...
}
});
In my android application I have to do some http request using android volley. If my request succeed everything's ok, the problem arise when I get an error and this error has status code 401. In this case I want to make some stuff and repeat the same request, same url and same parameters. Is there an official way to do that? If not, how can I get my params from error?
StringRequest req = new StringRequest(method, URL,
new Response.Listener<String>() {
#Override
public void onResponse(String response){
//VolleyLog.v("Response:%n %s", response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
NetworkResponse response = error.networkResponse;
if(response.statusCode == 401){
//make some stuff...
//here i want to resend my request
}
}
}) {
#Override
public Map<String, String> getHeaders() throws AuthFailureError {
//get headers
}
#Override
public Map<String, String> getParams() throws AuthFailureError {
//get params
}
};
// add the request object to the queue to be executed
ApplicationController.getInstance().addToRequestQueue(req);
Any help would be appreciated.
You can create the RetryPolicy to change default retry behavior, only specify timeout milliseconds, retry count arguments :
public class YourRequest extends StringRequest {
public YourRequest(String url, Response.Listener<String> listener,
Response.ErrorListener errorListener) {
super(url, listener, errorListener);
setRetryPolicy(new DefaultRetryPolicy(DefaultRetryPolicy.DEFAULT_TIMEOUT_MS,
DefaultRetryPolicy.DEFAULT_MAX_RETRIES, DefaultRetryPolicy.DEFAULT_BACKOFF_MULT));
}
}
the another way is estimate the VolleyError, re-execute the same request again when if was TimeoutError instance :
public static void executeRequest() {
RequestQueue.add(new YourRequest("http://your.url.com/", new Response.Listener<String>() {
#Override
public void onResponse(String response) {
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
if (error instanceof TimeoutError) {
// note : may cause recursive invoke if always timeout.
executeRequest();
}
}
}));
}
Hope this will help you
After modifying the request add the request in requestQueue.
Do it in ErrorListener.
I'm a beginner with littleproxy, how can I create a reverse proxy server?
My proxy get requests from clients and sends them to servers (servers only a regular site same as www.xxx.com contain only web page(in not rest) and proxy get response from server(a web page) and return to client.
For example, client url is localhost:8080/x, proxy maps it to www.myserver.com/xy and shows xy page for client. How can do it by using a filter or a httpservlet.
My http servlet will be as follow:
public class ProxyFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) req;
HttpProxyServer server =
DefaultHttpProxyServer.bootstrap()
.withPort(8080)
.withFiltersSource(new HttpFiltersSourceAdapter() {
public HttpFilters filterRequest(HttpRequest originalRequest, ChannelHandlerContext ctx) {
return new HttpFiltersAdapter(originalRequest) {
#Override
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
// TODO: implement your filtering here ????
return null;
}
#Override
public HttpResponse proxyToServerRequest(HttpObject httpObject) {
// TODO: implement your filtering here ????
return null;
}
#Override
public HttpObject serverToProxyResponse(HttpObject httpObject) {
// TODO: implement your filtering here ????
return httpObject;
}
#Override
public HttpObject proxyToClientResponse(HttpObject httpObject) {
// TODO: implement your filtering here ????
return httpObject;
}
};
}
})
.start();
}
public void init(FilterConfig config) throws ServletException {
}
public void destroy() {
}
}
LittleProxy uses Host header to do the routing. So simplest thing you can do is set Host as the real server in clientToProxyRequest method.
public HttpResponse clientToProxyRequest(HttpObject httpObject) {
if(httpObject instanceof FullHttpRequest) {
FullHttpRequest httpRequest = (FullHttpRequest)httpObject;
httpRequest.headers().remove("Host");
httpRequest.headers().add("Host", "myserver.com:8080");
}
return null;
}