why okhttp3 client.execute does not work? - java

I have a simple flask app that takes an image and return prediction from keras model
flask code
#app.route('/route', methods=['GET','POST'])
def rose():
model = load_model('model.h5')
model.compile(loss='categorical_crossentropy',
optimizer='rmsprop',
metrics=['accuracy'])
img_width, img_height = 128, 128
img = Image.open(request.files['file'])
if img.mode != "RGB":
img.convert("RGB")
img = img.resize((img_width, img_height))
x = image.img_to_array(img)
x = np.expand_dims(x, axis=0)
images = np.vstack([x])
classes = model.predict(images)
return str(classes )
I need to upload the image from an android application using camerakit-android: here is my code:
package com.bostanji.wardeh.ui.home;
import android.app.Activity;
import android.app.AlertDialog;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.media.Image;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.provider.MediaStore;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.Nullable;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.Observer;
import androidx.lifecycle.ViewModelProviders;
import com.bostanji.wardeh.R;
import com.wonderkiln.camerakit.CameraKitError;
import com.wonderkiln.camerakit.CameraKitEvent;
import com.wonderkiln.camerakit.CameraKitEventListener;
import com.wonderkiln.camerakit.CameraKitImage;
import com.wonderkiln.camerakit.CameraKitVideo;
import com.wonderkiln.camerakit.CameraView;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.net.Socket;
import java.util.List;
import java.util.concurrent.TimeUnit;
import dmax.dialog.SpotsDialog;
import okhttp3.MediaType;
import okhttp3.MultipartBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class HomeFragment extends Fragment {
private CameraView cameraView;
private Button button;
private AlertDialog waitingDialog;
private Dialog emptyDialog;
#Override
public void onResume() {
super.onResume();
cameraView.start();
}
#Override
public void onPause() {
super.onPause();
cameraView.stop();
}
public View onCreateView(#NonNull LayoutInflater inflater,
ViewGroup container, Bundle savedInstanceState) {
View root = inflater.inflate(R.layout.fragment_home, container, false);
cameraView = root.findViewById(R.id.camera);
button = root.findViewById(R.id.btn_detect);
waitingDialog = new SpotsDialog.Builder().setContext(getContext()).setMessage("Please wait").setCancelable(false).build();
cameraView.addCameraKitListener(new CameraKitEventListener() {
#Override
public void onEvent(CameraKitEvent cameraKitEvent) {
}
#Override
public void onError(CameraKitError cameraKitError) {
}
#Override
public void onImage(final CameraKitImage cameraKitImage) {
//waitingDialog.show();
Bitmap bitmap = cameraKitImage.getBitmap();
final byte[] img = cameraKitImage.getJpeg();
final Bitmap uploadMap = bitmap;
bitmap = Bitmap.createScaledBitmap(bitmap, cameraView.getWidth(), cameraView.getHeight(), false);
cameraView.stop();
waitingDialog.show();
final Handler handler = new Handler();
new Thread(){
#Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
String postUrl= "flaskapp.com/route";
final MediaType MEDIA_TYPE_JPEG = MediaType.parse("image/jpeg");
RequestBody req = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","rose.jpeg", RequestBody.create(img, MEDIA_TYPE_JPEG)).build();
Request request = new Request.Builder()
.url(postUrl)
.post(req)
.build();
try {
Response response = client.newCall(request).execute();
final String r = response.body().string();
handler.post(new Runnable() {
#Override
public void run() {
waitingDialog.dismiss();
Toast.makeText(getContext(), r, Toast.LENGTH_LONG).show();
}
});
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
}
}
}.start();
}
#Override
public void onVideo(CameraKitVideo cameraKitVideo) {
}
});
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
cameraView.start();
cameraView.captureImage();
}
});
return root;
}
}
once I click the button to take a picture and upload it the waiting dialog show and stays like this for ever.
P.S I don't need to send in the post request anything else other than the image and wait for the response

