Unable to call api using retrofit in android - java

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

Related

Retrofit call to Spotify API returns a 404 error

Am using retrofit2 to try to connect to Spotify. For now I am just logging the result code to see if it works. When I remove the "Authorization" Header/Parameter from my api call, it gives me a 401 error, indicating that I was not authorized. When I add the Authorization parameter and pass the access token, it gives me 404 error, indicating "not found". I am inexperienced with this stuff, but nonetheless this confuses me, please send thoughts/suggestions.
import static com.example.spotifyapp1.spotifyconstants.Constants.CLIENT_ID;
import static com.example.spotifyapp1.spotifyconstants.Constants.REDIRECT_URI;
import static com.example.spotifyapp1.spotifyconstants.Constants.REQUEST_CODE;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.appcompat.app.AppCompatActivity;
import com.example.spotifyapp1.data.RetrofitInstance;
import com.example.spotifyapp1.data.SpotifyApi;
import com.example.spotifyapp1.databinding.ActivityMainBinding;
import com.spotify.sdk.android.auth.AuthorizationClient;
import com.spotify.sdk.android.auth.AuthorizationRequest;
import com.spotify.sdk.android.auth.AuthorizationResponse;
import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;
import retrofit2.Retrofit;
public class MainActivity extends AppCompatActivity {
private ActivityMainBinding binding;
Retrofit retrofit = RetrofitInstance.getRetrofitInstance();
SpotifyApi spotifyApi = retrofit.create(SpotifyApi.class);
Call<Response<String>> mainCall;
String accessToken;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = ActivityMainBinding.inflate(getLayoutInflater());
View view = binding.getRoot();
setContentView(view);
AuthorizationRequest.Builder builder = new AuthorizationRequest.Builder(CLIENT_ID, AuthorizationResponse.Type.TOKEN, REDIRECT_URI);
AuthorizationRequest request = builder.setScopes(new String[]{"app-remote-control","streaming"}).build();
AuthorizationClient.openLoginActivity(this,REQUEST_CODE,request);
binding.setVolumeButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
mainCall.enqueue(
new Callback<Response<String>>() {
#Override
public void onResponse(Call<Response<String>> call, Response<Response<String>> response) {
//Log.d("MainActivity",String.format("tokenAtCall:%s",accessToken));
Log.d("MainActivity", String.format("onResponse: code..%d",response.code()));
}
#Override
public void onFailure(Call<Response<String>> call, Throwable t) {
Log.d("MainActivity", "onFailure");
}
}
);
}
});
}
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode,resultCode,intent);
if (requestCode == REQUEST_CODE) {
AuthorizationResponse response = AuthorizationClient.getResponse(resultCode,intent);
switch (response.getType()) {
case TOKEN:
//Log.d("MainActivity", "token");
accessToken = response.getAccessToken();
//Log.d("MainActivity",String.format("token:%s",accessToken));
mainCall = spotifyApi.setVolume("Bearer " + accessToken,50,null);
case ERROR:
//Log.d("MainActivity", "error");
default:
//Log.d("MainActivity", "default");
}
}
}
}
Here I use the spotify.android:auth library to authenticate with spotify. The authentication appears to work as it provides me with an access token, which I then attempt to pass into the call, unsuccessfully.
import retrofit2.Call;
import retrofit2.Response;
import retrofit2.http.Header;
import retrofit2.http.PUT;
import retrofit2.http.Query;
public interface SpotifyApi {
#PUT("/me/player/volume")
Call<Response<String>> setVolume(
#Header("Authorization") String authorization,
#Query("volume_percent") int volumePercent,
#Query("device_id") String deviceId
);
}
Here's my api
import static com.example.spotifyapp1.spotifyconstants.Constants.BASE_URL;
import retrofit2.Retrofit;
import retrofit2.converter.gson.GsonConverterFactory;
public class RetrofitInstance {
public static Retrofit getRetrofitInstance() {
Retrofit retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
return retrofit;
}
}
and my retrofit
I found the answer! The "/v1" part of the URL needed to be on the endpoint rather than in the base URL, despite the documentation seemingly stating otherwise. Confusing and frustrating!

Im getting this error while trying to get data from JSON

package com.joshbradley.pokemonapp.activities;
import android.annotation.SuppressLint;
import android.os.Bundle;
import android.widget.ImageView;
import android.widget.TextView;
import androidx.appcompat.app.AppCompatActivity;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import com.android.volley.Request;
import com.android.volley.RequestQueue;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.JsonArrayRequest;
import com.android.volley.toolbox.StringRequest;
import com.android.volley.toolbox.Volley;
import com.joshbradley.pokemonapp.R;
import com.joshbradley.pokemonapp.adapters.Adapter;
import com.joshbradley.pokemonapp.helperclass.HelperClass;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.security.SecureRandom;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;
public class HomeScreen extends AppCompatActivity {
//VARIABLES
RecyclerView recyclerView;
List<HelperClass> helperClasses;
Adapter adapter;
private static String JSON_URL_TEST = "https://pokeapi.co/api/v2/pokemon?limit=151";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home_screen);
//RECYCLER AND VIEW
recyclerView = findViewById(R.id.home_screen_recycler);
helperClasses = new ArrayList<>();
//CALLING EXTRACT DATA METHOD
extractData();
}
//EXTRACT DATA & REQUESTS
private void extractData() {
RequestQueue queue = Volley.newRequestQueue(this);
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, "https://pokeapi.co/api/v2/pokemon?limit=151", null, new Response.Listener<JSONArray>() {
#Override
public void onResponse(JSONArray response) {
for (int i = 0; i < response.length(); i++){
try {
JSONObject jsonObject = response.getJSONObject(i);
HelperClass helperClass = new HelperClass();
helperClass.setName(jsonObject.getString("name"));
helperClass.setImageUrl(jsonObject.getString("url"));
helperClasses.add(helperClass);
} catch (JSONException e) {
e.printStackTrace();
}
}
//ADAPTER AND LAYOUT MANAGER
recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
adapter = new Adapter(getApplicationContext(), helperClasses);
recyclerView.setAdapter(adapter);
}
// ERROR RESPONSE
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
queue.add(jsonArrayRequest);
}
}
// MY ERROR
com.android.volley.ParseError: org.json.JSONException: Value {"count":1154,"next":"https:\/\/pokeapi.co\/api\/v2\/pokemon?offset=151&limit=151","previous":null,"results":[{"name":"bulbasaur","url":"https:\/\/pokeapi.co\/api\/v2\/pokemon\/1\/"},{"name":"ivysaur","url":"https:\/\/pokeapi.co\/api\/v2\/pokemon\/2\/"},{"name":"venusaur","url":"https:\/\/pokeapi.co\/api\/v2\/pokemon\/3\/"},
In your extractData() method you have the following which implies that you are expecting the service response to be a JSONArray:
JsonArrayRequest jsonArrayRequest = new JsonArrayRequest(Request.Method.GET, ...
If you look at the body of the Exception you will see that the service is returning an object (which contains an array).
{ "count":1154
, "next":"https:\/\/pokeapi.co\/api\/v2\/pokemon?offset=151&limit=151"
, "previous":null
, "results":[ ... some array of values]
... you cut it off so there may be more fields ...
}
As such, it looks like you should accept a JSONObject and then extract the value associated with the results key. I'm not sure on the syntax but probably something like...
JsonObjectRequest request = new JsonObjectRequest(...
#Override
public void onResponse(JSONObject response) {
JSONArray results = response.getJSONArray("results");
....

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

why okhttp3 client.execute does not work?

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();
}

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)
}
}
});
}
}

Categories

Resources