server availability checker in Android - java

I am trying to check internet connection of device first, if Internet is available...I need to check server is online or not. I have searched lot of in stackflow for it but there no where latest solution is available like below
1
2
but none of it is working properly as people comments and my trial. I am checking internet status of device with below code
public static boolean isInternetAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
boolean isActiveNetworkConnected = false;
if (connectivity != null) {
NetworkInfo info = connectivity.getActiveNetworkInfo();
if (info != null) {
if (info.getState() == NetworkInfo.State.CONNECTED) {
isActiveNetworkConnected = true;
} else {
isActiveNetworkConnected = false;
}
}
} else {
isActiveNetworkConnected = false;
}
return isActiveNetworkConnected;
}
Let me know anyone have proper solution which can check server available or not with this code.

After checking the internet connectivity, you can simply make a test API hit to check server status. Send the request to server if server respond ok, start next work or in-other case handle server not responding message for user.
Here is a sample using okhttp
public boolean isServerUp(){
private final OkHttpClient client = new OkHttpClient();
public void run() throws Exception {
Request request = new Request.Builder()
.url("your server url here")
.build();
client.newCall(request).enqueue(new Callback() {
#Override public void onFailure(Call call, IOException e) {
e.printStackTrace();
return false;
}
#Override public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) throw new IOException("Unexpected code " + response);
return true;
}
});
}
return false;
}

For checking the current status of the server after network checked, need to check if the response is not null

Related

How to Change API Base Url at Runtime(Retrofit,Android,Java)?

