I am new for retrofit and I am using it and I have implemented in activity directly not inside thread and when I am starting then it taking lot of time and blocking User Interface also and after getting response and when I hit again same by restarting activity It wait unlimited time. It is being stuck on same request.
I have an activity and having three fragment and using pager so firstly I am hitting web-service inside activity and using call back updating my recycler view adapter
retrofit = new Retrofit.Builder().baseUrl("xyz.co.in/").addConverterFactory(GsonConverterFactory.create()).build();
app = retrofit.create(ApiInterface.class);
Call<List<Pojo>> listCall = app.getDetails();
sb = new StringBuffer("xyz.co.in/api/api.php?api=user&ver=1.0&key=56F353E05208C8E&cmd=OBJECT_GET_LOCATIONS");
sb.append(",");
listCall.enqueue(new Callback<List<Pojo>>() {
#Override
public void onResponse(Response<List<Pojo>> response, Retrofit retrofit) {
final ArrayList<Pojo> list = (ArrayList<Pojo>) response.body();
for (int i = 0; i < list.size(); i++) {
if (i == 0)
sb.append("" + list.get(i).getImei());
else
sb.append(";" + list.get(i).getImei());
}
Ion.with(MainActivity.this).load(sb.toString())
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
if (e != null)
Toast.makeText(getApplicationContext(), "Error : " + e.toString(), Toast.LENGTH_SHORT).show();
else {
try {
list_pojo = new ArrayList<>();
address_description = new ArrayList<>();
for (int i = 0; i < list.size(); i++) {
JsonObject jsonObject = result.getAsJsonObject(list.get(i).getImei().toString());
list_pojo.add(new Imei_Pogo(jsonObject.get("dt_server").getAsString(), jsonObject.get("dt_tracker").getAsString(), jsonObject.get("lat").getAsDouble(), jsonObject.get("lng").getAsDouble(), jsonObject.get("altitude").getAsString(), jsonObject.get("angle").getAsString(), jsonObject.get("speed").getAsInt()));
geocoder = new Geocoder(MainActivity.this, Locale.getDefault());
addresses = geocoder.getFromLocation( jsonObject.get("lat").getAsDouble(), jsonObject.get("lng").getAsDouble(), 1); // Here 1 represent max location result to returned, by documents it recommended 1 to 5
String address = addresses.get(0).getAddressLine(0); // If any additional address line present than only, check with max available address lines by getMaxAddressLineIndex()
String city = addresses.get(0).getLocality();
String state = addresses.get(0).getAdminArea();
String country = addresses.get(0).getCountryName();
String postalCode = addresses.get(0).getPostalCode();
address_description.add(address + "," + city + "," + state + "," + country + "-" + postalCode);
}
// new MyDataBase(getApplicationContext()).insertData(list,list_pojo,address_description);
callback.updateUI(list, list_pojo,address_description);
dialog.dismiss();
} catch (Exception g) {
g.printStackTrace();
}
finally {
if(dialog.isShowing())
dialog.dismiss();
}
}
}
});
}
#Override
public void onFailure(Throwable t) {
Toast.makeText(MainActivity.this, "failed", Toast.LENGTH_SHORT).show();
}
});
Related
I am building an android app that displays the COVID19 statistics for India, I am getting the stats in JSON format from https://api.covid19india.org/data.json , this API contains data of individual states too,
Below is the snip of Json array(contains json objects representing each state) that i am requesting
as of Now i am displaying the entire data ( all states ) at a time on my screen, However i want to give the state name as the input and display the stats of only that state For eg. in the below image in place of sample i want to write a state name and the stats of that state must be displayed on click of the button.
Here is the code of mainActivity.java, I am using Volley Library for fetching data from API
public class MainActivity extends AppCompatActivity {
private TextView result;
private RequestQueue mq;
public String value;
int flag = 0;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
result = findViewById(R.id.textView4);
Button parse = findViewById(R.id.button);
mq = Volley.newRequestQueue(this);
EditText text = (EditText)findViewById(R.id.state_ip);
value = text.getText().toString();
parse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
jsonParse(value);
**//How do i pass 'value' i.e the state name entered by user to jsonParse**
}
});
}
private void jsonParse(final String value) {
Log.d("val_state",value);
String url = "https://api.covid19india.org/data.json";
JsonObjectRequest request = new JsonObjectRequest(Request.Method.GET, url, null,
new Response.Listener<JSONObject>() {
#Override
public void onResponse(JSONObject response) {
try {
JSONArray jsonArray = response.getJSONArray("statewise");
for (int i = 0; i < jsonArray.length(); i++)
{
JSONObject st = jsonArray.getJSONObject(i);
String statename = st.getString("state");
String active = st.getString("active");
String confirmed = st.getString("confirmed");
String deaths = st.getString("deaths");
String recovered = st.getString("recovered");
if(statename.equals(value))
{
flag= 1;
}
statename = "State : " + statename;
active = "Active Cases : " + active;
confirmed = "Confirmed Cases : " + confirmed;
deaths = "Total Deaths : " + deaths;
recovered = "Total Recovered : " + recovered;
if(flag==1)
{
flag=0;
result.append(statename + "\n" + String.valueOf(active) + "\n" + String.valueOf(confirmed) + "\n" + String.valueOf(deaths) + "\n" + String.valueOf(recovered) + "\n\n\n");
}
}
} catch (JSONException e) {
e.printStackTrace();
}
}
}, new Response.ErrorListener() {
#Override
public void onErrorResponse(VolleyError error) {
error.printStackTrace();
}
});
mq.add(request);
}
}
Here , i want to pass the value of state entered by the user to the method jsonParse() so that i check the state name with the received JSON data and append it to the TextView, but when i do this , and try to log the value inside the jsonParse() method i get nothing, why is this happening , How do i implement the above ?
Your EditText value is update and has to be captured after the button is clicked.
parse.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
value = text.getText().toString();
jsonParse(value);
}
});
I'm using Fast Android Networking library to parse a JSONArray generated from my PHP/MySQL API. I'm using a for loop to sum all integer values in the JSONArray. Everything works great when I first launch the activity the data is sent to (as static references), but on relaunch, the data is doubled i.e if on first launch sum was 500, on relaunch it returns 1000.
This is the method I use to parse the JSONArray
public void getGroupStats() {
MaterialDialog.Builder builder = new MaterialDialog.Builder(Splash.this)
.progress(true, 100)
.content("Loading...")
.cancelable(false);
dialog = builder.build();
dialog.show();
AndroidNetworking.post(Helper.Header + "/savings/api/Api.php?apicall=getgroups")
.addBodyParameter("goal", sharedPreferences.getString("Goal", ""))
.addBodyParameter("type", sharedPreferences.getString("Type", ""))
.setPriority(Priority.MEDIUM)
.build()
.getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
JSONArray jsonArray = null;
try {
jsonArray = response.getJSONArray("savings");
for (int j = 0; j < jsonArray.length(); j++) {
obj = (JSONObject) jsonArray.get(j);
groupsaving += Integer.parseInt(obj.getString("saving"));
groupsaved += Integer.parseInt(obj.getString("saved"));
Helper.Members = jsonArray.length();
}
Intent intent = new Intent(Splash.this, Statistics.class);
intent.putExtra("Title", textView.getText().toString());
if (textView.getText().toString().contains("SAVVY SAVER")) {
Helper.Image = "smallest_bag";
} else if (textView.getText().toString().contains("POWER SAVER")) {
Helper.Image = "small_bag";
} else if (textView.getText().toString().contains("SUPER SAVER")) {
Helper.Image = "big_bag";
} else {
Helper.Image = "biggest_bag";
}
startActivity(intent);
} catch (JSONException e) {
e.printStackTrace();
}
Helper.GroupSaving = groupsaving;//to be used in next activity
Helper.GroupSaved = groupsaved;
Toast.makeText(getApplicationContext(), String.valueOf(groupsaved) + " " + String.valueOf(groupsaving), Toast.LENGTH_LONG).show();
dialog.cancel();
}
#Override
public void onError(ANError error) {
Toast.makeText(getApplicationContext(), error.toString(), Toast.LENGTH_LONG).show();
dialog.cancel();
}
});
}
What am I doing wrong?
Cant you just make your variables zero before the loop?
I want to draw a complete route on Mapbox from origin to destination using .geojson file.
Please find below code.
private void drawMapMatched(Position[] coordinates) {
try {
MapboxMapMatching client = new MapboxMapMatching.Builder()
.setAccessToken(Mapbox.getAccessToken())
.setSteps(true)
.setProfile(MapMatchingCriteria.PROFILE_DRIVING)
.setCoordinates(coordinates)
.build();
client.enqueueCall(new Callback<MapMatchingResponse>() {
#Override
public void onResponse(Call<MapMatchingResponse> call, Response<MapMatchingResponse> response) {
List<LatLng> mapMatchedPoints = new ArrayList<>();
if (response.code() == 200) {
String geometry = response.body().getMatchings().get(0).getGeometry();
List<Position> positions = PolylineUtils.decode(geometry, Constants.PRECISION_6);
if (positions == null) {
return;
}
for (int i = 0; i < positions.size(); i++) {
mapMatchedPoints.add(new LatLng(
positions.get(i).getLatitude(),
positions.get(i).getLongitude()));
}
if (mapMatchedRoute != null) {
mapboxMap.removeAnnotation(mapMatchedRoute);
}
mapMatchedRoute = mapboxMap.addPolyline(new PolylineOptions()
.color(Color.GREEN)
.alpha(0.65f)
.width(4));
for (int i = 0; i < mapMatchedPoints.size(); i++) {
mapMatchedRoute.addPoint(mapMatchedPoints.get(i));
}
Position origin = Position.fromCoordinates(mapMatchedPoints.get(0).getLongitude(), mapMatchedPoints.get(0).getLatitude());
Position destination = Position.fromCoordinates(mapMatchedPoints.get(mapMatchedPoints.size() - 1).getLongitude(), mapMatchedPoints.get(mapMatchedPoints.size() - 1).getLatitude());
getRoute(origin, destination);
} else {
Log.e(TAG, "Too many coordinates, profile not found, invalid input, or no match.");
}
}
#Override
public void onFailure(Call<MapMatchingResponse> call, Throwable throwable) {
Log.e(TAG, "MapboxMapMatching error: " + throwable.getMessage());
}
});
} catch (ServicesException servicesException) {
servicesException.printStackTrace();
}
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, null); locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.NAVIGATION);
}
private void getRoute(final Position origin, final Position destination) {
ArrayList<Position> positions = new ArrayList<>();
positions.add(origin);
positions.add(destination);
MapboxDirections client = new MapboxDirections.Builder()
.setAccessToken(Mapbox.getAccessToken())
.setOrigin(origin)
.setDestination(destination)
.setAlternatives(true)
.setProfile(DirectionsCriteria.PROFILE_DRIVING)
.setSteps(true)
.setOverview(DirectionsCriteria.OVERVIEW_FULL)
.setBearings(new double[]{60, 45}, new double[]{45, 45})
.setAnnotation(DirectionsCriteria.ANNOTATION_DISTANCE, DirectionsCriteria.ANNOTATION_DURATION)
.build();
client.enqueueCall(new Callback<DirectionsResponse>() {
#Override
public void onResponse(Call<DirectionsResponse> call, Response<DirectionsResponse> response) {
Log.d(TAG, "API call URL: " + call.request().url().toString());
Log.d(TAG, "Response code: " + response.code());
if (response.body() == null) {
Log.e(TAG, "No routes found, make sure you set the right user and access token.");
return;
}
// Print some info about the route
route = response.body().getRoutes().get(0);
//showMessage(String.format(Locale.US, "Route is %.1f meters long.", currentRoute.getDistance()));
// Draw the route on the map
drawRoute(route, origin, destination);
}
#Override
public void onFailure(Call<MapMatchingResponse> call, Throwable throwable) {
}
});
} catch (ServicesException servicesException) {
servicesException.printStackTrace();
}
locationLayerPlugin = new LocationLayerPlugin(mapView, mapboxMap, null);
locationLayerPlugin.setLocationLayerEnabled(LocationLayerMode.NAVIGATION);
}`
Route is getting draw but from origin to destination.
For example, if complete route is like, A-B-C-D-E, so I want to draw route which connects A-B-C-D-E but I am able to connect directly A-E.
Please guide.
Thanks in advance.
Firstly, i'm fetching some data from server database and getting some addresses which i'm reversing to location latitude and longitude, so i can calculate after that distance between my location latlng and theirs.
But for some reason Activity freezes at loading data and list is loading very slow with this feature. This is how i'm calculating distance between two location:
AndroidNetworking.get(AppConfig.GET_FIELDS_ORDER_BY_CITY.replace("city", tvCurrentLocation.getText().toString()))
.setPriority(Priority.IMMEDIATE)
.build().getAsJSONObject(new JSONObjectRequestListener() {
#Override
public void onResponse(JSONObject response) {
mFieldList.clear();
try {
if (!response.getBoolean("error")) {
JSONArray fieldsArray = response.getJSONArray("fields");
for (int i = 0; i < fieldsArray.length(); i++) {
JSONObject fieldObj = fieldsArray.getJSONObject(i);
Field field = new Field();
...
field.setCertificate(fieldObj.getString("certificate"));
Log.d("Location", fieldObj.getString("address"));
// If i delete from here
if (!fieldObj.getString("address").isEmpty()) {
LatLng latLng = AppUtils.getLocationFromAddress(SearchActivityV2.this,
fieldObj.getString("address"));
float dist = AppUtils.distFrom(44.8029925f, 20.495337f, (float) latLng.latitude, (float) latLng.longitude);
DecimalFormat df = new DecimalFormat("####0.0");
if (dist > 1000) {
double distance = AppUtils.calculationByDistance(new LatLng(44.8029925, 20.495337), latLng);
field.setDistance(df.format(distance) + " km");
} else {
String newValue = Double.toString(Math.floor(dist));
field.setDistance(newValue + " m");
}
} else {
field.setDistance("1000");
}
mFieldList.add(field);
}
// to here, list would load immediately, so
// something is not right with this
mFieldsListAdapter.notifyDataSetChanged();
}
} catch (JSONException e) {
Log.e(getClass().getSimpleName(), e.getMessage());
e.printStackTrace();
}
}
#Override
public void onError(ANError anError) {
Log.e(getClass().getSimpleName(), anError.getMessage());
}
});ield.setDistance(df.format(distance) + " km");
} else {
String newValue = Double.toString(Math.floor(dist));
field.setDistance(newValue + " m");
}
Any suggestions or tips what should i do? Thank you!
"onResponse" method works on main thread, So data parsing and heavy calculations may freeze app's UI thread.
Try to move all your parsing code and calculations to AsyncTask's "doInBackground" and update your adapter in "onPostExecute" because you must be on ui thread to perform this action.
code example:
private class ResponseParser extends AsyncTask<JSONObject, Void, Void> {
#Override
protected Void doInBackground(JSONObject... params) throws JSONException {
mFieldList.clear();
JSONArray fieldsArr = params[0].getJSONArray("fields");
if (!response.getBoolean("error")) {
JSONArray fieldsArray = response.getJSONArray("fields");
for (int i = 0; i < fieldsArray.length(); i++) {
JSONObject fieldObj = fieldsArray.getJSONObject(i);
Field field = new Field();
...
field.setCertificate(fieldObj.getString("certificate"));
Log.d("Location", fieldObj.getString("address"));
// If i delete from here
if (!fieldObj.getString("address").isEmpty()) {
LatLng latLng = AppUtils.getLocationFromAddress(SearchActivityV2.this,
fieldObj.getString("address"));
float dist = AppUtils.distFrom(44.8029925f, 20.495337f, (float) latLng.latitude, (float) latLng.longitude);
DecimalFormat df = new DecimalFormat("####0.0");
if (dist > 1000) {
double distance = AppUtils.calculationByDistance(new LatLng(44.8029925, 20.495337), latLng);
field.setDistance(df.format(distance) + " km");
} else {
String newValue = Double.toString(Math.floor(dist));
field.setDistance(newValue + " m");
}
} else {
field.setDistance("1000");
}
mFieldList.add(field);
}
// to here, list would load immediately, so
// something is not right with this
}
return null;
}
#Override
protected void onPostExecute(Void aVoid) {
super.onPostExecute(aVoid);
mFieldsListAdapter.notifyDataSetChanged();
}
}
Hope it helps!
Code 1 is a part of my Fragment class
From Code 1 i am getting my place name. I want to pass that place name to a non Activity class That is to CODE 2.
Code 1
#Override
public void onActivityCreated(Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
gps = new GPSTracker(getActivity());
Geocoder geocoder= new Geocoder(getActivity(), Locale.ENGLISH);
myAddress=(TextView)getView().findViewById(R.id.gpsLocation);
surveyView = (SurveyView) getView().findViewById(R.id.surveyView);
newsHomeView = (NewsHomeView) getView().findViewById(R.id.newsHomeView);
audioView = (AudioItemView) getView().findViewById(R.id.audioView);
AudioListener listener = (AudioListener)getActivity();
audioView.setListener(listener);
newsHomeView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
MainActivity mnAct = (MainActivity)HomeFragment.this.getActivity();
mnAct.moveToPage(Constants.NEWS_PAGE);
}
});
iPrevIndex = -1;
// check if GPS enabled
if(gps.canGetLocation()){
double latitude = gps.getLatitude();
double longitude = gps.getLongitude();
// \n is for new line
//Toast.makeText(getApplicationContext(), "Your Location is - \nLat: " + latitude + "\nLong: " + longitude, Toast.LENGTH_LONG).show();
try {
//Place your latitude and longitude
// List<Address> addresses = geocoder.getFromLocation(37.423247,-122.085469, 1);
List<Address> addresses = geocoder.getFromLocation(latitude,longitude, 1);
if(addresses != null) {
Address fetchedAddress = addresses.get(0);
StringBuilder strAddress = new StringBuilder();
for(int i=0; i<=fetchedAddress.getMaxAddressLineIndex(); i++) {
strAddress.append(fetchedAddress.getAddressLine(i)).append("\n");
}
Log.i("country name ",fetchedAddress.getAddressLine(fetchedAddress.getMaxAddressLineIndex()));
String s=fetchedAddress.getAddressLine(fetchedAddress.getMaxAddressLineIndex()-1);// Bangalore, Karnataka, 560038
String str[]=s.split(" ");// array of Bangalore, Karnataka, 560038
System.out.println(Arrays.toString(str)); // print all array element
// myAddress.setText("You'r location is: " +strAddress.toString());
}
else
myAddress.setText("No location found..!");
// Toast.makeText(getActivity(),"Please switch on yor gps",Toast.LENGTH_LONG).show();
}
catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Toast.makeText(getActivity(),"Could not get address..!", Toast.LENGTH_LONG).show();
}
}else{
// can't get location
// GPS or Network is not enabled
// Ask user to enable GPS/network in settings
gps.showSettingsAlert();
}
}
CODE 2
public class Audios extends BaseCollection<Audio> {
private static String newValue;
public static setNewValue(String value) {
this.newValue = value;
//Code to use this value.
}
#Override
public void loadWithJson(JSONArray jsonObj) {
if(null == jsonObj) {
return;
}
try {
List<Audio> entries = new ArrayList<Audio>();
for (int o = 0; o < jsonObj.length(); ++o) {
Audio opt = Audio.fromJson(jsonObj.getJSONObject(o));
// String title = opt.getTitle();
//System.out.println(opt.getTitle().substring(0, 4)); // title.substring(0, 3);
// entries.add(opt);
entries.add(opt);
}
this.entries = entries;
} catch (Exception e) {
e.printStackTrace();
}
}
public void getAudioResult(JSONObject jsonRes) {
int id, grpId, dwnCount, upCount;
if(null != jsonRes) {
try {
id = jsonRes.getInt(Constants.MEDIA_ID);
grpId = jsonRes.getInt(Constants.GROUP_ID);
dwnCount= jsonRes.getInt(Constants.SET_THUMBS_DWN);
upCount = jsonRes.getInt(Constants.SET_THUMBS_UP);
}
catch(JSONException je) { id = grpId = dwnCount = upCount = -1;}
if(-1 == id || -1 == grpId) {
return;
}
for(int iLoop = 0; iLoop < entries.size(); iLoop++) {
Audio opt = entries.get(iLoop);
if(opt.token == id && opt.groupId == grpId) {
opt.thumbDwns = dwnCount;
opt.thumbUps = upCount;
break;
}
}
}
}
}
In code 1 Hear i am getting my place name
Values:
place=str[1].substring(0, 4);
AudiosFragment hm=new AudiosFragment();
Bundle bundle = new Bundle();
bundle.putString("place", str[1].substring(0, 4));
Please tell me how i will pass this place value.
easy way to pass data from one class to another is by using constructor
Consider Example:
Class A{
Object o;
private methodA()
{
B b = new B(o); //here you are passing o to Class B
b.methodB();
}
}
Class B{
Object o;
public B(Object O)
{
this.o=o;
}
public methodB()
{
use object o here
}
}
may be this will help..
You can use a Singleton class but is maybe to complex for only a String [].
public class Singleton {
private static Singleton uniqInstance;
private String str[];
private Singleton() {
}
public static synchronized Singleton getInstance() {
if (uInstance == null) {
uInstance = new Singleton();
}
return uInstance;
}
}
Just create a method inside the Audios Class.
Now, depending on the fact that you want different objects of the Audio Class to have different value for this String, you can define it static or not. Then just call that method.
Example :
Class Audios extends BaseCollection<Audio> {
private static String newValue;
public static void setNewValue(String value) {
this.newValue = value;
//Code to use this value.
..
}
}
From the Fragment, just call Audios.setNewValue("This is the value for the String");