I am trying to insert data using the Retrofit library. The data has been inserted successfully and I am also receiving the response from the API, but my error is that I am not getting the intent Activity (AdminActivity.class) after the Toast. Can anyone help me on this??
private void createUserResponse() {
ApiInterface apiInterface = ApiClient.getClient().create(ApiInterface.class);
CreateUserRequest createUserRequest = new CreateUserRequest(editTextUserId.getText().toString().trim(),
editTextPassword.getText().toString().trim(),
editTextUserName.getText().toString().trim(),
editTextProfileImage.getText().toString().trim(), editTextSchoolId.getText().toString().trim(),editTextRole.getText().toString().trim());
Call<CreateUserResponse> createUserResponseCall = apiInterface. createUserCall(createUserRequest);
createUserResponseCall.enqueue(new Callback<CreateUserResponse>() {
#Override
public void onResponse(Call<CreateUserResponse> call, Response<CreateUserResponse> response) {
Log.d("CreateUser" , "onResponse: " + response.body().getMessage());
String status = response.body().getStatus();
if (status.equals("sucess")){
String message = response.body().getMessage();
Toast.makeText(getActivity(),"User Created Successfully" + message,Toast.LENGTH_SHORT).show();
Intent i = new Intent(getActivity(), AdminActivity.class);
startActivity(i);
} else{
String message = response.body().getMessage();
Toast.makeText(getActivity(),"" + message, Toast.LENGTH_SHORT).show();
}
}
#Override
public void onFailure(Call<CreateUserResponse> call, Throwable t) {
}
});
}
You have a typo within your if-else condition, so your code do not execute the if statement even if you get a successful response.
Fix the following typo and try again:
if (status.equals("success")) // fixed typo on "sucess" word
Related
I think I wrote the codes correctly, but Firebase does not add data in Realtime Database. I downloaded the JSON file, connected the project, checked it via Firebase tools, but it still doesn't add data. What can I do it?
Mainactivity.java - addevent class(it will work when click the button)
private void addEvent(){
String plan = etplan.getText().toString();
String note = etnote.getText().toString();
String date = etdate.getText().toString();
String time = ettime.getText().toString();
String remb = "false";
if (remember.isChecked()==true){
remb = "true";
}
else{
remb = "false";
}
String id = dbRef.push().getKey();
Events event = new Events(id,plan,note,date,time,remb);
dbRef.child(id).setValue(event);
}
I get the following error in the Run section of the program:
glUtilsParamSize: unknow param at 0x000082
And edited this code:
dbRef.child(id).setValue(event)
.addOnSuccessListener(new OnSuccessListener<Void>() {
#Override
public void onSuccess(Void unused) {
Toast.makeText(MainActivity.this,"Events Added SUCCESSFULLY!", Toast.LENGTH_SHORT).show();
}
})
.addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception e) {
Toast.makeText(MainActivity.this,e.toString(), Toast.LENGTH_SHORT).show();
}
});
I try to add data from my object to ArrayList but it's not work.
This code read data from JSON and add to ArrayList in MySQLConnect.java like this.
private ComputerService computerservice;
public static ArrayList<ComputerService> computerServicesArrayList = new ArrayList<>();
private String URL = "http://10.200.100.10/", GET_URL = "android/get_data.php";
public MySQLConnect(){
main = null;
}
public MySQLConnect(Activity mainA){
main = mainA;
}
public List<ComputerService> getData(){
String url = URL + GET_URL;
StringRequest stringRequest = new StringRequest(url, new Response.Listener<String>() {
#Override
public void onResponse(String response) {
showJSON(response);
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(main, error.getMessage().toString(), LENGTH_LONG).show();
}
}
);
RequestQueue requestQueue = Volley.newRequestQueue(main.getApplicationContext());
requestQueue.add(stringRequest);
return computerServicesArrayList;
}
public void showJSON(String response){
String data_mysql = "";
computerServicesArrayList.clear();
try{
JSONObject jsonObject = new JSONObject(response);
JSONArray result = jsonObject.getJSONArray("data");
for(int i=0; i < result.length(); i++){
JSONObject collectData = result.getJSONObject(i);
String id = collectData.getString("id");
String type = collectData.getString("type");
String address = collectData.getString("address");
computerservice = new ComputerService(id, type, address);
computerServicesArrayList.add(computerservice);
}
System.out.println("Size in class MySQLConnect");
System.out.println(computerServicesArrayList.size());
} catch (JSONException e) {
e.printStackTrace();
}
}
The MainActivity.java I show computerServicesArrayList.size() like this.
public static List<ComputerService> computerServicesArrayList;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mySQLConnect = new MySQLConnect(MainActivity.this);
update();
}
public void update(){
computerServicesArrayList = mySQLConnect.getData();
System.out.println("Size in MainActivity");
System.out.println(computerServicesArrayList.size());
}
The output show like this.
Size in MainActivity
0
Size in class MySQLConnect
83
From the code I can print computerServicesArrayList.size() the result is 83 but when I print from MainActivity why it show result 0. How to fix it?
I don't know the Volley framework/classes in detail. But it looks like you are creating an asynchronous request. So your rest-request gets send and when the response comes in your showJSON() method is called.
But you immediatley return the computerServicesArrayList result, which is empty because you don't have your response yet. This is also the reason why the print statement from your MainActivity is executed before the print from your showJSON method.
If you want to wait for the rest-response you have to do synchronous requests.
Maybe this can help you more about Volley and asyn/sync requests:
how to wait the volley response to finish it's work inside intentservice?
Can I do a synchronous request with volley?
But normally you would send an async-request and when you get the response you do your logic (update fields, store something in database, ...).
Your computerServicesArrayList is populated by callback from Volley (new Response.Listener()). This population happens correctly as you have verified. But it does take some time, for the network up/down travel. When your MainActivity's call to mySQLConnect.getData() returns this round trip is not complete yet; so you get an empty list in MainActivity.
The usual solution to this problem is to make the listener call methods in MainActivity. This can be done by making
class MainActivity implements Response.Listener<String> {
/* --- */
#Override
public void onResponse(String response) {
showJSON(response);
}
void showJSON(String response){
// Do the stuff here
}
I have this method
private void setNews(final GetDataCallback getDataCallback){
GetDataService service = RetrofitClientInstance.getRetrofitInstance().create(GetDataService.class);
Call<ItemsAPI> call = service.getAllItems();
call.enqueue(new Callback<ItemsAPI>() {
#Override
public void onResponse(Call<ItemsAPI> call, Response<ItemsAPI> response) {
if (response.isSuccessful()) {
Log.d(TAG, "onResponse");
items = response.body();
getDataCallback.onGetData(items.getItems());
}
else {
getDataCallback.onError();
}
}
#Override
public void onFailure(Call<ItemsAPI> call, Throwable t) {
getDataCallback.onError();
Log.d(TAG, "onFailure "+ t.getMessage());
}
});
}
where I get callball with information from API
And I need to give this info to another callball
public MutableLiveData<List<News>> getNews(){
setNews(new GetDataCallback() {
#Override
public void onGetData(List<News> newsData) {
dataSet = newsData;
Log.d(TAG, "size: "+dataSet.size());
}
#Override
public void onError() {
}
});
MutableLiveData<List<News>> data = new MutableLiveData<>();
Log.d(TAG, "size before setValue: "+dataSet.size());
data.setValue(dataSet);
return data;
}
When I check log I can see
2019-05-18 10:45:17.575 2250-2250/? D/NewsRepository: size before setValue: 0
2019-05-18 10:45:18.334 2250-2250/com.krasnov.rxjavalearning D/NewsRepository: onResponse
2019-05-18 10:45:18.334 2250-2250/com.krasnov.rxjavalearning D/NewsRepository: size: 30
From another class I call getNews() method. I need to do setNews() first, have elements in data set and after return value from getNews().
How can I do this?
Retrofit.enqueue() is asynchronous call and execute in future.
If you want to update ui from Livedata from getNews()
LiveData<Data> getNews() {
final MutableLiveData<Data> data = new MutableLiveData<>();
setNews( new MyCallback(){
Void onSuccess(Data data){
data.setValue(data); // for success live data get call back
}
void onError(){
data.setValue(null); // for error case can pass null or empty list
}
});
return data;
}
You will get update with response
I have an android app that is connected to an API through retrofit, ive succesfully logged in, if i press back button to return back to the login activity again, if i try re-logging in again, the app crashes and give me a NullPointerException.
here's connection code
private void loginUser(String email, String password) {
UnifyAuthenticationApiInterface service = this.client.create(UnifyAuthenticationApiInterface.class);
Call<UnifyAuthenticationApiResponse> call = service.staffLogin(email, password);
call.enqueue(new Callback<UnifyAuthenticationApiResponse>() {
#Override
public void onResponse(Call<UnifyAuthenticationApiResponse> call,
Response<UnifyAuthenticationApiResponse> response) {
UnifyAuthenticationApiResponse result = response.body();
School school = new School();
com.peterstev.unify.login.Data data = result.getData();
mySchoolsList = new ArrayList<School>();
mySchoolsList = data.getSchools();
staff = data.getStaff();
gotoHomeActivity();
}
#Override
public void onFailure(Call<UnifyAuthenticationApiResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Login Failed # onFailure", Toast.LENGTH_SHORT).show();
}
});
}
and the goToHomeActivity() is
private void gotoHomeActivity() {
progressDialog.dismiss();
if (mySchoolsList.size() > 1) {
schoolsListView = new ListView(MainActivity.this);
schoolsArrayAdapter = new SchoolListAdapter(MainActivity.this, android.R.layout.simple_list_item_1, mySchoolsList);
schoolsListView.setAdapter(schoolsArrayAdapter);
dialog = new Dialog(MainActivity.this);
dialog.setContentView(schoolsListView);
dialog.setTitle("Welcome " + staff.getFullName());
dialog.show();
} else {
Intent intent = new Intent(MainActivity.this, NavMainActivity.class);
startActivity(intent);
}
}
the NullPointerException gets thrown at
com.peterstev.unify.login.Data data = result.getData();
at first, it gets the data n succesfully logs in, but when i use the back button n try to log in again it crashes.
Debugger is your answer - check if you aren't loosing any data when going back - maybe you're storing login params somewhere in activity class but you're not saving instance state properly and second request is triggered without necessary data. Check state of variables just before calling your request first and second time.
In situation like that always best bet to place breakpoint and trigger your work step by step. You cannot be good developer without debugger skills.
I think for some reason, the data object wasn't receiving the result when i used the back button to navigate to the parent activity. so i used and if condition to make it get the required data.
private void loginUser(String email, String password) {
UnifyAuthenticationApiInterface service = this.client.create(UnifyAuthenticationApiInterface.class);
Call<UnifyAuthenticationApiResponse> call = service.staffLogin(email, password);
call.enqueue(new Callback<UnifyAuthenticationApiResponse>() {
#Override
public void onResponse(Call<UnifyAuthenticationApiResponse> call,
Response<UnifyAuthenticationApiResponse> response) {
if(response.isSuccessful()) {
UnifyAuthenticationApiResponse result = response.body();
School school = new School();
data = result.getData();
if(data == null) {
try{
this.onResponse(call, response);
}catch(NullPointerException NPE){
Log.d("NPE", NPE.getMessage());
}
}
mySchoolsList = new ArrayList<School>();
mySchoolsList = data.getSchools();
staff = data.getStaff();
gotoHomeActivity();
}
}
#Override
public void onFailure(Call<UnifyAuthenticationApiResponse> call, Throwable t) {
progressDialog.dismiss();
Toast.makeText(MainActivity.this, "Login Failed # onFailure", Toast.LENGTH_SHORT).show();
}
});
}
I am trying to make this application in Android, I am getting data from foursquare's API in JSON format and I need to Parse it to present it in another intent.
I am using Android's volley library to get the JSON but the problem is the onResponse() function of JsonObjectRequest has no return parameter.so I cannot get the JSON object gotten from url outside of the the onResponse.
I haven't worked with volley before and hence don't know much about it, any help is appreciated. Here is the code that I am trying to make it work.
Edit: The main problem I'm facing is that I cannot assign a value to global variable in this case myPlaces inside the JsonObjectRequest's onResponse method. Or to be exact, the variable assigned inside means nothing outside, thus in the last line
Toast.makeText(MainActivity.this, myPlaces[2].getName(), Toast.LENGTH_LONG).show();
when I try to access the myPlaces[2] it gives me an null pointer exception.
Thanks.
public void onClick(View v) {
RequestQueue requestQueue = Volley.newRequestQueue(MainActivity.this);
JsonObjectRequest jsonObjectRequest = new JsonObjectRequest(urlString, null, new com.android.volley.Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONObject meta = response.getJSONObject("meta");
String status = meta.getString("code");
Toast.makeText(MainActivity.this, status, Toast.LENGTH_SHORT).show();
if(status.equals("200"))
{
JSONObject responseJson = response.getJSONObject("response");
JSONArray venues = responseJson.getJSONArray("venues");
Places[] tempPlaces = new Places[venues.length()];
for (int i = 0 ; i < venues.length(); i++)
{
Places place = new Places();
JSONObject venueObject = venues.getJSONObject(i);
place.setName(venueObject.getString("name"));
JSONObject locatVenue = venueObject.getJSONObject("location");
place.setLat(locatVenue.getDouble("lat"));
place.setLon(locatVenue.getDouble("lng"));
tempPlaces[i] = place;
}
Toast.makeText(MainActivity.this, tempPlaces[2].getName(), Toast.LENGTH_LONG).show();
myPlaces = tempPlaces;
}
else
{
Toast.makeText(MainActivity.this, "No response from API", Toast.LENGTH_LONG).show();
}
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(MainActivity.this, "There is some error here", Toast.LENGTH_LONG).show();
}
}
}, new com.android.volley.Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
Toast.makeText(MainActivity.this, "There has been some error", Toast.LENGTH_LONG).show();
}
});
requestQueue.add(jsonObjectRequest);
Toast.makeText(MainActivity.this, myPlaces[2].getName(), Toast.LENGTH_LONG).show();
Volley itself isn't an inner class; the response is an anonymous class.
You don't need a return in Volley, you just use the variables already defined in your class.
I'm assuming myPlaces is a field in your class? Otherwise, I'm not sure where it is declared outside the onClick..
This line assigns myPlaces and looks like it would work fine
myPlaces = tempPlaces;
You could define a method in your class to parse the whole JSONObject instead of needing to return from Volley. This just passes the logic to another method, so you don't need to think about "returning" inside Volley.
public void parseJSON(JsonObject object)
And pass the response from volley into that and do your normal parsing and variable assignment and you can Toast myPlaces inside that method.
Also, note that Volley is asynchronous, meaning you aren't guaranteed an immediate result, so
Toast.makeText(MainActivity.this, myPlaces[2].getName(), Toast.LENGTH_LONG).show();
Would likely have thrown either a NullPointerException or IndexOutOfBoundsException because myPlaces was either undeclared or empty before the Volley request. I say that because it does not appear to be assigned before the Volley request.