I need to change base url at run time.
I have login button and when login button click time i am called my login api
like below :
login api = http://192.168.0.61/api/authenticate
API_BASE_URL = http://192.168.0.61/api/
when i get success response from first api i get client server url for changing baseUrl.
CompanyUrlConfigEntity companyUrlConfigEntity = response.body();
like below :
String clientUrl = companyUrlConfigEntity.
getBaseUrl();
clientUrl = http://192.168.0.238/api/
In this project mainly for client or company based.So they have their own server.
Each company has using more than 20 api's.
So i need to change base url .
I am also checked below link for changing base url:
https://futurestud.io/tutorials/retrofit-2-how-to-change-api-base-url-at-runtime-2
and changed code like that
public static void changeApiBaseUrl(String newApiBaseUrl) {
API_BASE_URL = newApiBaseUrl;
builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new Gson()));
}
when i debugged and checked my baseUrl then it shows properly like below:
API_BASE_URL = http://192.168.0.238/api/
But when i call my customer api it shows the my first base url calling,
the url not changed.
expected customer api : http://192.168.0.238/api/customers
reality customer api : http://192.168.0.61/api/customers
I am also checked below link :
https://futurestud.io/tutorials/retrofit-2-how-to-use-dynamic-urls-for-requests
thats working , But each api need to pass fullPath url with each api like below:
#GET
public Call<ResponseBody> profilePicture(#Url String url);
But using this method , each api calling place i need to attach full path of url.
There is any other options? Please help me.
ServiceGenerator.class
public class ServiceGenerator {
public static String API_BASE_URL = "http://192.168.0.61/api/";
private static Retrofit retrofit;
private static OkHttpClient.Builder httpClient = new
OkHttpClient.Builder();
private static Retrofit.Builder builder =
new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new
Gson()));
private ServiceGenerator() {
}
public static void changeApiBaseUrl(String newApiBaseUrl) {
API_BASE_URL = newApiBaseUrl;
builder = new Retrofit.Builder()
.baseUrl(API_BASE_URL)
.addConverterFactory(new NullOnEmptyConverterFactory())
.addConverterFactory(ScalarsConverterFactory.create())
.addConverterFactory(GsonConverterFactory.create(new Gson()));
}
public static Retrofit retrofit() {
return retrofit;
}
public static <S> S createService(Class<S> serviceClass) {
return createService(serviceClass, null, null);
}
public static <S> S createService(Class<S> serviceClass,
final String authToken,
final ProgressListener progressListener) {
if (authToken != null) {
httpClient.addInterceptor(new Interceptor() {
#Override
public Response intercept(Chain chain) throws IOException {
Request original = chain.request();
final String headerValue = AUTHORIZATION_TYPE + authToken;
Request request = original.newBuilder()
.header(AUTHORIZATION_HEADER_KEY, headerValue)
.method(original.method(), original.body())
.build();
return chain.proceed(request);
}
});
}
addResponseProgressListener(progressListener);
if (BuildConfig.DEBUG) {
HttpLoggingInterceptor httpLoggingInterceptor = new
HttpLoggingInterceptor();
httpLoggingInterceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
httpClient.addInterceptor(httpLoggingInterceptor);
}
if (authToken != null) {
if (picasso == null) {
setUpPicasso(authToken);
}
}
OkHttpClient client = httpClient.build();
httpClient.connectTimeout(15, TimeUnit.SECONDS);
httpClient.readTimeout(2, TimeUnit.MINUTES);
httpClient.writeTimeout(2, TimeUnit.MINUTES);
retrofit = builder.client(client).build();
return retrofit.create(serviceClass);
}
}
LoginFragment.java
#OnClick(R.id.bt_login)
void onLogin() {
checkValidityOfUser();
}
private void checkValidityOfUser() {
final Login login = getLoginCredentials();
Call<CompanyUrlConfigEntity> callCheckValidity = dataProcessController.
getApiClient().
checkValidityOfUsers(login.getUsername());
callCheckValidity.enqueue(new Callback<CompanyUrlConfigEntity>() {
#Override
public void onResponse(Call<CompanyUrlConfigEntity> call,
Response<CompanyUrlConfigEntity> response) {
if (response.code() == 200) {
CompanyUrlConfigEntity companyUrlConfigEntity = response.body();
boolean status = companyUrlConfigEntity.isValidUser();
if (status) {
String baseUrls = companyUrlConfigEntity.
getBaseUrl();
baseUrls = baseUrls + "/api/";
ServiceGenerator.changeApiBaseUrl(baseUrls);
logins();
} else {
ToastHelper.show("please contact admin");
}
} else {
ToastHelper.show("" + response.code() + response.message());
}
}
#Override
public void onFailure(Call<CompanyUrlConfigEntity> call, Throwable t) {
ToastHelper.show("please contact admin");
}
});
}
private void logins() {
login = getLoginCredentials();
Call<Void> callLogin = dataProcessController.
getApiClient().
login(login);
callLogin.enqueue(new Callback<Void>() {
#Override
public void onResponse(Call<Void> call, Response<Void> response) {
if (response.code() == 200) {
} else if (response.code() == 401) {
}
}
#Override
public void onFailure(Call<Void> call, Throwable t) {
}
});
}
Base on your comments, I would say that you are correctly changing the API url on your builder, but that your second call still uses an instance of service where the url has not changed.
To explain a little more, from what I understand this is how everything gets executed:
when fragment is created, the apiClient is created and pointing to the first url
with dataProcessController.getApiClient() in your first call, you are getting the service that is pointing to the first url and then execute the call.
when the call is successful, you read the new url from result and update the ServiceGenerator with that new url. Then you execute the logins() method.
and in that method, you recall the dataProcessController.getApiClient() and do the second call with it. However, as you never redid apiClient = ServiceGenerator.createService(ApiClient.class);, the apiClient instance you are getting is still pointing to the first url, because it hasn't been notified that the url changed.
What I would try here, would be to change the method getApiClient() in your DataProcessController class to something like this:
public ApiClient getApiClient() {
apiClient = ServiceGenerator.createService(ApiClient.class);
return apiClient;
}
and see if this is work better.
Or if you don't want to regenerate the service inside that function, you can also do something like this:
public class DataProcessController {
private ApiClient apiClient = null;
private DataProcessController() {
regenerateClient();
}
public ApiClient getApiClient() { return apiClient; }
// add this to regenerate the client whenever url changes
public void regenerateClient() {
apiClient = ServiceGenerator.createService(ApiClient.class);
}
}
then, everytime you do change the url, do this:
ServiceGenerator.changeApiBaseUrl(baseUrls);
dataProcessController.regenerateClient();
and you should get a client that points to the correct url everytime you do dataProcessController.getApiClient()
https://segunfamisa.com/posts/firebase-remote-config
You should follow concept of firebase remote config. Here you dont need to store base Url in source code it will be retrieved from firebase config values which is stored at server of firebase.
// fetch
mRemoteConfig.fetch(3000)
.addOnCompleteListener(this, new OnCompleteListener<Void>() {
#Override
public void onComplete(Task<Void> task) {
if (task.isSuccessful()) {
// update your base url here.
} else {
//task failed
}
}
});