You use a deprecated constructor, which is error prone. It would be better to use final Handler handler = new Handler(Looper.getMainLooper());
Furthermore you just post your message when the post request was successful. If it's not successful, the waiting dialog will stay forever.
So it would update your code:
#Override
public void onImage(final CameraKitImage cameraKitImage) {
//waitingDialog.show();
Bitmap bitmap = cameraKitImage.getBitmap();
final byte[] img = cameraKitImage.getJpeg();
final Bitmap uploadMap = bitmap;
bitmap = Bitmap.createScaledBitmap(bitmap, cameraView.getWidth(), cameraView.getHeight(), false);
cameraView.stop();
waitingDialog.show();
final Handler handler = new Handler(Looper.getMainLooper());
new Thread(){
#Override
public void run() {
try {
OkHttpClient client = new OkHttpClient();
String postUrl= "flaskapp.com/route";
final MediaType MEDIA_TYPE_JPEG = MediaType.parse("image/jpeg");
RequestBody req = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file","rose.jpeg", RequestBody.create(img, MEDIA_TYPE_JPEG)).build();
Request request = new Request.Builder()
.url(postUrl)
.post(req)
.build();
Response response = client.newCall(request).execute();
final String r = response.body().string();
} catch (Exception e) {
Log.e('Camera', 'POST failed', e);
} finally {
handler.post(new Runnable() {
#Override
public void run() {
waitingDialog.dismiss();
Toast.makeText(getContext(), r, Toast.LENGTH_LONG).show();
}
});
}
}.start();
}

Related

Unable to call api using retrofit in android

Earlier i was able to call api using this code and but now it is not working
I'm not sure that what went wrong so if you can help it will be great.
i have uploaded my code files of circulareNotice.java,api.java and Retrofitclient.java
check the code and let me know that what is error and also solution of that error.
circularNotice.java
package com.example.college_connect_faculty;
import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.appcompat.app.AppCompatActivity;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
import android.text.TextWatcher;
import android.util.Log;
import android.view.View;
import android.view.textclassifier.ConversationActions;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.tasks.OnCompleteListener;
import com.google.android.gms.tasks.Task;
import com.google.firebase.FirebaseApp;
import com.google.firebase.messaging.FirebaseMessaging;
import com.google.firebase.messaging.RemoteMessage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
public class circularNotice extends AppCompatActivity {
EditText noticetxt,noticeTitle;
Button noticeBtn;
TextView stringLength;
String topic = "com.example.college_connect_faculty";
#Override
protected void onCreate(Bundle savedInstanceState) {
FirebaseApp.initializeApp(this);
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_circular_notice);
FirebaseMessaging.getInstance().subscribeToTopic("all");
noticetxt = findViewById(R.id.noticetxt);
noticeBtn = findViewById(R.id.noticeBtn);
stringLength = findViewById(R.id.stringLength);
noticeTitle = findViewById(R.id.noticeTitle);
noticetxt.addTextChangedListener(new TextWatcher() {
#Override
public void beforeTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void onTextChanged(CharSequence charSequence, int i, int i1, int i2) {
}
#Override
public void afterTextChanged(Editable editable) {
String s = noticetxt.getText().toString();
int l = s.length();
stringLength.setText(String.valueOf(l));
}
});
noticeBtn.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String notice = noticetxt.getText().toString();
String title = noticeTitle.getText().toString();
try {
Call<ResponseBody> call = RetrofitClient.getInstance().getApi().noticeUpload(notice, title);
call.enqueue(new Callback<ResponseBody>() {
#RequiresApi(api = Build.VERSION_CODES.Q)
#Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
try {
String s = response.body().string();
Toast.makeText(circularNotice.this, s, Toast.LENGTH_SHORT).show();
FcmNotificationsSender notificationsSender = new FcmNotificationsSender("/topics/all",
title, notice, getApplicationContext(), circularNotice.this);
notificationsSender.SendNotifications();
FirebaseMessaging firebaseMessaging = FirebaseMessaging.getInstance();
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
});
}catch (Exception e){
Toast.makeText(circularNotice.this,e.getMessage().toString(),Toast.LENGTH_SHORT).show();
}
}
});
}
}
api.java
package com.example.college_connect_faculty;
import java.util.TreeMap;
import okhttp3.MultipartBody;
import okhttp3.RequestBody;
import okhttp3.ResponseBody;
import retrofit2.Call;
import retrofit2.http.Field;
import retrofit2.http.FormUrlEncoded;
import retrofit2.http.Multipart;
import retrofit2.http.POST;
import retrofit2.http.Part;
public interface api {
#FormUrlEncoded
#POST("uploadSubjects.php")
Call<ResponseBody>uploadSubject(
#Field("semester") String semester,
#Field("branch") String branch,
#Field("subject")String subject
);
#FormUrlEncoded
#POST("showSubjects.php")
Call<ResultSubject> showSubject(
#Field("semester") String semester,
#Field("branch") String branch
);
#Multipart
#POST("filesUpload.php")
Call<ResponseBody> fileUpload(
#Part MultipartBody.Part fileName,
#Part("branch") RequestBody branch,
#Part("semester") RequestBody semester,
#Part("subject") RequestBody subject
);
#FormUrlEncoded
#POST("noticeUpload.php")
Call<ResponseBody> noticeUpload(
#Field("notice") String notice,
#Field("title") String title
);
}
Retrofitclient.java
package com.example.college_connect_faculty;
import android.content.Context;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitClient {
static Context context;
final String BASE_URL = "http://192.168.153.223/college_connect/";
private static RetrofitClient mInstance;
Retrofit retrofit;
RetrofitClient(){
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
public static synchronized RetrofitClient getInstance(){
if (mInstance==null){
mInstance = new RetrofitClient();
}
return mInstance;
}
public api getApi(){
return retrofit.create(api.class);
}
}
i have checked my ipv4. No problems in it
refer to this answer for a solution
https://stackoverflow.com/a/53984915/5035015
for more information regarding Network security configuration, refer to the below link
https://developer.android.com/training/articles/security-config

Problem to implement API in Android Studio

I need help to implement a list view from an API,
i need one more list to complete and make a get method.
This is for a project for faculty and i dont see solution on tutorials on internet
Here is code for information view :
package com.example.myapplication;
import android.content.pm.PackageManager;
import android.os.AsyncTask;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import com.google.android.gms.common.api.Api;
import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonParser;
import com.google.gson.annotations.SerializedName;
import com.google.gson.reflect.TypeToken;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.net.HttpCookie;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutionException;
import java.io.File;
import java.io.IOException;
import javax.net.ssl.HttpsURLConnection;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
public class TopScorer extends AppCompatActivity {
SearchView searchView;
ListView listView;
String teams[] = {};
ArrayAdapter<String> arrayAdapter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_top_scorer);
searchView = findViewById(R.id.search);
listView = findViewById(R.id.listview);
searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
ArrayList<String> teamsInf = new ArrayList<>();
#Override
public boolean onQueryTextSubmit(String query) {
API API = new API(query);
try {
API.execute().get();
teamsInf = API.getTeamsInfo();
arrayAdapter = new ArrayAdapter<String>(TopScorer.this, android.R.layout.simple_list_item_1, teamsInf);
listView.setAdapter(arrayAdapter);
} catch (ExecutionException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
return true;
}
#Override
public boolean onQueryTextChange(String newText) {
return true;
}
});
}
public class API extends AsyncTask {
String teamName;
ArrayList<String> teamsInfo;
public API(String name) {
this.teamsInfo = new ArrayList<>();
}
#Override
protected Object doInBackground(Object[] objects) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://heisenbug-premier-league-live-scores-v1.p.rapidapi.com/api/premierleague/team?name="+this.teamName)
.get()
.addHeader("X-RapidAPI-Key", "6ad8dfcfcbmshb4a45a22532e4a1p1efecajsnc2fb433de0da")
.addHeader("X-RapidAPI-Host", "heisenbug-premier-league-live-scores-v1.p.rapidapi.com")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NonNull Call call, #NonNull IOException e) {
Toast.makeText(TopScorer.this, "Error", Toast.LENGTH_SHORT).show();
}
#Override
public void onResponse(#NonNull Call call, #NonNull Response response) throws IOException {
int index=1;
String myResult = response.body().string();
Gson gson = new Gson();
Data responseResult=gson.fromJson(myResult, Data.class);
for (lst l : responseResult.Data())
{
Log.d(TAG, "Liverpool: " + l.getTeam());
teamsInfo.add(String.valueOf(index) + ". " + l.getPlayed() + ": " + l.getWin());
teamsInfo.add("Draws : " + l.getDraw());
teamsInfo.add("Loss : " + l.getLoss());
teamsInfo.add("Goals Against : " + l.getGoalsAgainst());
teamsInfo.add("Goals For : " + l.getGoalsFor());
teamsInfo.add("Points : " + l.getPoints());
teamsInfo.add("");
index++;
}
}
});
return null;
}
public ArrayList<String> getTeamsInfo()
{
return this.teamsInfo;
}
}
}
and here is Data Class code:
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class Data {
private String team;
private String played;
private String win;
private String draw;
private String loss;
private String goalsFor;
private String goalsAgainst;
private String points;
public String getTeam() {
return this.team;
}
public String getPlayed() {
return this.played;
}
public String getWin() {
return this.win;
}
public String getDraw() {
return this.draw;
}
public String getLoss() {
return this.loss;
}
public String getGoalsFor() {
return this.goalsFor;
}
public String getGoalsAgainst() {
return this.goalsAgainst;
}
public String getPoints() {
return this.points;
}
public Data fromJson(JSONObject jsonObject) {
Data team = new Data();
try {
team.team = jsonObject.getString("team");
team.played = jsonObject.getString("played");
team.win = jsonObject.getString("win");
team.draw = jsonObject.getString("draw");
team.loss = jsonObject.getString("loss");
team.goalsFor = jsonObject.getString("goalsFor");
team.goalsAgainst = jsonObject.getString("goalsAgainst");
team.points = jsonObject.getString("points");
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return team;
}
}
can anyone help me, i prefered to implement api respone with okhttp code

Oauth2 doesnt open an browser and a token in an android app

Trying to use the Oauth authorization flow in an andoid app using java. No browser opened needed for authorizing. I don't know if i should ask here or on the api's website
permission for internet is granted in manifest.xml
MainActivity.java:
import android.os.Bundle;
import android.util.Log;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button RankConfirm = findViewById(R.id.UsernameConfirm);
RankConfirm.setOnClickListener(v -> {
final EditText username_box = findViewById(R.id.OsuUsername);
final String Username = username_box.getText().toString();
final TextView RankView = findViewById(R.id.RankView);
API_Response.UpdateRank(Username,RankView);
});}
}
API.java
import android.util.Log;
import android.widget.TextView;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class API {
public static void UpdateRank(String Username, TextView RankView) {
Thread NetworkThread = new Thread ("NetworkThread"){
private volatile String Rank = "nic";
public void run() {
OkHttpClient client1 = new OkHttpClient();
Request request1 = new Request.Builder()
.url("https://osu.ppy.sh/oauth/authorize/?client_id=14403&redirect_uri=https://google.com&response_type=code&scope=public")
.build();
try {
Response response1 = client1.newCall(request1).execute();
String Code = response1.body().string();
Log.e("Debug", Code);
} catch (IOException e) {
Log.e("Debug", "IO exception1");
}```
Realized i was doing it completly wrong and i should have used a WebView

Use Json in Fragment (textView) from OkHttp Request in seperate class

If the button in DietFragment is pressed, it runs the getJson() method in HttpRequestDietPlan. Afterwards the Json(mealId, title) is used in the DietFragment.
Problem: DietFragment doesn't wait for the Request to finish.
Future isn't possible because lowest Android version needs to be 4.4
DietFragment
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class DietFragment extends Fragment {
Button button;
TextView mealOne;
public int mealId;
public DietPlan dietPlan = new DietPlan();
HttpRequestDietPlan hrt = new HttpRequestDietPlan();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_diet, null);
ET = rootView.findViewById(R.id.targetCalories_Input);
Tv1 = rootView.findViewById(R.id.targetCalories_Output);
button = rootView.findViewById(R.id.testButton);
mealOne = rootView.findViewById(R.id.meal1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hrt.getJson();
// java.lang.IllegalMonitorStateException: object not locked by thread before wait()
mealId = hrt.dietPlan.meals.get(0).mealId;
title = hrt.dietPlan.meals.get(0).title;
mealOne.setText(title);
}
});
return rootView;
}
}
HttpRequestDietPlan
import android.os.Build;
import android.support.annotation.RequiresApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpRequestDietPlan {
public DietPlan dietPlan = new DietPlan();
public final CompletableFuture<Response> future = new CompletableFuture<>();
public void getJson() {
OkHttpClient client = new OkHttpClient();
final Request request = new Request.Builder()
.addHeader("X-RapidAPI-Host", "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com")
.addHeader("X-RapidAPI-Key", "KEY_KEY_KEY")
.url("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/mealplans/generate?timeFrame=day&targetCalories=2000")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
call.cancel();
e.printStackTrace();
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
} else {
try {
String jsonData = response.body().string();
JSONObject json = new JSONObject(jsonData);
JSONArray arrayMeals = json.getJSONArray("meals");
for (int i = 0; i < arrayMeals.length(); i++) {
JSONObject object = arrayMeals.getJSONObject(i);
Meal meal = new Meal(
object.getInt("id"),
object.getString("title")
);
dietPlan.meals.add(meal);
System.out.println(meal);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}
});
}
}
Here are some suggestions:
You don't need to create a new OkHttpClient at each call, so I moved it outside the method.
Then you can pass a callback (CallHandler) to be notified when the result of the call will be available, and update your data after the result is received.
One more thing, about the deserialization, I suggest you to use a library (https://github.com/google/gson) to deserialize your json response to an instance of a class.
PS: I didn't test this code, this is just a implementation suggestion.
Fragment:
import android.os.Bundle;
import android.support.annotation.Nullable;
import android.support.v4.app.Fragment;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
public class DietFragment extends Fragment {
Button button;
TextView mealOne;
public int mealId;
public DietPlan dietPlan = new DietPlan();
HttpRequestDietPlan hrt = new HttpRequestDietPlan();
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_diet, null);
ET = rootView.findViewById(R.id.targetCalories_Input);
Tv1 = rootView.findViewById(R.id.targetCalories_Output);
button = rootView.findViewById(R.id.testButton);
mealOne = rootView.findViewById(R.id.meal1);
button.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
hrt.getJson(new HttpRequestDietPlan.CallHandler(
#Override
public void onFailure(Exception e) {
e.printStackTrace();
}
#Override
public void onSuccess(DietPlan dietPlan) {
mealId = hrt.dietPlan.meals.get(0).mealId;
title = hrt.dietPlan.meals.get(0).title;
mealOne.setText(title);
}
));
}
});
return rootView;
}
}
HttpRequestDietPlan:
import android.os.Build;
import android.support.annotation.RequiresApi;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.concurrent.CompletableFuture;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
public class HttpRequestDietPlan {
private OkHttpClient client = new OkHttpClient();
public interface CallHandler {
public void onSuccess(DietPlan dietPlan);
public void onFailure(Exception e);
}
public void getJson(CallHandler callHandler) {
final Request request = new Request.Builder()
.addHeader("X-RapidAPI-Host", "spoonacular-recipe-food-nutrition-v1.p.rapidapi.com")
.addHeader("X-RapidAPI-Key", "KEY_KEY_KEY")
.url("https://spoonacular-recipe-food-nutrition-v1.p.rapidapi.com/recipes/mealplans/generate?timeFrame=day&targetCalories=2000")
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
call.cancel();
e.printStackTrace();
callHandler.onFailure(e)
}
#Override
public void onResponse(Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
IOException e = new IOException("Unexpected code " + response);
callHandler.onFailure(e)
} else {
DietPlan dietPlan = new DietPlan();
// Deserialize with a library here
try {
String jsonData = response.body().string();
JSONObject json = new JSONObject(jsonData);
JSONArray arrayMeals = json.getJSONArray("meals");
for (int i = 0; i < arrayMeals.length(); i++) {
JSONObject object = arrayMeals.getJSONObject(i);
Meal meal = new Meal(
object.getInt("id"),
object.getString("title")
);
dietPlan.meals.add(meal);
System.out.println(meal);
}
} catch (JSONException e) {
e.printStackTrace();
}
callHandler.onSuccess(dietPlan)
}
}
});
}
}

My app crashes when using OkHttp

When I'm trying to send post request using OkHttp, the app on my phone (LG g3) crashes without an error.
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
RequestBody body = RequestBody.create(MediaType.parse("application/x-www-form-urlencoded"), "login=test&pasword=test");
Request request = new Request.Builder()
.url("http://myUrl")
.post(body)
.build();
try {
Response response = client.newCall(request).execute();
txtRequest.setText(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
});
What am I doing wrong?
you are executing the network call on main thread, this is the exception i guess you are getting. Use AsyncTask and your problem is solved. here is corrected version of your code.
Edited
package com.example.nisu.postrequest;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import java.io.IOException;
import okhttp3.MediaType;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
import okhttp3.Response;
public class SendPost extends AppCompatActivity {
Button btnSend;
TextView txtRequest;
OkHttpClient client = new OkHttpClient();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_send_post);
btnSend = (Button) findViewById(R.id.btnSend);
txtRequest = (TextView) findViewById(R.id.txtRequest);
btnSend.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
final Request request = new Request.Builder()
.url("http://httpbin.org/ip").get()
.build();
new MyAsyncTask().execute(request);
}
});
}
class MyAsyncTask extends AsyncTask<Request, Void, Response> {
#Override
protected Response doInBackground(Request... requests) {
Response response = null;
try {
response = client.newCall(requests[0]).execute();
} catch (IOException e) {
e.printStackTrace();
}
return response;
}
#Override
protected void onPostExecute(Response response) {
super.onPostExecute(response);
try {
txtRequest.setText(response.body().string());
} catch (IOException e) {
e.printStackTrace();
}
}
}
}

Categories

Resources