I want to make this request in a fragment but the errors, as could I do?, thanks! I have many errors as .Builder() or OkHttpClient() when I want to implement it in a Fragment so I do not say any error in particular
String url = "https://freegeoip.net/json/"
Request mRequest = new Request.Builder()
.url(url)
.build();
Context mContext // A UI context
new OkHttpClient().newCall(mRequest).enqueue(new Callback() {
Handler mainHandler = new Handler(mContext.getApplicationContext().getMainLooper());
#Override
public void onResponse(Call call, Response response) {
String responseBody = null;
try {
responseBody = response.body().string();
} catch (final IOException e) {
mainHandler.post(new Runnable() {
#Override
public void run() {
// handle error
}
});
}
final String finalResponseBody = responseBody;
mainHandler.post(new Runnable() {
#Override
public void run() {
// handle response body
try {
JSONObject locationObject = new JSONObject(finalResponseBody);
} catch (JSONException e) {
e.printStackTrace();
}
}
});
}
#Override
public void onFailure(Call call, final IOException e) {
mainHandler.post(new Runnable() {
#Override
public void run() {
mNetworkListener.onNetworkError(e.getMessage());
}
});
}
});
Related
I'm building an app that calls to a webservice. When i use HttpUrlConnection class to make a request to the webservice then it works, but i replace with OkHttpClient to make request then my app can't connect to the service, OnFailure method is always called with content: "OnFailure: failed to connect to todolistmobileapp-env.ap-south-1.elasticbeanstalk.com/13.232.26.212 (port 80) after 4ms"
Anyone tell me what problem i'm getting into?
public class RequestRegisterAuthor extends AppNetworkRequest {
public static final String TAG = RequestRegisterAuthor.class.getSimpleName();
private final String url = ToDoRestAPIs.baseRemoteHostUrl + ToDoRestAPIs.registerAuthor;
public RequestRegisterAuthor(APICallbackListener apiCallbackListener, Object jsonRequestBody){
super(apiCallbackListener);
request = new Request.Builder().url(url)
.addHeader(AppNetworkRequest.CONTENT_TYPE, AppNetworkRequest.JSON_CONTENT_TYPE)
.post(RequestBody.create(MediaType.parse(JSON_CONTENT_TYPE), jsonRequestBody.toString()))
.build();
}
#Override
public void makeBackEndRequest() {
new Thread(this).start();
}
#Override
public void run() {
okHttpClient.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call,final IOException e) {
handler.post(new Runnable() {
#Override
public void run() {
apiCallbackListener.onFailureCallback(e.getMessage());
Log.e(TAG + "- OnFailure", e.getMessage());
}
});
}
#Override
public void onResponse(Call call, Response response) throws IOException {
try {
if(response.code() == 201){
responseObject = new GsonBuilder().create().fromJson(response.body().string(), Author.class);
}
else{
responseObject = new Error(response.code(), response.message());
}
} catch (JsonSyntaxException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
responseObject = new Error(101, e.getMessage()); // pre-defined code.
}
handler.post(new Runnable() {
#Override
public void run() {
apiCallbackListener.onSuccessCallback(REQUEST_TYPE.REQUEST_REGISTER_AUTHOR, responseObject);
}
});
}
});
} }
Here is the logcat:
https://pastebin.com/3CNsGrPm
I believe HttpUrlConnection uses OkHttp under the hood, could you post your code for both methods of connecting?
I'm using reactive for android for my request to backend, the problem is that the request sometimes work and sometimes not.
and i get the exception
io.reactivex.exceptions.UndeliverableException: android.os.NetworkOnMainThreadException
in Mainactivity onCreate() i'm calling GetServices function which sends a post request
Get services
public Observable<Response> GetService() {
return Observable.fromCallable(new Callable<Response>() {
#Override
public Response call() throws Exception {
return RequestHelper.GetRequest("getvendoractiveservices");
}
});
}
public void GetServices()
{
GetService().subscribeOn(Schedulers.io()).observeOn(AndroidSchedulers.mainThread()).subscribe(new Observer<Response>() {
#Override
public void onSubscribe(#io.reactivex.annotations.NonNull Disposable d) {
}
#Override
public void onNext(#io.reactivex.annotations.NonNull Response value) {
try {
Log.w("services",value.body().string()); //exception here
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onError(#io.reactivex.annotations.NonNull Throwable e) {
e.printStackTrace();
}
#Override
public void onComplete() {
}
});
}
my postrequest
public static String URI="http://192.168.137.1:4000/";
public static Response PostRequest(String api, FormBody formBody)
{
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url(URI+api)
.header("carmen-token", LoginActivity.token)
.post(formBody)
.build();
try {
return client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
I am implementing Helper class in Android studio to service Activity
public void getLastId()
{
//init OkHttpClient
OkHttpClient client = new OkHttpClient();
//backend url
Request request = new Request.Builder()
.url("http://192.168.1.102:8080/aquabackend/public/customers/lastid")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
try {
JSONObject jobject = new JSONObject(jsonData);
String id = jobject.getString("id");
//increment current id +1
String last_id = String.valueOf(Integer.parseInt(id)+1);
Log.i("new id", last_id);
} catch (Exception e) {
e.printStackTrace();
}
//Log.i("ok", response.body().string());
}
});
My function call in activity class
Helper helper = new Helper();
helper.getLastId();
//I want to get method to return lastId and then manipulate with the data
How can I make method return value of the id?
As it is an asynchronous process you won't be able to return a value from the method itself. However, you can use a callback to provide you the value when the asynchronous process has been completed. Below is an example of how you might want to do this.
public interface GetLastIdCallback {
void lastId(String id);
}
You would modify getLastId as follows:
public void getLastId(GetLastIdCallback idCallback) {
...
String last_id = String.valueOf(Integer.parseInt(id)+1);
idCallback.lastId(last_id);
...
}
Your Helper class usage would now look like this:
Helper helper = new Helper();
helper.getLastId(new GetLastIdCallback() {
#Override
public void lastId(String id) {
// Do something with your id
}
});
I'd suggest making your callback a bit more generic than I have suggested above. It could look like this:
public interface GenericCallback<T> {
void onValue(T value);
}
...
Helper helper = new Helper();
helper.getLastId(new GenericCallback<String>() {
#Override
public void onValue(String value) {
// Do something
}
});
If you used an interface like above you would be able to work with any return type.
Create a interface.
public interface Result{
void getResult(String id);
}
Now, pass interface to method as parameter.
Helper helper = new Helper();
helper.getLastId(new Result(){
#Override
void getResult(String id){
}
});
And In your method :
public void getLastId(final Result result)
{
//init OkHttpClient
OkHttpClient client = new OkHttpClient();
//backend url
Request request = new Request.Builder()
.url("http://192.168.1.102:8080/aquabackend/public/customers/lastid")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
try {
JSONObject jobject = new JSONObject(jsonData);
String id = jobject.getString("id");
//increment current id +1
String last_id = String.valueOf(Integer.parseInt(id)+1);
Log.i("new id", last_id);
result.getResult(last_id);
} catch (Exception e) {
e.printStackTrace();
}
//Log.i("ok", response.body().string());
}
});
You have to create interface for it.
public interface getResponse {
void getJsonResponse(final String id);
}
In Your code :
public void getLastId(fianl getResponse response)
{
//init OkHttpClient
OkHttpClient client = new OkHttpClient();
//backend url
Request request = new Request.Builder()
.url("http://192.168.1.102:8080/aquabackend/public/customers/lastid")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
}
#Override
public void onResponse(Call call, Response response) throws IOException {
String jsonData = response.body().string();
try {
JSONObject jobject = new JSONObject(jsonData);
String id = jobject.getString("id");
//increment current id +1
String last_id = String.valueOf(Integer.parseInt(id)+1);
Log.i("new id", last_id);
if(response!=null){
response.getJsonResponse(last_id)
}
} catch (Exception e) {
e.printStackTrace();
}
//Log.i("ok", response.body().string());
}
});
In Activity :
public class HomeActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Helper helper = new Helper();
helper.getLastId(new getResponse(){
#Override
void getJsonResponse(String id){
}
});
}}
}
I have a threading problem with Android okhttp Websockets. I am doing a chat application, where I need to write and read from our server using websocket.
I read in other posts that with Okhttp, I should use StrictMode.ThreadPolicy.Builder().permitAll() as it has some issues etc. I added it.
But I keep getting this error when I try to sendMessage:
W/System.err: android.os.NetworkOnMainThreadException
09-13 17:13:32.198 22766-22766/com.microsoft.translator
Note that I am sending Message on a different thread, not on main thread.
Here is my code. Appreciate any help.
create websocket :
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my_chat);
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
// lot other init stuff
createWebSocket();
}
private void createWebSocket() {
okHttpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(WSS_URL + token)
.build();
webSocketCall = WebSocketCall.create(okHttpClient, request);
webSocketCall.enqueue(this);
}
#Override
public void onOpen(WebSocket webSocket, Response response) {
try {
Log.d(TAG, "onOpen: " + response.message());
String message = createJsonMessage("Hello");
byte[] messageBytes = message.getBytes();
showToastOnUIThread("OnOpen sending message");
webSocket.sendMessage(WebSocket.PayloadType.TEXT, new Buffer().write(messageBytes));
this.webSocket = webSocket;
//startRepeatingTask();
} catch (IOException e) {
e.printStackTrace();
}
}
private void sendMessage(final String msgString) {
Runnable postMessageThread = new Runnable() {
#Override
public void run() {
String message = createJsonMessage(msgString);
byte[] messageBytes = message.getBytes();
try {
if (webSocket != null) {
try {
webSocket.sendMessage(WebSocket.PayloadType.TEXT, new Buffer().write(messageBytes));
} catch (IOException e) {
e.printStackTrace();
Toast.makeText(ChatActivity.this, e.getMessage(), Toast.LENGTH_SHORT).show();
} catch (Exception ex) {
ex.printStackTrace();
Toast.makeText(ChatActivity.this, ex.getMessage(), Toast.LENGTH_SHORT).show();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
};
postMessageThread.run();
}
I think this code is a simple example. If you don't use token to auth, you can remove addHeader.
OkHttpClient client = new OkHttpClient();
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("your_name_input", "your_value")
.build();
Request request = new Request.Builder()
.url("your_url")
.post(requestBody)
.addHeader("name_your_token", "your_token")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
#Override
public void onResponse(Call call, Response response) throws IOException {
final String yourResponse = response.body().string();
if(response.isSuccessful()){
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "Ok: "+yourResponse,Toast.LENGTH_SHORT).show();
}
});
}else{
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(MainActivity.this, "Ok: "+yourResponse,Toast.LENGTH_SHORT).show();
}
});
}
}
});
And you also add permission in manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
I think your code should be like this:
new Thread(new Runnable() {
public void run() {
// call send message here
}
}).start();
Or you can use Asyntask
Here is the scenario: I have an Activity, named MainActivity, calling a OkHttp wrapper class, named NetworkManager to perform network post in background:
// In MainActivity
NetworkManager manager = new NetworkManager();
try {
manager.post("http://www.example.com/api/", reqObj); // reqObj is a JSONObject
} catch(IOException ioe) {
Log.e(TAG, ioe.getMessage());
}
Then, in the NetworkManager, I perform the POST action in asynchronous mode:
public class NetworkManager {
static String TAG = "NetworkManager";
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
void post(String url, JSONObject json) throws IOException {
//RequestBody body = RequestBody.create(JSON, json);
try {
JSONArray array = json.getJSONArray("d");
RequestBody body = new FormEncodingBuilder()
.add("m", json.getString("m"))
.add("d", array.toString())
.build();
Request request = new Request.Builder()
.url(url)
.post(body)
.build();
// Asynchronous Mode
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
Log.e(TAG, e.toString());
// what should I put here?
}
#Override
public void onResponse(Response response) throws IOException {
Log.w(TAG, response.body().string());
// what should I put here?
}
});
} catch (JSONException jsone) {
Log.e(TAG, jsone.getMessage());
}
}
}
What I'm trying to achieve is to call a function in MainActivity after network POST is successful or failed. How can I achieve this?
You can create an interface with onFailure and onResponse then let YourActivity implement it. And, on NetworkManagertry to notify YourActivity using listener.
// MainActivity implements NetworkListener
NetworkManager manager = new NetworkManager();
manager.setOnNetWorkListener(this);
try {
manager.post("http://www.example.com/api/", reqObj); // reqObj is a JSONObject
} catch(IOException ioe) {
Log.e(TAG, ioe.getMessage());
}
void onFailure(Request request, IOException e) {
// call your activity methods
}
void onResponse(Response response) {
// call your activity methods
}
// ======NetworkManager class============
public class NetworkManager {
static String TAG = "NetworkManager";
public static final MediaType JSON = MediaType.parse("application/json; charset=utf-8");
OkHttpClient client = new OkHttpClient();
public NetworkListenerv listener;
public void setOnNetWorkListener(NetworkListener listener) {
this.listener = listener
}
// Asynchronous Mode
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Request request, IOException e) {
Log.e(TAG, e.toString());
// what should I put here?
if (listener != null) {
listener.onFailure(request, e);
}
}
#Override
public void onResponse(Response response) throws IOException {
Log.w(TAG, response.body().string());
// what should I put here?
if (listener != null) {
listener.onResponse(response);
}
}
});
// Your interface;
public interface NetworkListener {
void onFailure(Request request, IOException e);
void onResponse(Response response);
}