Handling HTTP 404 using Selenium WebDriver with Java

Clicking on a hyperlink is throwing me the below error.
Please suggest me how to handle this is below exception.
Use below code to check for the response code of the URL:
public static boolean getResponseCode(String chkurl) {
boolean validResponse = false;
try {
//Get response code of URL
HttpResponse urlresp = new DefaultHttpClient().execute(new HttpGet(chkurl));
int resp_Code = urlresp.getStatusLine().getStatusCode();
System.out.println("Response Code Is : "+resp_Code +" for "+chkurl);
if ((resp_Code == 404) || (resp_Code == 505)) {
validResponse = false;
} else {
validResponse = true;
}
} catch (Exception e) {
}
return validResponse;
}
I'm afraid there is no way to check do HTTP status code directly using Webdriver. You can use a HTTP client directly, but if the problem is a 500 code, or a 403, it can become unwieldy. We cover a more powerful technique using Mob Browser Proxy with WedDriver in our book:
http://selenium-webdriver-in-practice.github.io

Netty handler removing itself

I have a netty authentication handler that looks at the first message that comes in (HttpRequest),
If the request is authorized I then have the handler remove itself from the pipeline before sending the message upstream. However it seems that the next message still makes it to the handler. Is this expected?
Using netty 4.14
public void channelRead(ChannelHandlerContext ctx, Object obj) throws Exception {
if (!(obj instanceof HttpRequest)) {
//Do not authenticate unknown object types.
ReferenceCountUtil.release(obj);
return;
}
HttpRequest httpRequest = (HttpRequest)obj;
AuthenticatedInfo authenticatedInfo = Services.authenticationAuthority.authenticate(httpRequest, null);
// check access
if (authenticatedInfo.getMerchantId() == null) {
sendUnauthorized(ctx);
ReferenceCountUtil.release(obj);
} else {
ctx.pipeline().remove(this);
ctx.fireChannelRead(httpRequest);
}
}

calling some online service from GWT

I have this JavaScript code which is connecting with the service and sending back the result.
Now the requirement is to call the same service from Pure Java.
Below is the javascript code for calling the service.
If some one can guide me to convert this Javascript to Java in my GWT Application
Thanks
function verifyValidationSyntax(textToValidate)
{
var url = "https://validation-grammar.example.com/validation_grammar_service/rest/validation_step_validation";
var client = new XMLHttpRequest();
client.open("POST", url, false);
client.setRequestHeader("Content-Type", "text/plain");
client.send(textToValidate);
if (client.responseText==='true') {
return "true";
} else {
return "false";
}
}
I wont convert your code, But here is the sweetest example from docs
String url = "http://www.myserver.com/getData?type=3";
RequestBuilder builder = new RequestBuilder(RequestBuilder.GET, URL.encode(url));
try {
Request request = builder.sendRequest(null, new RequestCallback() {
public void onError(Request request, Throwable exception) {
// Couldn't connect to server (could be timeout, SOP violation, etc.)
}
public void onResponseReceived(Request request, Response response) {
if (200 == response.getStatusCode()) {
// Process the response in response.getText()
} else {
// Handle the error. Can get the status text from response.getStatusText()
}
}
});
} catch (RequestException e) {
// Couldn't connect to server
}
You may miss this in docs
To use the HTTP types in your application, you'll need to first inherit the GWT HTTP module by adding the following tag to your module XML file:
<inherits name="com.google.gwt.http.HTTP" />

