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();
}
}
}
}
Related
Hello Guys I received a a big problem in my project. I make the OkHttp request i receive response from server all is perfect. the problem is why i can't display data, i made a model item in xml and listview(this is the required view) and when i acces the page is blank.
Can anyone help me with this issue?
code for page is the following:
package com.example.socceraplication;
import static android.content.ContentValues.TAG;
import androidx.appcompat.app.AppCompatActivity;
import androidx.annotation.NonNull;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.widget.ArrayAdapter;
import android.widget.ListAdapter;
import android.widget.ListView;
import android.widget.SearchView;
import android.widget.SimpleAdapter;
import android.widget.Toast;
import com.google.gson.Gson;
import java.util.ArrayList;
import java.util.HashMap;
import java.io.IOException;
import java.util.List;
import java.util.concurrent.ExecutionException;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import okhttp3.Call;
import okhttp3.Callback;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.ResponseBody;
import java.util.ArrayList;
public class TeamInfo extends AppCompatActivity {
private ListView lv;
ArrayList<HashMap<String, String>> resultList;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_team_info);
resultList = new ArrayList<>();
lv = (ListView) findViewById(R.id.list);
new GetContacts().execute();
}
private class GetContacts extends AsyncTask<Void, Void, Void>{
#Override
protected void onPreExecute() {
super.onPreExecute();
Toast.makeText(TeamInfo.this,"Json Data is downloading",Toast.LENGTH_LONG).show();
}
#Override
protected Void doInBackground(Void... arg0) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://heisenbug-premier-league-live-scores-v1.p.rapidapi.com/api/premierleague/team?name=Liverpool")
.get()
.addHeader("X-RapidAPI-Key", "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx")
.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) {
call.cancel();
}
#Override
public void onResponse(#NonNull Call call, #NonNull Response response) throws IOException {
String jsonStr=response.body().string();
Log.e(TAG, "Response from url: " + jsonStr);
if (jsonStr != null) {
try {
JSONObject jsonObj = new JSONObject(jsonStr);
// Getting JSON Array node
JSONArray records = jsonObj.getJSONArray("records");
// looping through All items
for (int i = 0; i < records.length(); i++) {
JSONObject c = records.getJSONObject(i);
String league = c.getString("league");
String season = c.getString("season");
String name = c.getString("name");
String officialName = c.getString("officialName");
String address = c.getString("address");
String telephone = c.getString("telephone");
String fax = c.getString("fax");
String website = c.getString("website");
String founded = c.getString("founded");
String teamSize = c.getString("teamSize");
String averageAge = c.getString("averageAge");
String foreigners = c.getString("foreigners");
String nationaTeamPlayers = c.getString("nationaTeamPlayers");
String teamValue = c.getString("teamValue");
String venue = c.getString("venue");
String venueCapacity = c.getString("venueCapacity");
HashMap<String, String> result = new HashMap<>();
// adding each child node to HashMap key => value
result.put("league",league);
result.put("season",season);
result.put("name",name);
result.put("officialName",officialName);
result.put("address",address);
result.put("telephone",telephone);
result.put("fax",fax);
result.put("website",website);
result.put("founded",founded);
result.put("teamSize",teamSize);
result.put("averageAge",averageAge);
result.put("foreigners",foreigners);
result.put("nationaTeamPlayers",nationaTeamPlayers);
result.put("teamValue",teamValue);
result.put("venue",venue);
result.put("venueCapacity",venueCapacity);
resultList.add(result);
}
} catch (final JSONException e) {
Log.e(TAG, "Json parsing error: " + e.getMessage());
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Json parsing error: " + e.getMessage(), Toast.LENGTH_LONG).show();
}
});
}
}else {
Log.e(TAG, "Couldn't get json from server.");
runOnUiThread(new Runnable() {
#Override
public void run() {
Toast.makeText(getApplicationContext(),
"Couldn't get json from server. Check LogCat for possible errors!",
Toast.LENGTH_LONG).show();
}
});
}
}
});
return null;
}
#Override
protected void onPostExecute(Void result) {
super.onPostExecute(result);
ListAdapter adapter = new SimpleAdapter(TeamInfo.this, resultList,
R.layout.list_item_team, new String[]{ "league","season","name","officialName","address","telephone","fax","website","founded","teamSize","averageAge","foreigners","nationaTeamPlayers","teamValue","venue","venueCapacity"},
new int[]{R.id.league, R.id.season,R.id.name,R.id.officialName,R.id.address,R.id.telephone,R.id.fax,R.id.website,R.id.founded,R.id.teamSize,R.id.averageAge,R.id.foreigners,R.id.nationaTeamPlayers,R.id.teamValue,R.id.venue,R.id.venueCapacity});
lv.setAdapter(adapter);
}
}
}
The enqueue call is asynchronous, which means it queues up work to be run in the background at some point in the future, and when it is complete then it runs the callback you supply (onResponse). This means in your case the order of calls is
Start doInBackground
Add your Http call to the queue
Return from doInBackground
Run onPostExecute
Post empty list to the adapter
... some time later ...
Run the onResponse callback when it gets data
To fix this, you can remove the async task entirely and just queue the work from the main thread, since it already handles actually doing the request in the background.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_team_info);
resultList = new ArrayList<>();
lv = (ListView) findViewById(R.id.list);
startRequest();
}
private void startRequest() {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
//...
.build();
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(#NonNull Call call, #NonNull IOException e) {
call.cancel();
}
#Override
public void onResponse(#NonNull Call call, #NonNull Response response) {
showResult(response);
}
});
}
private void showResult(Response response) {
// show the result here - no need to runOnUiThread
// set the adapter, put text in views, etc from in here
}
If you really want to make the call from your own AsyncTask in the background, you should use the synchronous API, not the asynchronous API. This means calling execute instead of enqueue, like this:
// this MUST run on a background thread or it will block the UI thread
Response response = client.newCall(request).execute();
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
I'm trying to delete and create a data string from a API webpage but i can't get the error code
I create API website from native php. But i create data on postman work insert and delete data
Code Delete Data
package com.dev.kedaiit.sibooks.ui.kategori;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.dev.kedaiit.sibooks.MainActivity;
import com.dev.kedaiit.sibooks.R;
import com.dev.kedaiit.sibooks.util.AppController;
import com.dev.kedaiit.sibooks.util.ServerAPI;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class DeleteKategori extends AppCompatActivity {
EditText deleteID ;
Button btnDelete;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_delete_kategori);
deleteID = (EditText) findViewById(R.id.id_kategori);
btnDelete = (Button) findViewById(R.id.btn_delete);
pd = new ProgressDialog(DeleteKategori.this);
btnDelete.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
deleteData();
}
});
}
private void deleteData()
{
pd.setMessage("Delete Data ...");
pd.setCancelable(true);
pd.show();
StringRequest delReq = new StringRequest(Request.Method.POST, ServerAPI.URL_DELETE_KATEGORI, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.cancel();
Log.d("volley","response : " + response.toString());
try {
JSONObject res = new JSONObject(response);
Toast.makeText(DeleteKategori.this,"Successs" +res.getString("message"), Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
startActivity(new Intent(DeleteKategori.this, KategoriFragment.class));
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Log.d("volley", "error : " + error.getMessage());
Toast.makeText(DeleteKategori.this, "ERROR DELETE DATA", Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String, String> map = new HashMap<>();
map.put("id_kategori",deleteID.getText().toString());
return map;
}
};
AppController.getInstance().addToRequestQueue(delReq);
}
}
Code Insert Data
package com.dev.kedaiit.sibooks.ui.kategori;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import com.android.volley.AuthFailureError;
import com.android.volley.Request;
import com.android.volley.Response;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.StringRequest;
import com.dev.kedaiit.sibooks.R;
import com.dev.kedaiit.sibooks.util.AppController;
import com.dev.kedaiit.sibooks.util.ServerAPI;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.HashMap;
import java.util.Map;
public class InsertKategori extends AppCompatActivity {
EditText id_kategori, kategori;
Button btnBatal, btnSimpan;
ProgressDialog pd;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_insert_kategori);
/*get data from intent*/
Intent data = getIntent();
final int update = data.getIntExtra("update",0);
String intent_idkategori = data.getStringExtra("id_kategori");
String intent_kategori = data.getStringExtra("kategori");
/*end get data from intent*/
// id_kategori = (EditText) findViewById(R.id.idkategori);
kategori = (EditText) findViewById(R.id.edt_kategori);
btnBatal = (Button) findViewById(R.id.btn_cancel);
btnSimpan = (Button) findViewById(R.id.btn_simpan);
pd = new ProgressDialog(InsertKategori.this);
/*kondisi update / insert*/
if(update == 1)
{
btnSimpan.setText("Update Data");
id_kategori.setText(intent_idkategori);
id_kategori.setVisibility(View.VISIBLE);
kategori.setText(intent_kategori);
}
btnSimpan.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if(update == 1)
{
Update_data();
}else {
simpanData();
}
}
});
btnBatal.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent main = new Intent(InsertKategori.this,KategoriFragment.class);
startActivity(main);
}
});
}
private void Update_data()
{
pd.setMessage("Update Data");
pd.setCancelable(true);
pd.show();
StringRequest updateReq = new StringRequest(Request.Method.POST, ServerAPI.URL_UPDATE_KATEGORI,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.cancel();
try {
JSONObject res = new JSONObject(response);
Toast.makeText(InsertKategori.this, ""+ res.getString("message") , Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
startActivity( new Intent(InsertKategori.this,KategoriFragment.class));
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Toast.makeText(InsertKategori.this, "Gagal Insert Data", Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = new HashMap<>();
map.put("id_kategori",id_kategori.getText().toString());
map.put("kategori",kategori.getText().toString());
return map;
}
};
AppController.getInstance().addToRequestQueue(updateReq);
}
private void simpanData()
{
pd.setMessage("Menyimpan Data");
pd.setCancelable(true);
pd.show();
StringRequest sendData = new StringRequest(Request.Method.POST, ServerAPI.URL_INSERT_KATEGORI,
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.cancel();
try {
JSONObject res = new JSONObject(response);
Toast.makeText(InsertKategori.this, ""+ res.getString("message") , Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
startActivity( new Intent(InsertKategori.this,KategoriFragment.class));
}
},
new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
pd.cancel();
Toast.makeText(InsertKategori.this, "Gagal Insert Data", Toast.LENGTH_SHORT).show();
}
}){
#Override
protected Map<String, String> getParams() throws AuthFailureError {
Map<String,String> map = new HashMap<>();
map.put("id_kategori",id_kategori.getText().toString());
map.put("kategori",kategori.getText().toString());
return map;
}
};
AppController.getInstance().addToRequestQueue(sendData);
}
}
Fragment Kategori
package com.dev.kedaiit.sibooks.ui.kategori;
import android.app.ProgressDialog;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.DividerItemDecoration;
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.JsonObjectRequest;
import com.android.volley.toolbox.Volley;
import com.dev.kedaiit.sibooks.R;
import com.dev.kedaiit.sibooks.adapter.AdapterDataKategori;
import com.dev.kedaiit.sibooks.model.DataKategori;
import com.dev.kedaiit.sibooks.util.ServerAPI;
import com.google.android.material.floatingactionbutton.FloatingActionButton;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class KategoriFragment extends Fragment {
private RecyclerView recyclerView;
private FloatingActionButton floatingActionButton;
private LinearLayoutManager linearLayoutManager;
private DividerItemDecoration dividerItemDecoration;
private List<DataKategori> list;
private RecyclerView.Adapter adapter;
public KategoriFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(final LayoutInflater inflater, final ViewGroup container, Bundle savedInstanceState) {
final View view = inflater.inflate(R.layout.fragment_kategori, container, false);
recyclerView = view.findViewById(R.id.recyclerViewKategori);
list = new ArrayList<DataKategori>();
adapter = new AdapterDataKategori(getContext(), list);
linearLayoutManager = new LinearLayoutManager(getContext());
linearLayoutManager.setOrientation(LinearLayoutManager.VERTICAL);
dividerItemDecoration = new DividerItemDecoration(recyclerView.getContext(), linearLayoutManager.getOrientation());
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(linearLayoutManager);
recyclerView.addItemDecoration(dividerItemDecoration);
recyclerView.setAdapter(adapter);
FloatingActionButton fab = (FloatingActionButton) view.findViewById(R.id.fab);
FloatingActionButton delKtg = (FloatingActionButton) view.findViewById(R.id.delKtg);
fab.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(), InsertKategori.class);
startActivity(intent);
}
});
delKtg.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Intent intent = new Intent(view.getContext(),DeleteKategori.class);
startActivity(intent);
}
});
getData();
return view;
}
private void getData() {
final ProgressDialog progressDialog = new ProgressDialog(getContext());
progressDialog.setMessage("Loading...");
progressDialog.show();
JsonObjectRequest my_request = new JsonObjectRequest(Request.Method.GET, ServerAPI.URL_DATA_KATEGORI, null, new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try{
JSONArray jsonArray = response.getJSONArray("data");
for (int i = 0; i < jsonArray.length(); i++) {
JSONObject Jobj = jsonArray.getJSONObject(i);
DataKategori obj = new DataKategori();
obj.setId_kategori(Jobj.getString("id_kategori"));
obj.setKategori(Jobj.getString("kategori"));
list.add(obj);
}
} catch (JSONException e) {
e.printStackTrace();
progressDialog.dismiss();
}
adapter.notifyDataSetChanged();
progressDialog.dismiss();
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Log.e("Volley", "Error: " + error.getMessage());
progressDialog.dismiss();
}
});
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(my_request);
}
}
https://github.com/bellabeen/sibooks-client This project me get this in the logcat and when i dont get error code
Your code is almost fine. You just missed one thing. You did not initialize VolleyRequest. Inside simponData and UpdateData methods write this line at the bottom.
RequestQueue requestQueue = Volley.newRequestQueue(getContext());
requestQueue.add(my_request);
instead of AppController.getInstance().addToRequestQueue(updateReq).
other thing is you are calling the fragment in intent from when response is received .You should call onbackPress() when result is recieved successfully.
new Response.Listener<String>() {
#Override
public void onResponse(String response) {
pd.cancel();
try {
JSONObject res = new JSONObject(response);
Toast.makeText(InsertKategori.this, ""+ res.getString("message") , Toast.LENGTH_SHORT).show();
} catch (JSONException e) {
e.printStackTrace();
}
onBackPressed();
}
},
It will restore the previous fragment. In order to update the KategoriFragment view when successful response is received, you can call the getData() method in onResume() method instead of oncreate(). it will call this method whenever fragment is visible to the use
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)
}
}
});
}
}
I have an activity with 2 EditText.
When the user is clicking on the Send button, I want to send EditText value to my server.
i tried to make a POST request when the user clicking on the button.
The problem is when the user is clicking on the button He get a error, and the application closing automatically.
This is my code:
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import com.google.firebase.iid.FirebaseInstanceId;
import com.google.firebase.messaging.FirebaseMessaging;
import java.io.IOException;
import okhttp3.FormBody;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.RequestBody;
public class register extends AppCompatActivity {
private EditText nameE,l_nameE;
private Button registerE;
private String name,l_name,token;
boolean thread_running = true;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_register);
FirebaseMessaging.getInstance().subscribeToTopic("test");
token = FirebaseInstanceId.getInstance().getToken();
Toast.makeText(this, token, Toast.LENGTH_LONG).show();
final Button register = (Button)findViewById(R.id.button);
nameE = (EditText)findViewById(R.id.editText);
l_nameE = (EditText)findViewById(R.id.editText2);
register.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
registerToken();
}
});
}
public void intialize(){
name = nameE.getText().toString().trim();
l_name = l_nameE.getText().toString().trim();
}
public boolean validate(){
boolean e=true;
if(name.equals("")){
e=false;
nameE.setError("enter name");
}else if(l_name.equals("")){
e=false;
l_nameE.setError("enter l_name");
}
return e;
}
private void registerToken() {
intialize();
if (!validate()) {
Toast.makeText(this, "err", Toast.LENGTH_LONG).show();
}else{
reg();
}
}
public void reg(){
Toast.makeText(this, "reg", Toast.LENGTH_LONG).show();
OkHttpClient client = new OkHttpClient();
RequestBody body = new FormBody.Builder()
.add("name",name)
.add("l_name",l_name)
.build();
Request request = new Request.Builder()
.url("http://192.168.0.106/fcm/register.php")
.post(body)
.build();
try {
client.newCall(request).execute();
} catch (IOException e) {
e.printStackTrace();
}
}
}
thank you
You are doing a network call on the main thread. That is not allowed on Android as it will block your whole application until the request is completed.
A solution will be to wrap your network call in an AsyncTask for example.
But as you are using OKHttpClient, they are offering an async api for such things.
client.newCall(request).enqueue(new Callback() {
#Override
public void onFailure(Call call, IOException e) {
//something went wrong
Log.e(YOUR_TAG, e);
}
#Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Response not sueccessful " + response);
}
//success do whatever you want. for example -->
Log.d(YOUR_TAG, response.body().string());
}
}
So in your example instead of an synchronous call like
client.newCall(request).execute();
you have to use the async callback version like shown above.
hopefully that helps
Edit: For more recipes take a look at the wiki page: https://github.com/square/okhttp/wiki/Recipes
I am trying to get an Android device to send some HTTP request using GET method.
Here is my code:
package com.kde.httprequest;
import java.io.IOException;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.ResponseHandler;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.BasicResponseHandler;
import org.apache.http.impl.client.DefaultHttpClient;
import android.app.Activity;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;
public class main2 extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
final EditText edit1 = (EditText) findViewById (R.id.editText1);
Button btn1 = (Button) findViewById (R.id.button1);
btn1.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
grabURL(edit1.getText().toString());
}
});
}
public void grabURL(String url) {
new GrabURL().execute(url);
}
private class GrabURL extends AsyncTask<String, Void, Void> {
private final HttpClient Client = new DefaultHttpClient();
private String Content;
private String Error = null;
private ProgressDialog Dialog = new ProgressDialog(main2.this);
final TextView text1 = (TextView) findViewById (R.id.textView1);
protected void onPreExecute() {
Dialog.setMessage("Downloading source..");
Dialog.show();
}
protected Void doInBackground(String... urls) {
try {
HttpGet httpget = new HttpGet(urls[0]);
ResponseHandler<String> responseHandler = new BasicResponseHandler();
Content = Client.execute(httpget, responseHandler);
} catch (ClientProtocolException e) {
Error = e.getMessage();
cancel(true);
} catch (IOException e) {
Error = e.getMessage();
cancel(true);
}
return null;
}
protected void onPostExecute(Void unused) {
Dialog.dismiss();
if (Error != null) {
Toast.makeText(main2.this, Error, Toast.LENGTH_LONG).show();
text1.setText(Error);
} else {
Toast.makeText(main2.this, "Source: " + Content, Toast.LENGTH_LONG).show();
text1.setText(Content);
}
}
}
}
My simple PHP test:
<?php
$a = $_GET['user'];
$b = $_GET['pass'];
if ($a=="usr" && $b=="pass") {
echo "success";
} else {
echo "fail";
}
?>
My code is running smoothly when send to this URL:
digitalzone-btm.com/test2.php?user=user&pass=pass
The response from my PHP is a string say "success" or "fail", that is what I am expected.
But I am getting a different response from my local webserver with a same Android app and PHP file.
Ex url:
http://192.168.1.8/test2.php?user=user&pass=pass
The response is exactly my PHP source code.
How can I get a "success" or "fail" response from my local webserver?
It would appear your local web server doesn't have php installed or configured right. Check here for help.
PHP: Installation and Configuration - Manual