Retrofit2 - Upload image to server give an Internal Server Error as response in android studio

I am trying to send image files from my android app to a back end server. On Postman, images are sent and response code:200 is received.
However, trying to send images from my android app using retrofit, I keep receiving response code:500 Internal Server Error. Here is my code:
public interface RetrofitInterface {
#Multipart
#POST("uploads/addImage")
Call<ResponseBody> uploadImage(#Part MultipartBody.Part image);
}
The NetworkClient
public class NetworkClient {
private static Retrofit retrofit;
public static Retrofit getRetrofit(){
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(20, TimeUnit.SECONDS)
.readTimeout(30, TimeUnit.SECONDS)
.writeTimeout(30, TimeUnit.SECONDS).build();
if(retrofit == null){
String BASE_URL = "https://addimage.herokuapp.com/";
retrofit = new Retrofit.Builder().baseUrl(BASE_URL).
addConverterFactory(GsonConverterFactory.create()).client(okHttpClient).build();
}
return retrofit;
}
}
And then the call
private void uploadImage(Uri imageUri){
File file = new File(imageUri.toString());
RequestBody requestBody = RequestBody.create(MediaType.parse("image/*"), file);
MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);
Retrofit retrofit = NetworkClient.getRetrofit();
RetrofitInterface retrofitInterface = retrofit.create(RetrofitInterface.class);
Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("UploadImage", "Yeepee!!! = "+response.message());
}else Log.d("UploadImage", "Response failure = "+response.message());
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
// "Connection Timeout";
Log.e("UploadImage", "Connection Timeout");
} else if (t instanceof IOException) {
// "Timeout";
Log.e("UploadImage", "Timeout");
} else {
//Call was cancelled by user
if(call.isCanceled()) {
Log.e("UploadImage", "Call was cancelled forcefully");
} else {
//Generic error handling
Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
}
}
}
});
}
I am not sure if it's a server error since images upload successfully from Postman. I am very confused and I am not sure what I am doing wrong.
According to your Postmen screen shot there is no key for image file can you try like below
remove this line
MultipartBody.Part body = MultipartBody.Part.createFormData("file", "image.jpg", requestBody);
And add this one
MultipartBody.Part body = MultipartBody.Part.createFormData("", "image.jpg", requestBody);
Generally 500 Internal Server error means there is something wrong in the server, but if the Postman is giving 200 that means the server part is OK, there's something wrong in your code.
try changing this line
File file = new File(imageUri.toString());
to this
File file = new File(imageUri.path);
And also make sure that the key name you used is same as the response key name
Thank you all for your responses. I have been able to resolve and it turned out to be a conflict between my request body and what the server was expecting.
For my case, I was sending a different mime-type(a .jpg), where the server developer made the server look for .jpeg and .png.
This was how I got to see the error and resolve the conflict.
Call<ResponseBody> call = retrofitInterface.uploadImage(body);
call.enqueue(new Callback<ResponseBody>() {
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
if(response.isSuccessful()){
Log.d("UploadImage", "Yeepee!!! = "+response.message());
}else {
Log.d("UploadImage", "Response failure = "+response.message());
try {
Log.d("UploadImage", "Response failure = "+response.errorBody().string());
} catch (IOException e) {
Log.d("UploadImage", "IOException = "+e.getMessage());
}
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
if (t instanceof SocketTimeoutException) {
// "Connection Timeout";
Log.e("UploadImage", "Connection Timeout");
} else if (t instanceof IOException) {
// "Timeout";
Log.e("UploadImage", "Timeout");
} else {
//Call was cancelled by user
if(call.isCanceled()) {
Log.e("UploadImage", "Call was cancelled forcefully");
} else {
//Generic error handling
Log.e("UploadImage", "Network Error :: " + t.getLocalizedMessage());
}
}
}
});
The response.errorBody().string() got the error message from the server and I was able to resolve the conflict.

Categories

Resources