My recyclerView works on debug but not on 'run app' - java

My code looks like this:
package com.example.humspots.fragments;
import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import com.amplifyframework.AmplifyException;
import com.amplifyframework.api.aws.AWSApiPlugin;
import com.amplifyframework.api.graphql.model.ModelMutation;
import com.amplifyframework.api.graphql.model.ModelQuery;
import com.amplifyframework.core.Amplify;
import com.amplifyframework.datastore.generated.model.Event;
import com.example.humspots.R;
import com.example.humspots.adapters.EventAdapter;
import java.util.ArrayList;
import java.util.List;
import static com.parse.Parse.getApplicationContext;
/**
* A simple {#link Fragment} subclass.
*/
public class EventsFragment extends Fragment {
public static final String EVENTBRITE_URL = "https://www.eventbriteapi.com/v3/users/me/?token=FXZ47VT64UDMVS6KNOP4";
public static final String HSU_URL = "https://25livepub.collegenet.com/calendars/student-project-humboldt-app.json";
public static final String ORGANIZATION_URL = "https://www.eventbriteapi.com/v3/organizations/436148186604/events/?token=FXZ47VT64UDMVS6KNOP4";
public static final String TAG = "EventsFragment";
EventAdapter eventAdapter;
List<Event> events;
RecyclerView rvEvents;
public EventsFragment() {
// Required empty public constructor
}
#Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
// Inflate the layout for this fragment
return inflater.inflate(R.layout.fragment_events, container, false);
}
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
rvEvents = view.findViewById(R.id.rvEvents);
//bottomNavigationView = findViewById(R.id.bottomNavigation);
events = new ArrayList<>();
amplifyAndSetAdapter();
eventAdapter.notifyDataSetChanged();
}
private void addEventToAWS() {
Event todo = Event.builder().eventTitle("My todo")
.eventDate("11/21/20")
.eventTime("11:30:00")
.extraInfo("AHHHHHHHHHHHHHHHHH")
.category("temp")
.description("this is a description")
.template("Lost Coast")
.postUrl("https://docs.amplify.aws/lib/graphqlapi/mutate-data/q/platform/android")
.venue("McDonalds")
.build();
Amplify.API.mutate(
ModelMutation.create(todo),
response -> Log.i(TAG, "Added Todo with id: " + response.getData().getId()),
error -> Log.e(TAG, "Create failed", error)
);
}
private void amplifyAndSetAdapter() {
initializeAmplify();
amplifyQuery();
}
private void initializeAmplify() {
try {
// Add these lines to add the AWSApiPlugin plugins
Amplify.addPlugin(new AWSApiPlugin());
Amplify.configure(getApplicationContext());
Log.i(TAG, "Initialized Amplify");
} catch (AmplifyException error) {
Log.e(TAG, "Could not initialize Amplify", error);
}
}
private void amplifyQuery() {
//create the adapter
eventAdapter = new EventAdapter(getContext(), events);
//set a layout manager on RV
rvEvents.setLayoutManager(new LinearLayoutManager(getContext()));
//set the adapter on the recycler view
rvEvents.setAdapter(eventAdapter);
Amplify.API.query(
ModelQuery.list(Event.class),
response -> {
for (Event event : response.getData()) {
Log.i("Amplify", event.getEventTitle() + " " + event.getEventDate() + " " + event.getEventTime() + " " + event.getCategory()
+ " " + event.getPostUrl() + " " + event.getExtraInfo() + " " + event.getVenue() + " " + event.getTemplate());
addEvents(event);
}
},
error -> Log.e("Amplify", "Query failure", error)
);
}
private void addEvents(Event event) {
try {
events.add(event);
Log.i(TAG, "Events: " + events.size());
} catch (Exception e) {
Log.e(TAG, "Events: ", e);
}
}
}
the EventAdapter looks like this:
package com.example.humspots.adapters;
import android.content.Context;
import android.content.Intent;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.amplifyframework.datastore.generated.model.Event;
import com.bumptech.glide.Glide;
import com.example.humspots.DetailActivity;
import com.example.humspots.R;
import org.parceler.Parcels;
import java.util.List;
public class EventAdapter extends RecyclerView.Adapter<EventAdapter.ViewHolder> {
Context context;
List<Event> events;
public EventAdapter(Context context, List<Event> events) {
this.context = context;
this.events = events;
}
//usually involves inflating a layout from XML and returning the viewholder
#NonNull
#Override
public ViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View eventView = LayoutInflater.from(context).inflate(R.layout.item_event, parent, false);
return new ViewHolder(eventView);
}
//involves populating data into the item through holder
#Override
public void onBindViewHolder(#NonNull ViewHolder holder, int position) {
//get the event at the given position
Event event = events.get(position);
//bind the event data into the view holder
holder.bind(event);
}
//returns the total number of items in the list
#Override
public int getItemCount() {
return events.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
RelativeLayout container;
TextView tvDay;
TextView tvMonth;
TextView tvEventTitle;
TextView tvSummary;
ImageView ivEventImage;
public ViewHolder(#NonNull View itemView) {
super(itemView);
container = itemView.findViewById(R.id.Container);
tvDay = itemView.findViewById(R.id.tvDay);
tvMonth = itemView.findViewById(R.id.tvMonth);
tvEventTitle = itemView.findViewById(R.id.tvEventTitle);
tvSummary = itemView.findViewById(R.id.tvSummary);
ivEventImage = itemView.findViewById(R.id.ivEventImage);
}
public void bind(final Event event) {
tvDay.setText(event.getDayOfMonth());
tvMonth.setText(event.getMonthOfYear());
tvEventTitle.setText(event.getEventTitle());
tvSummary.setText(event.getDescription());
//Glide.with(context).load(event.getPostUrl()).into(ivEventImage);
//register the click listener on the whole container.
container.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
//then, navigate to new activity on click.
Intent i = new Intent(context, DetailActivity.class);
i.putExtra("event", Parcels.wrap(event));
context.startActivity(i);
}
});
}
}
}
event looks like this:
package com.amplifyframework.datastore.generated.model;
import java.util.List;
import java.util.UUID;
import java.util.Objects;
import androidx.core.util.ObjectsCompat;
import com.amplifyframework.core.model.Model;
import com.amplifyframework.core.model.annotations.Index;
import com.amplifyframework.core.model.annotations.ModelConfig;
import com.amplifyframework.core.model.annotations.ModelField;
import com.amplifyframework.core.model.query.predicate.QueryField;
import static com.amplifyframework.core.model.query.predicate.QueryField.field;
/** This is an auto generated class representing the Event type in your schema. */
#SuppressWarnings("all")
#ModelConfig(pluralName = "Events")
public final class Event implements Model {
public static final QueryField ID = field("id");
public static final QueryField EVENT_TITLE = field("EventTitle");
public static final QueryField DESCRIPTION = field("Description");
public static final QueryField EVENT_DATE = field("EventDate");
public static final QueryField EVENT_TIME = field("EventTime");
public static final QueryField CATEGORY = field("Category");
public static final QueryField POST_URL = field("PostURL");
public static final QueryField EXTRA_INFO = field("ExtraInfo");
public static final QueryField VENUE = field("Venue");
public static final QueryField TEMPLATE = field("Template");
private final #ModelField(targetType="ID", isRequired = true) String id;
private final #ModelField(targetType="String") String EventTitle;
private final #ModelField(targetType="String") String Description;
private final #ModelField(targetType="String") String EventDate;
private final #ModelField(targetType="String") String EventTime;
private final #ModelField(targetType="String") String Category;
private final #ModelField(targetType="String") String PostURL;
private final #ModelField(targetType="String") String ExtraInfo;
private final #ModelField(targetType="String") String Venue;
private final #ModelField(targetType="String") String Template;
public String getId() {
return id;
}
public String getEventTitle() {
return EventTitle;
}
public String getDescription() {
return Description;
}
public String getEventDate() {
return EventDate;
}
public String getEventTime() {
return EventTime;
}
public String getCategory() {
return Category;
}
public String getPostUrl() {
return PostURL;
}
public String getExtraInfo() {
return ExtraInfo;
}
public String getVenue() {
return Venue;
}
public String getTemplate() {
return Template;
}
private Event(String id, String EventTitle, String Description, String EventDate, String EventTime, String Category, String PostURL, String ExtraInfo, String Venue, String Template) {
this.id = id;
this.EventTitle = EventTitle;
this.Description = Description;
this.EventDate = EventDate;
this.EventTime = EventTime;
this.Category = Category;
this.PostURL = PostURL;
this.ExtraInfo = ExtraInfo;
this.Venue = Venue;
this.Template = Template;
}
#Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
} else if(obj == null || getClass() != obj.getClass()) {
return false;
} else {
Event event = (Event) obj;
return ObjectsCompat.equals(getId(), event.getId()) &&
ObjectsCompat.equals(getEventTitle(), event.getEventTitle()) &&
ObjectsCompat.equals(getDescription(), event.getDescription()) &&
ObjectsCompat.equals(getEventDate(), event.getEventDate()) &&
ObjectsCompat.equals(getEventTime(), event.getEventTime()) &&
ObjectsCompat.equals(getCategory(), event.getCategory()) &&
ObjectsCompat.equals(getPostUrl(), event.getPostUrl()) &&
ObjectsCompat.equals(getExtraInfo(), event.getExtraInfo()) &&
ObjectsCompat.equals(getVenue(), event.getVenue()) &&
ObjectsCompat.equals(getTemplate(), event.getTemplate());
}
}
#Override
public int hashCode() {
return new StringBuilder()
.append(getId())
.append(getEventTitle())
.append(getDescription())
.append(getEventDate())
.append(getEventTime())
.append(getCategory())
.append(getPostUrl())
.append(getExtraInfo())
.append(getVenue())
.append(getTemplate())
.toString()
.hashCode();
}
#Override
public String toString() {
return new StringBuilder()
.append("Event {")
.append("id=" + String.valueOf(getId()) + ", ")
.append("EventTitle=" + String.valueOf(getEventTitle()) + ", ")
.append("Description=" + String.valueOf(getDescription()) + ", ")
.append("EventDate=" + String.valueOf(getEventDate()) + ", ")
.append("EventTime=" + String.valueOf(getEventTime()) + ", ")
.append("Category=" + String.valueOf(getCategory()) + ", ")
.append("PostURL=" + String.valueOf(getPostUrl()) + ", ")
.append("ExtraInfo=" + String.valueOf(getExtraInfo()) + ", ")
.append("Venue=" + String.valueOf(getVenue()) + ", ")
.append("Template=" + String.valueOf(getTemplate()))
.append("}")
.toString();
}
public static BuildStep builder() {
return new Builder();
}
/**
* WARNING: This method should not be used to build an instance of this object for a CREATE mutation.
* This is a convenience method to return an instance of the object with only its ID populated
* to be used in the context of a parameter in a delete mutation or referencing a foreign key
* in a relationship.
* #param id the id of the existing item this instance will represent
* #return an instance of this model with only ID populated
* #throws IllegalArgumentException Checks that ID is in the proper format
*/
public static Event justId(String id) {
try {
UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
} catch (Exception exception) {
throw new IllegalArgumentException(
"Model IDs must be unique in the format of UUID. This method is for creating instances " +
"of an existing object with only its ID field for sending as a mutation parameter. When " +
"creating a new object, use the standard builder method and leave the ID field blank."
);
}
return new Event(
id,
null,
null,
null,
null,
null,
null,
null,
null,
null
);
}
public CopyOfBuilder copyOfBuilder() {
return new CopyOfBuilder(id,
EventTitle,
Description,
EventDate,
EventTime,
Category,
PostURL,
ExtraInfo,
Venue,
Template);
}
public interface BuildStep {
Event build();
BuildStep id(String id) throws IllegalArgumentException;
BuildStep eventTitle(String eventTitle);
BuildStep description(String description);
BuildStep eventDate(String eventDate);
BuildStep eventTime(String eventTime);
BuildStep category(String category);
BuildStep postUrl(String postUrl);
BuildStep extraInfo(String extraInfo);
BuildStep venue(String venue);
BuildStep template(String template);
}
public static class Builder implements BuildStep {
private String id;
private String EventTitle;
private String Description;
private String EventDate;
private String EventTime;
private String Category;
private String PostURL;
private String ExtraInfo;
private String Venue;
private String Template;
#Override
public Event build() {
String id = this.id != null ? this.id : UUID.randomUUID().toString();
return new Event(
id,
EventTitle,
Description,
EventDate,
EventTime,
Category,
PostURL,
ExtraInfo,
Venue,
Template);
}
#Override
public BuildStep eventTitle(String eventTitle) {
this.EventTitle = eventTitle;
return this;
}
#Override
public BuildStep description(String description) {
this.Description = description;
return this;
}
#Override
public BuildStep eventDate(String eventDate) {
this.EventDate = eventDate;
return this;
}
#Override
public BuildStep eventTime(String eventTime) {
this.EventTime = eventTime;
return this;
}
#Override
public BuildStep category(String category) {
this.Category = category;
return this;
}
#Override
public BuildStep postUrl(String postUrl) {
this.PostURL = postUrl;
return this;
}
#Override
public BuildStep extraInfo(String extraInfo) {
this.ExtraInfo = extraInfo;
return this;
}
#Override
public BuildStep venue(String venue) {
this.Venue = venue;
return this;
}
#Override
public BuildStep template(String template) {
this.Template = template;
return this;
}
/**
* WARNING: Do not set ID when creating a new object. Leave this blank and one will be auto generated for you.
* This should only be set when referring to an already existing object.
* #param id id
* #return Current Builder instance, for fluent method chaining
* #throws IllegalArgumentException Checks that ID is in the proper format
*/
public BuildStep id(String id) throws IllegalArgumentException {
this.id = id;
try {
UUID.fromString(id); // Check that ID is in the UUID format - if not an exception is thrown
} catch (Exception exception) {
throw new IllegalArgumentException("Model IDs must be unique in the format of UUID.",
exception);
}
return this;
}
}
public final class CopyOfBuilder extends Builder {
private CopyOfBuilder(String id, String eventTitle, String description, String eventDate, String eventTime, String category, String postUrl, String extraInfo, String venue, String template) {
super.id(id);
super.eventTitle(eventTitle)
.description(description)
.eventDate(eventDate)
.eventTime(eventTime)
.category(category)
.postUrl(postUrl)
.extraInfo(extraInfo)
.venue(venue)
.template(template);
}
#Override
public CopyOfBuilder eventTitle(String eventTitle) {
return (CopyOfBuilder) super.eventTitle(eventTitle);
}
#Override
public CopyOfBuilder description(String description) {
return (CopyOfBuilder) super.description(description);
}
#Override
public CopyOfBuilder eventDate(String eventDate) {
return (CopyOfBuilder) super.eventDate(eventDate);
}
#Override
public CopyOfBuilder eventTime(String eventTime) {
return (CopyOfBuilder) super.eventTime(eventTime);
}
#Override
public CopyOfBuilder category(String category) {
return (CopyOfBuilder) super.category(category);
}
#Override
public CopyOfBuilder postUrl(String postUrl) {
return (CopyOfBuilder) super.postUrl(postUrl);
}
#Override
public CopyOfBuilder extraInfo(String extraInfo) {
return (CopyOfBuilder) super.extraInfo(extraInfo);
}
#Override
public CopyOfBuilder venue(String venue) {
return (CopyOfBuilder) super.venue(venue);
}
#Override
public CopyOfBuilder template(String template) {
return (CopyOfBuilder) super.template(template);
}
}
public String getDayOfMonth() {
return EventDate.substring(5, 7);
}
public String getMonthOfYear() {
return EventDate.substring(0, 3);}
}
So far I have tried moving the eventAdapter.notifyDataSetChanged(); around to try to get it to work on 'run app'; however no matter where I put it it'll throw an error or it'll only show the data when I run it with debug.
I tried moving the:
//create the adapter
eventAdapter = new EventAdapter(getContext(), events);
//set a layout manager on RV
rvEvents.setLayoutManager(new LinearLayoutManager(getContext()));
//set the adapter on the recycler view
rvEvents.setAdapter(eventAdapter);
to different spots as well but it doesnt change anything. I dont know what I am doing wrong.

I had to change a few things as well as add a new thread and wait function:
#Override
public void onViewCreated(#NonNull View view, #Nullable Bundle savedInstanceState) {
super.onViewCreated(view, savedInstanceState);
rvEvents = view.findViewById(R.id.rvEvents);
//set a layout manager on RV
rvEvents.setLayoutManager(new LinearLayoutManager(getContext()));
//set the adapter on the recycler view
rvEvents.setAdapter(eventAdapter);
amplifyAndSetAdapter();
//for some reason the code only works with both notifyDataSetChanged (other is in the other thread)
eventAdapter.notifyDataSetChanged();
}
private void amplifyAndSetAdapter() {
initializeAmplify();
amplifyQuery();
}
private void initializeAmplify() {
try {
// Add these lines to add the AWSApiPlugin plugins
Amplify.addPlugin(new AWSApiPlugin());
Amplify.configure(getApplicationContext());
Log.i(TAG, "Initialized Amplify");
} catch (AmplifyException error) {
Log.e(TAG, "Could not initialize Amplify", error);
}
}
private void amplifyQuery() {
Amplify.API.query(
ModelQuery.list(Event.class),
response -> {
for (Event event : response.getData()) {
Log.i("Amplify", "Title: " + event.getEventTitle() + " Date: " + event.getEventDate() + " Time: " + event.getEventTime()
+ " PostURL: " + event.getPostUrl() + " ExtraInfo: " + event.getExtraInfo() + " Venue: " + event.getVenue() + " Template: " + event.getTemplate());
addEvents(event);
}
//Used to seperate the ui using a wait function to add the proper time delay so that an error isnt thrown
Thread thread = new Thread(){
#Override
public void run() {
try {
synchronized (this) {
wait(100);
runOnUiThread(new Runnable() {
#Override
public void run() {
eventAdapter.notifyDataSetChanged();
}
});
}
} catch (InterruptedException e) {
e.printStackTrace();
}};
};
thread.start();
},
error -> Log.e("Amplify", "Query failure", error)
);
}
private void addEvents(Event event) {
try {
events.add(event);
Log.i(TAG, "Events: " + events.size());
} catch (Exception e) {
Log.e(TAG, "Events: ", e);
}
}
}

Related

How to create array from values that existing in another array

I have a small problem that I can't solve:
I have an array of objects (Country) that I get them from API.
One of the parameters in each object(Country) is an array of border Country - value name = border.
In one Fragment I show all the countries that get from API.
One of my goals is to click on a some country and will opens a new screen where all the countries bordering the country I clicked on will be shown.
I already have all the logic of switching between screens, RecyclerViews on both screen and more, but I don't know how to create and parse the new array of the bordering countries to the new screen.
That what i have for now:
All countries adapter:
public class CountryAdapter extends RecyclerView.Adapter<CountryAdapter.CountryViewHolder> {
#Override
public void onBindViewHolder(#NonNull CountryViewHolder holder, final int position) {
holder.mTVCountryName.setText(countries.get(position).getName());
holder.mTVCountryNativeName.setText(countries.get(position).getNativeName());
GlideToVectorYou
.init()
.with(mContext)
.load(Uri.parse(countries.get(position).getFlag()), holder.mCountryFlag);
holder.mCountryFlag.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
if (iOnItemClickListener != null) {
//Array list of all border countries by alpha3 value
List<String> borderCountriesAlpha3 = new ArrayList<>();
for (int i = 0; i < countries.get(position).getBorders().size(); i++) {
try {
borderCountriesAlpha3.add(countries.get(position).getBorders().get(i));
} catch (Exception e) {
}
}
iOnItemClickListener.onItemClick(position, borderCountriesAlpha3);
}
}
});
}
Getting the data from API:
public void getAllCountries(){
ApiService apiService = ApiClient.getRetrofitInstance().create(ApiService.class);
call = apiService.getAllCountries();
call.enqueue(new Callback<List<Country>>() {
#Override
public void onResponse(Call<List<Country>> call, Response<List<Country>> response) {
mCountryPresenter.generateDataList(response.body());
}
#Override
public void onFailure(Call<List<Country>> call, Throwable t) {
}
});
}
Country pojo class:
public class Country implements Comparable<Country> {
#SerializedName("name")
#Expose
private String name;
#SerializedName("alpha3Code")
#Expose
private String alpha3Code;
#SerializedName("borders")
#Expose
private List<String> borders = null;
#SerializedName("nativeName")
#Expose
private String nativeName;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAlpha3Code() {
return alpha3Code;
}
public void setAlpha3Code(String alpha3Code) {
this.alpha3Code = alpha3Code;
}
public List<String> getBorders() {
return borders;
}
public void setBorders(List<String> borders) {
this.borders = borders;
}
public String getNativeName() {
return nativeName;
}
public void setNativeName(String nativeName) {
this.nativeName = nativeName;
}
}
Fragment that contain recycler view for all countries:
public class CountryListFragment extends Fragment implements CountryPresenter {
private View view;
private RecyclerView mRVCountries;
private CountryAdapter mCountryAdapter;
private CountriesView mCountriesView;
#Nullable
#Override
public View onCreateView(#NonNull LayoutInflater inflater, #Nullable ViewGroup container, #Nullable Bundle savedInstanceState) {
view = inflater.inflate(R.layout.fragment_country_list, container, false);
initView(view);
initClasses();
initContentView();
return view;
}
private void initClasses() {
mCountriesView = new CountriesView(this, getContext());
}
private void initView(View view) {
mRVCountries = view.findViewById(R.id.rvCountries);
}
private void initContentView() {
mCountriesView.getAllCountries();
}
#Override
public void generateDataList(List<Country> countries) {
mCountryAdapter = new CountryAdapter(countries, getContext(), getActivity());
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(getContext());
mRVCountries.setLayoutManager(layoutManager);
mRVCountries.setAdapter(mCountryAdapter);
mCountryAdapter.setiOnItemClickListener(new CountryAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position, List<String> borderCountries) {
Log.d("myDebug", "onItemClick: " + position + " " + borderCountries);
}
});
}
public void sortByNativeName() {
mCountryAdapter.sortByNativeName();
}
public void sortByArea() {
mCountryAdapter.sortByArea();
}
}
You can use Java's streaming API or Collections API to search a list, copy a sublist to another etc. Here is an example of your requirement of finding bordering countries for a given country and get a lost of border country objects -
package com.advisory.pic.etl.claim.standardize;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Test {
public static void main(String[] args) {
}
public void workOnCountries(){
List<Country> countries = Arrays.asList(new Country("United States","USA",Arrays.asList("MXO","CDA")),
new Country("Mexico","MXO",Arrays.asList("USA","CLB")),
new Country("Colombia","CLB",Arrays.asList("MXO","VNZ")),
new Country("Canada","CNA",Arrays.asList("USA")));
//get list of neighbouring countries for USA
//first find USA in the list of countries
Country country = null;
for(Country c : countries){
if(c.alpha3Code.equalsIgnoreCase("USA")){
country = c;
}
}
//find border countries
List<String> b = country.borders;
//get border contries from main country list
List<Country> borderCountries = countries.stream().filter(c -> b.contains(c)).collect(Collectors.toList());
}
private class Country{
Country(String name, String alpha3Code, List<String> borders){
this.name = name;
this.alpha3Code = alpha3Code;
this.borders = borders;
}
private String name;
private String alpha3Code;
private List<String> borders = null;
}
}
if you want to pass array of objects to another screen you can use serialize in bundle
mCountryAdapter.setiOnItemClickListener(new CountryAdapter.OnItemClickListener() {
#Override
public void onItemClick(int position, List<String> borderCountries) {
Bundle bundle=new Bundle();
bundle.putSerializable("list",(ArrayList<String>) borderCountries);
// then you can add bundle to intent if you navigate activity or navigate
//fragment set this bundle
Log.d("myDebug", "onItemClick: " + position + " " + borderCountries);
}
});

Firebase model POJO getter returns null in FirebaseRecyclerAdapter

I have a FirebaseRecyclerAdapter fetching data from the firebase database but when I am trying to access firebase data the getter method of the POJO returns null. I am able to get the database reference key.
final Query beveragesQuery = mDatabaseReference.child(FirebaseValues.PRODUCTS)
.child(FirebaseValues.BEVERAGES);
FirebaseRecyclerOptions<GenericProductModel> beveragesOptions =
new FirebaseRecyclerOptions.Builder<GenericProductModel>()
.setQuery(beveragesQuery, GenericProductModel.class)
.build();
adapter = new FirebaseRecyclerAdapter<GenericProductModel, Combos.MovieViewHolder>(
beveragesOptions
) {
#NonNull
#Override
public Combos.MovieViewHolder onCreateViewHolder(#NonNull ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.cards_cardview_layout, parent, false);
return new Combos.MovieViewHolder(view);
}
#Override
protected void onBindViewHolder(#NonNull Combos.MovieViewHolder viewHolder, int position, #NonNull GenericProductModel model) {
Log.d(TAG, "Item received:"+getRef(position).getKey());
String json = new Gson().toJson(model);
Log.d(TAG, "Item received:"+ json);
Log.d(TAG, "Item received:"+ model.toString());
if (tv_no_item.getVisibility() == View.VISIBLE) {
tv_no_item.setVisibility(View.GONE);
}
Log.d(TAG, "card name:"+model.getCardname());
viewHolder.cardname.setText(model.getCardname());
viewHolder.cardprice.setText("₹ " + Float.toString(model.getCardprice()));
Picasso.get().load(model.getCardimage()).into(viewHolder.cardimage);
viewHolder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
Intent intent = new Intent(Beverages.this, IndividualProduct.class);
intent.putExtra("product", getItem(position));
startActivity(intent);
}
});
}
#Override
public void onError(DatabaseError e) {
Log.e(TAG, "RV Adapter, Error occurred: " + e.getMessage());
}
};
mLayoutManager = new StaggeredGridLayoutManager(2, StaggeredGridLayoutManager.VERTICAL);
mRecyclerView.setLayoutManager(mLayoutManager);
adapter.startListening();
mRecyclerView.setAdapter(adapter);
}
My POJO or model class is
public class GenericProductModel implements Serializable {
public int cardid;
public String cardname;
public String cardimage;
public String carddescription;
public float cardprice;
public GenericProductModel() {
}
public GenericProductModel(int cardid, String cardname, String cardimage, String carddescription, float cardprice) {
this.cardid = cardid;
this.cardname = cardname;
this.cardimage = cardimage;
this.carddescription = carddescription;
this.cardprice = cardprice;
}
public int getCardid() {
return cardid;
}
public String getCardname() {
return cardname;
}
public String getCardimage() {
return cardimage;
}
public String getCarddescription() {
return carddescription;
}
public float getCardprice() {
return cardprice;
}
public void setCardid(int cardid) {
this.cardid = cardid;
}
public void setCardname(String cardname) {
this.cardname = cardname;
}
public void setCardimage(String cardimage) {
this.cardimage = cardimage;
}
public void setCarddescription(String carddescription) {
this.carddescription = carddescription;
}
public void setCardprice(float cardprice) {
this.cardprice = cardprice;
}
}
I am implementing Serializable because I am sending this data as an intent to other activity.
Added some more log options for clearity
When I run the app the log output I am getting is:
03-17 15:05:55.200 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: Item received, received:1
03-17 15:05:55.227 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: Item received:{"a":0,"e":0.0}
03-17 15:05:55.227 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: Item received:com.vdeveloper.chaisutta.b.a#63d3fc
03-17 15:05:55.227 4501-4501/com.vdeveloper.chaisutta D/BeveragesTAG: card name:null
Database Screenshot:
I have found a solution myself. The problem was with my POJO. As this project was on androidx I need to add the annotation "#Keep" to stop the compiler from removing methods which it thinks are redundant.
import java.io.Serializable;
import androidx.annotation.Keep;
#Keep
public class GenericProductModel implements Serializable {
public int cardid;
public String cardname;
public String cardimage;
public String carddescription;
public float cardprice;
public GenericProductModel() {
}
public GenericProductModel(int cardid, String cardname, String cardimage, String carddescription, float cardprice) {
this.cardid = cardid;
this.cardname = cardname;
this.cardimage = cardimage;
this.carddescription = carddescription;
this.cardprice = cardprice;
}
public int getCardid() {
return cardid;
}
public String getCardname() {
return cardname;
}
public String getCardimage() {
return cardimage;
}
public String getCarddescription() {
return carddescription;
}
public float getCardprice() {
return cardprice;
}
public void setCardid(int cardid) {
this.cardid = cardid;
}
public void setCardname(String cardname) {
this.cardname = cardname;
}
public void setCardimage(String cardimage) {
this.cardimage = cardimage;
}
public void setCarddescription(String carddescription) {
this.carddescription = carddescription;
}
public void setCardprice(float cardprice) {
this.cardprice = cardprice;
}
}
Thanks, everyone for helping
You are getting null because all your values are null since you are returning in each getter this.fieldName instead of the fieldName. To solve this, please change your getters to:
public int getCardid() {
return cardid;
}
public String getCardname() {
return cardname;
}
public String getCardimage() {
return cardimage;
}
public String getCarddescription() {
return carddescription;
}
public float getCardprice() {
return cardprice;
}
See, there is no this anymore.

Issue with ArrayList from JSON using Retrofit and populating RecyclerView

I’ve been trying to get recycler view working with retrofit. I seem to be pulling in the JSON fine from within getRecipes() method, and my logs are showing me that the some data is there.
However, when I call my getRecipes() method from onCreate(), something seems to be going wrong. When I check to see if my recipeList array contains my JSON results within onCreate, it is telling me it is empty. Why is it doing this if my logs within my getRecipes() method are showing me that data is there...?
Not sure if it is an issue with my recycler view or what I am doing with retrofit, or something else. Been trying for days to figure out, so any advice would be greatly appreciated.
JSON
https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/baking.json
public class ItemListActivity extends AppCompatActivity {
private boolean mTwoPane;
public static final String LOG_TAG = "myLogs";
public static List<Recipe> recipeList = new ArrayList<>();
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getRecipes();
setContentView(R.layout.activity_item_list);
getRecipes();
//Logging to check that recipeList contains data
if(recipeList.isEmpty()){
Log.d(LOG_TAG, "Is empty");
}else {
Log.d(LOG_TAG, "Is not empty");
}
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
toolbar.setTitle(getTitle());
RecyclerView recyclerView = (RecyclerView) findViewById(R.id.item_list);
RecyclerView.LayoutManager layoutManager = new LinearLayoutManager(this);
recyclerView.setLayoutManager(layoutManager);
SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);
if (findViewById(R.id.item_detail_container) != null) {
mTwoPane = true;
}
}
public void getRecipes(){
String ROOT_URL = "https://d17h27t6h515a5.cloudfront.net/topher/2017/May/59121517_baking/";
Retrofit RETROFIT = new Retrofit.Builder()
.baseUrl(ROOT_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
RecipeService service = RETROFIT.create(RecipeService.class);
Call<List<Recipe>> call = service.getMyJson();
call.enqueue(new Callback<List<Recipe>>() {
#Override
public void onResponse(Call<List<Recipe>> call, Response<List<Recipe>> response) {
Log.d(LOG_TAG, "Got here");
if (!response.isSuccessful()) {
Log.d(LOG_TAG, "No Success");
}
Log.d(LOG_TAG, "Got here");
recipeList = response.body();
//Logging to check data is there
Log.v(LOG_TAG, "LOGS" + recipeList.size());
for (int i = 0; i < recipeList.size(); i++) {
String newString = recipeList.get(i).getName();
Ingredients[] ingredients = recipeList.get(i).getIngredients();
for(int j = 0; j < ingredients.length; j++){
Log.d(LOG_TAG, ingredients[j].getIngredient());
}
Steps[] steps = recipeList.get(i).getSteps();
for(int k = 0; k < steps.length; k++){
Log.d(LOG_TAG, steps[k].getDescription());
}
Log.d(LOG_TAG, newString);
}
}
#Override
public void onFailure(Call<List<Recipe>> call, Throwable t) {
Log.e("getRecipes throwable: ", t.getMessage());
t.printStackTrace();
}
});
}
public class SimpleItemRecyclerViewAdapter
extends RecyclerView.Adapter<SimpleItemRecyclerViewAdapter.ViewHolder> {
private final List<Recipe> mValues;
public SimpleItemRecyclerViewAdapter(List<Recipe> items) {
mValues = items;
}
#Override
public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View view = LayoutInflater.from(parent.getContext())
.inflate(R.layout.item_list_content, parent, false);
return new ViewHolder(view);
}
#Override
public void onBindViewHolder(final ViewHolder holder, int position) {
holder.mItem = mValues.get(position);
holder.mContentView.setText(mValues.get(position).getName());
holder.mView.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View v) {
if (mTwoPane) {
Bundle arguments = new Bundle();
arguments.putString(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getId());
ItemDetailFragment fragment = new ItemDetailFragment();
fragment.setArguments(arguments);
getSupportFragmentManager().beginTransaction()
.replace(R.id.item_detail_container, fragment)
.commit();
} else {
Context context = v.getContext();
Intent intent = new Intent(context, ItemDetailActivity.class);
intent.putExtra(ItemDetailFragment.ARG_ITEM_ID, holder.mItem.getId());
context.startActivity(intent);
}
}
});
}
#Override
public int getItemCount() {
return mValues.size();
}
public class ViewHolder extends RecyclerView.ViewHolder {
public View mView;
public TextView mContentView;
public Recipe mItem;
public ViewHolder(View view) {
super(view);
mView = view;
mContentView = (TextView) view.findViewById(R.id.content);
}
#Override
public String toString() {
return super.toString() + " '" + mContentView.getText() + "'";
}
}
}
RecipeService
public interface RecipeService {
#GET("baking.json")
Call<List<Recipe>> getMyJson();}
Models
Recipe
public class Recipe{
private Ingredients[] ingredients;
private String id;
private String servings;
private String name;
private String image;
private Steps[] steps;
public Ingredients[] getIngredients ()
{
return ingredients;
}
public void setIngredients (Ingredients[] ingredients)
{
this.ingredients = ingredients;
}
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public String getServings ()
{
return servings;
}
public void setServings (String servings)
{
this.servings = servings;
}
public String getName ()
{
return name;
}
public void setName (String name)
{
this.name = name;
}
public String getImage ()
{
return image;
}
public void setImage (String image)
{
this.image = image;
}
public Steps[] getSteps ()
{
return steps;
}
public void setSteps (Steps[] steps)
{
this.steps = steps;
}
#Override
public String toString()
{
return "[ingredients = "+ingredients+", id = "+id+", servings = "+servings+", name = "+name+", image = "+image+", steps = "+steps+"]";
}}
Ingredients
public class Ingredients{
private String measure;
private String ingredient;
private String quantity;
public String getMeasure ()
{
return measure;
}
public void setMeasure (String measure)
{
this.measure = measure;
}
public String getIngredient ()
{
return ingredient;
}
public void setIngredient (String ingredient)
{
this.ingredient = ingredient;
}
public String getQuantity ()
{
return quantity;
}
public void setQuantity (String quantity)
{
this.quantity = quantity;
}
#Override
public String toString()
{
return "[measure = "+measure+", ingredient = "+ingredient+", quantity = "+quantity+"]";
}}
Steps
public class Steps{
private String id;
private String shortDescription;
private String description;
private String videoURL;
private String thumbnailURL;
public String getId ()
{
return id;
}
public void setId (String id)
{
this.id = id;
}
public String getShortDescription ()
{
return shortDescription;
}
public void setShortDescription (String shortDescription)
{
this.shortDescription = shortDescription;
}
public String getDescription ()
{
return description;
}
public void setDescription (String description)
{
this.description = description;
}
public String getVideoURL ()
{
return videoURL;
}
public void setVideoURL (String videoURL)
{
this.videoURL = videoURL;
}
public String getThumbnailURL ()
{
return thumbnailURL;
}
public void setThumbnailURL (String thumbnailURL)
{
this.thumbnailURL = thumbnailURL;
}
#Override
public String toString()
{
return "[id = "+id+", shortDescription = "+shortDescription+", description = "+description+", videoURL = "+videoURL+", thumbnailURL = "+thumbnailURL+"]";
}}
Logs
https://gist.github.com/2triggers/12b6eeb32ed8909ab50bbadd4742d7f7
this will be empty always because this line will execute before getting the response from a server.
if(recipeList.isEmpty()){
Log.d(LOG_TAG, "Is empty");
}else {
Log.d(LOG_TAG, "Is not empty");
}
Better call this after this line recipeList = response.body();
SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);
if (findViewById(R.id.item_detail_container) != null) {
mTwoPane = true;
}
it is because you are sending the recipelist into the adapter before even it is populated , after you are sending the recipelist into the adapter which is empty you are populating your recipelist from getRecipes method, you might be wondering you have declared the getRecipes method before even you are assigning the recipelist to adapter so how come it is empty, yea but the fact is your getRecipes work on background thread so even before your recipelist gets populated your adapter assignment takes place on the main thread so you are basically assigning the empty list, one thing you can do is notify when the adapter when the data changes or when the the recipelist is filled with data that is from within the getRecipe method.
when you assign the recipelist = response.body right after this you can notify the adapter
or move this two lines
SimpleItemRecyclerViewAdapter simpleItemRecyclerViewAdapter = new SimpleItemRecyclerViewAdapter(recipeList);
recyclerView.setAdapter(simpleItemRecyclerViewAdapter);
right after the
recipelist = response.body;
in getRecipes method
Try create the Constructor with all atributes from your Recipe.class
Like:
public Ingredients(String measure, String ingredients, String quantity ){
this.measure = measure;
this.ingredients = ingredients;
this.quantity = quantity
}
Do same in all class where make up your object of list.

Variable is not reflecting the assigned value while working with retrofit library: Android

I am trying to get the photo of the day from bing using this url
http://www.bing.com/HPImageArchive.aspx?format=js&idx=0&n=1&mkt=en-US
I am having trouble saving the value of the url which i am getting through retrofit library.
This is my code:
MainActivity.class
package com.gadgetsaint.downloadmanagerexample;
import android.Manifest;
import android.app.DownloadManager;
import android.support.v4.app.NotificationCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import java.util.ArrayList;
import retrofit.Call;
import retrofit.Callback;
import retrofit.Response;
import retrofit.Retrofit;
public class MainActivity extends AppCompatActivity {
private DownloadManager downloadManager;
private long refid;
private Uri Download_Uri;
String url,name;
ArrayList<Long> list = new ArrayList<>();
ApiInterface apiService;
TextView btnSingle ;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
apiService=ApiClient.getClient().create(ApiInterface.class);
downloadManager = (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
getImageUrl();
registerReceiver(onComplete,
new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
//url is showing null value even after assigning the data obtained through json .
Download_Uri = Uri.parse(url);
btnSingle = (TextView) findViewById(R.id.single);
btnSingle.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
list.clear();
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverRoaming(false);
request.setTitle("Abhishek Adhikari's file Downloading " + name + ".png");
request.setDescription("Downloading " + name + ".jpg");
request.setVisibleInDownloadsUi(true);
request.setDestinationInExternalPublicDir(Environment.getExternalStorageState(), "/adhikariabhishek/" + "/" + name + ".jpg");
refid = downloadManager.enqueue(request);
Log.e("OUT", "" + refid);
list.add(refid);
}
});
// TextView btnMultiple = (TextView) findViewById(R.id.multiple);
if(!isStoragePermissionGranted())
{
}
/* btnMultiple.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
list.clear();
for(int i = 0; i < 2; i++)
{
DownloadManager.Request request = new DownloadManager.Request(Download_Uri);
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setAllowedOverRoaming(false);
request.setTitle("GadgetSaint Downloading " + "Sample_" + i + ".png");
request.setDescription("Downloading " + "Sample_" + i + ".png");
request.setVisibleInDownloadsUi(true);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, "/GadgetSaint/" + "/" + "Sample_" + i + ".png");
refid = downloadManager.enqueue(request);
Log.e("OUTNM", "" + refid);
list.add(refid);
}
}
});
*/
}
public boolean isStoragePermissionGranted() {
if (Build.VERSION.SDK_INT >= 23) {
if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
== PackageManager.PERMISSION_GRANTED) {
return true;
} else {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
return false;
}
}
else { //permission is automatically granted on sdk<23 upon installation
return true;
}
}
BroadcastReceiver onComplete = new BroadcastReceiver() {
public void onReceive(Context ctxt, Intent intent) {
long referenceId = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
Log.e("IN", "" + referenceId);
list.remove(referenceId);
if (list.isEmpty())
{
Log.e("INSIDE", "" + referenceId);
NotificationCompat.Builder mBuilder =
new NotificationCompat.Builder(MainActivity.this)
.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle("FileDownloader")
.setContentText("All Download completed");
NotificationManager notificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(455, mBuilder.build());
}
}
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(onComplete);
}
#Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(grantResults[0]== PackageManager.PERMISSION_GRANTED){
// permission granted
}
}
private void getImageUrl() {
Call<ImageModel> call = apiService.getImageDetails("js","0","1","en-US");
call.enqueue(new Callback<ImageModel>() {
#Override
public void onResponse(Response<ImageModel> response, Retrofit retrofit) {
try {
Toast.makeText(MainActivity.this, "inside onresponse()", Toast.LENGTH_SHORT).show();
url=response.body().getImages().get(0).getUrl().toString();
//Here variable "url" is showing the data obtained through json
// but not reflecting changes back in "oncreate" method when used with variable "Download_uri"
Toast.makeText(MainActivity.this, url, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Toast.makeText(MainActivity.this, "Cannot download the image", Toast.LENGTH_SHORT).show();
}
});
}
#Subscribe(sticky = true,threadMode = ThreadMode.MAIN)
public void onMessage(String url){
Toast.makeText(MainActivity.this, "inside Eventbus : "+url+" ", Toast.LENGTH_SHORT).show();
}
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
EventBus.getDefault().unregister(this);
super.onStop();
}
}
ApiInterface.class
package com.gadgetsaint.downloadmanagerexample;
import retrofit.Call;
import retrofit.http.GET;
import retrofit.http.Query;
public interface ApiInterface {
#GET("HPImageArchive.aspx")
Call<ImageModel> getImageDetails(#Query("format") String format,
#Query("idx") String idx, #Query("n") String n, #Query("mkt") String
mkt);
}
ApiClient.class
package com.gadgetsaint.downloadmanagerexample;
import retrofit.GsonConverterFactory;
import retrofit.Retrofit;
public class ApiClient {
public static final String BASE_URL = "http://www.bing.com/";
private static Retrofit retrofit = null;
public static Retrofit getClient() {
if (retrofit==null) {
retrofit = new Retrofit.Builder()
.baseUrl(BASE_URL)
.addConverterFactory(GsonConverterFactory.create())
.build();
}
return retrofit;
}
}
ImageModel.class
package com.gadgetsaint.downloadmanagerexample;
import java.util.List;
public class ImageModel {
/**
* images : [{"startdate":"20170920","fullstartdate":"201709200700","enddate":"20170921","url":"/az/hprichbg/rb/RotenbergVineyards_EN-US11270850012_1920x1080.jpg","urlbase":"/az/hprichbg/rb/RotenbergVineyards_EN-US11270850012","copyright":"Vineyards at Rotenberg in Baden-Württemberg, Germany (© Werner Dieterich/plainpicture)","copyrightlink":"http://www.bing.com/search?q=rotenberg+stuttgart&form=hpcapt&filters=HpDate:%2220170920_0700%22","quiz":"/search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20170920_RotenbergVineyards%22&FORM=HPQUIZ","wp":true,"hsh":"0b5b6af9429a1f1e53c494ee482c73bc","drk":1,"top":1,"bot":1,"hs":[]}]
* tooltips : {"loading":"Loading...","previous":"Previous image","next":"Next image","walle":"This image is not available to download as wallpaper.","walls":"Download this image. Use of this image is restricted to wallpaper only."}
*/
private TooltipsBean tooltips;
private List<ImagesBean> images;
public TooltipsBean getTooltips() {
return tooltips;
}
public void setTooltips(TooltipsBean tooltips) {
this.tooltips = tooltips;
}
public List<ImagesBean> getImages() {
return images;
}
public void setImages(List<ImagesBean> images) {
this.images = images;
}
public static class TooltipsBean {
/**
* loading : Loading...
* previous : Previous image
* next : Next image
* walle : This image is not available to download as wallpaper.
* walls : Download this image. Use of this image is restricted to wallpaper only.
*/
private String loading;
private String previous;
private String next;
private String walle;
private String walls;
public String getLoading() {
return loading;
}
public void setLoading(String loading) {
this.loading = loading;
}
public String getPrevious() {
return previous;
}
public void setPrevious(String previous) {
this.previous = previous;
}
public String getNext() {
return next;
}
public void setNext(String next) {
this.next = next;
}
public String getWalle() {
return walle;
}
public void setWalle(String walle) {
this.walle = walle;
}
public String getWalls() {
return walls;
}
public void setWalls(String walls) {
this.walls = walls;
}
}
public static class ImagesBean {
/**
* startdate : 20170920
* fullstartdate : 201709200700
* enddate : 20170921
* url : /az/hprichbg/rb/RotenbergVineyards_EN-US11270850012_1920x1080.jpg
* urlbase : /az/hprichbg/rb/RotenbergVineyards_EN-US11270850012
* copyright : Vineyards at Rotenberg in Baden-Württemberg, Germany (© Werner Dieterich/plainpicture)
* copyrightlink : http://www.bing.com/search?q=rotenberg+stuttgart&form=hpcapt&filters=HpDate:%2220170920_0700%22
* quiz : /search?q=Bing+homepage+quiz&filters=WQOskey:%22HPQuiz_20170920_RotenbergVineyards%22&FORM=HPQUIZ
* wp : true
* hsh : 0b5b6af9429a1f1e53c494ee482c73bc
* drk : 1
* top : 1
* bot : 1
* hs : []
*/
private String startdate;
private String fullstartdate;
private String enddate;
private String url;
private String urlbase;
private String copyright;
private String copyrightlink;
private String quiz;
private boolean wp;
private String hsh;
private int drk;
private int top;
private int bot;
private List<?> hs;
public String getStartdate() {
return startdate;
}
public void setStartdate(String startdate) {
this.startdate = startdate;
}
public String getFullstartdate() {
return fullstartdate;
}
public void setFullstartdate(String fullstartdate) {
this.fullstartdate = fullstartdate;
}
public String getEnddate() {
return enddate;
}
public void setEnddate(String enddate) {
this.enddate = enddate;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public String getUrlbase() {
return urlbase;
}
public void setUrlbase(String urlbase) {
this.urlbase = urlbase;
}
public String getCopyright() {
return copyright;
}
public void setCopyright(String copyright) {
this.copyright = copyright;
}
public String getCopyrightlink() {
return copyrightlink;
}
public void setCopyrightlink(String copyrightlink) {
this.copyrightlink = copyrightlink;
}
public String getQuiz() {
return quiz;
}
public void setQuiz(String quiz) {
this.quiz = quiz;
}
public boolean isWp() {
return wp;
}
public void setWp(boolean wp) {
this.wp = wp;
}
public String getHsh() {
return hsh;
}
public void setHsh(String hsh) {
this.hsh = hsh;
}
public int getDrk() {
return drk;
}
public void setDrk(int drk) {
this.drk = drk;
}
public int getTop() {
return top;
}
public void setTop(int top) {
this.top = top;
}
public int getBot() {
return bot;
}
public void setBot(int bot) {
this.bot = bot;
}
public List<?> getHs() {
return hs;
}
public void setHs(List<?> hs) {
this.hs = hs;
}
}
}
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="#+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="#dimen/activity_vertical_margin"
android:paddingLeft="#dimen/activity_horizontal_margin"
android:paddingRight="#dimen/activity_horizontal_margin"
android:paddingTop="#dimen/activity_vertical_margin"
tools:context="com.gadgetsaint.downloadmanagerexample.MainActivity">
<TextView
android:id="#+id/single"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="#fff"
android:padding="20dp"
android:background="#ce3910"
android:layout_centerInParent="true"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Download single file" />
</RelativeLayout>
There is some trouble with the getImageUrl() method in MainActivity.class.
Help me out guys!!
Replace your getImageUrl() like this
private String getImageUrl() {
String imurl;
Call<ImageModel> call = apiService.getImageDetails("js","0","1","en-US");
call.enqueue(new Callback<ImageModel>() {
#Override
public void onResponse(Response<ImageModel> response, Retrofit retrofit) {
try {
Toast.makeText(MainActivity.this, "inside onresponse()", Toast.LENGTH_SHORT).show();
imurl=response.body().getImages().get(0).getUrl().toString();
//Here variable "url" is showing the data obtained through json
// but not reflecting changes back in "oncreate" method when used with variable "Download_uri"
Toast.makeText(MainActivity.this, url, Toast.LENGTH_SHORT).show();
} catch (Exception e) {
e.printStackTrace();
}
}
#Override
public void onFailure(Throwable t) {
Toast.makeText(MainActivity.this, "Cannot download the image", Toast.LENGTH_SHORT).show();
}
});
return imurl;
}
and in oncreate change,
Download_Uri = Uri.parse(url);
by this
Download_Uri = Uri.parse(getImageUrl());

Save custom object in shared preferences

I want to save a custom object myObject in shared preferences. Where this custom object has ArrayList<anotherCustomObj>. This anotherCustomObj has primary variables.
Both myObject and anotherCustomObj are parcelable.
I tried below code to convert it to String and save it :
String myStr = gson.toJson(myObject);
editor.putString(MY_OBJ, myStr);
But it gives RunTimeException.
EDIT : Below is logcat screen shot.
anotherCustomObj implementation :
package com.objectlounge.ridesharebuddy.classes;
import java.io.File;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Parcel;
import android.os.Parcelable;
import android.preference.PreferenceManager;
import android.util.Log;
import com.google.gson.annotations.SerializedName;
import com.objectlounge.ridesharebuddy.R;
public class RS_SingleMatch implements Parcelable {
private static final String RIDESHARE_DIRECTORY = "RideShareBuddy";
private static final String TAG = "RS_SingleMatch";
private static final String IMAGE_PATH = "imagePath";
private static final String IMAGE_NAME_PREFIX = "RideShareBuddyUserImage";
private Context context;
#SerializedName("id")
private int userId;
private int tripId;
private String imageUrl;
#SerializedName("userName")
private String email;
private String realName;
private String gender;
private int reputation;
private String createdAt;
private String birthdate;
private float fromLat, fromLon, toLat, toLon;
private String fromPOI, toPOI;
private String departureTime;
private int matchStrength;
// Constructor
public RS_SingleMatch(Context context) {
this.context = context;
}
// Constructor to use when reconstructing an object from a parcel
public RS_SingleMatch(Parcel in) {
readFromParcel(in);
}
#Override
public int describeContents() {
return 0;
}
#Override
// Called to write all variables to a parcel
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(userId);
dest.writeInt(tripId);
dest.writeString(imageUrl);
dest.writeString(email);
dest.writeString(realName);
dest.writeString(gender);
dest.writeInt(reputation);
dest.writeString(createdAt);
dest.writeString(birthdate);
dest.writeFloat(fromLat);
dest.writeFloat(fromLon);
dest.writeFloat(toLat);
dest.writeFloat(toLon);
dest.writeString(fromPOI);
dest.writeString(toPOI);
dest.writeString(departureTime);
dest.writeInt(matchStrength);
}
// Called from constructor to read object properties from parcel
private void readFromParcel(Parcel in) {
// Read all variables from parcel to created object
userId = in.readInt();
tripId = in.readInt();
imageUrl = in.readString();
email = in.readString();
realName = in.readString();
gender = in.readString();
reputation = in.readInt();
createdAt = in.readString();
birthdate = in.readString();
fromLat = in.readFloat();
fromLon = in.readFloat();
toLat = in.readFloat();
toLon = in.readFloat();
fromPOI = in.readString();
toPOI = in.readString();
departureTime = in.readString();
matchStrength = in.readInt();
}
// This creator is used to create new object or array of objects
public static final Parcelable.Creator<RS_SingleMatch> CREATOR = new Parcelable.Creator<RS_SingleMatch>() {
#Override
public RS_SingleMatch createFromParcel(Parcel in) {
return new RS_SingleMatch(in);
}
#Override
public RS_SingleMatch[] newArray(int size) {
return new RS_SingleMatch[size];
}
};
// Getters
public int getUserId() {
return userId;
}
public int getTripId() {
return tripId;
}
public String getImageUrl() {
return imageUrl;
}
public Bitmap getImage() {
Bitmap image = null;
// If imageUrl is not empty
if (getImageUrl().length() > 0) {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this.context);
String imagePath = prefs.getString(IMAGE_PATH + getUserId(), "");
// Get image from cache
if ((image = RS_FileOperationsHelper.getImageAtPath(imagePath)) == null) {
Log.d(TAG, "Image not found on disk.");
Thread t = new Thread(new Runnable() {
#Override
public void run() {
// If image not found on storage then download it
setImage(downloadImage(getImageUrl()));
}
});
t.start();
}
} else {
// Use default image
image = getDefaultProfileImage();
}
image = RS_ImageViewHelper.getRoundededImage(image, image.getWidth());
Log.d(TAG, "Image width : " + image.getWidth());
return image;
}
public String getEmail() {
return email;
}
public String getRealName() {
return realName;
}
public String getGender() {
return gender;
}
public int getReputation() {
return reputation;
}
public String getCreatedAt() {
return createdAt;
}
public String getBirthdate() {
return birthdate;
}
public float getFromLat() {
return fromLat;
}
public float getFromLon() {
return fromLon;
}
public float getToLat() {
return toLat;
}
public float getToLon() {
return toLon;
}
public String getFromPOI() {
return fromPOI;
}
public String getToPOI() {
return toPOI;
}
public String getDepartureTime() {
return departureTime;
}
public int getMatchStrength() {
return matchStrength;
}
// Setters
public void setContext(Context context) {
this.context = context;
}
public void setUserId(int userId) {
this.userId = userId;
}
public void setTripId(int tripId) {
this.tripId = tripId;
}
public void setImageUrl(String imageUrl) {
this.imageUrl = imageUrl;
}
public void setImage(Bitmap img) {
if (img != null) {
// Get cache directory's path and append RIDESHARE_DIRECTORY.
String cacheDirStoragePath = context.getCacheDir()
+ "/"
+ RIDESHARE_DIRECTORY;
// Create directory at cacheDirStoragePath if does not exist.
if (RS_FileOperationsHelper
.createDirectoryAtPath(cacheDirStoragePath)) {
String imagePath = cacheDirStoragePath + "/"
+ IMAGE_NAME_PREFIX + this.userId + ".png";
// Save new image to cache
RS_FileOperationsHelper.saveImageAtPath(img, imagePath, this.context);
SharedPreferences pref = PreferenceManager
.getDefaultSharedPreferences(context);
Editor e = pref.edit();
e.putString(IMAGE_PATH + getUserId(), imagePath);
e.commit();
}
}
}
public void setEmail(String email) {
this.email = email;
}
public void setRealName(String realName) {
this.realName = realName;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setReputation(int reputation) {
this.reputation = reputation;
}
public void setCreatedAt(String createdAt) {
this.createdAt = createdAt;
}
public void setBirthdate(String birthdate) {
this.birthdate = birthdate;
}
public void setFromLat(float fromLat) {
this.fromLat = fromLat;
}
public void setFromLon(float fromLon) {
this.fromLon = fromLon;
}
public void setToLat(float toLat) {
this.toLat = toLat;
}
public void setToLon(float toLon) {
this.toLon = toLon;
}
public void setFromPOI(String fromPOI) {
this.fromPOI = fromPOI;
}
public void setToPOI(String toPOI) {
this.toPOI = toPOI;
}
public void setDepartureTime(String departureTime) {
this.departureTime = departureTime;
}
public void setMatchStrength(int matchStrength) {
this.matchStrength = matchStrength;
}
// calculates age using given date
#SuppressLint("SimpleDateFormat")
public int calculateAge(String date) {
int age = 0;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
Date bdate = formatter.parse(date);
Calendar lCal = Calendar.getInstance();
lCal.setTime(bdate);
int lYear = lCal.get(Calendar.YEAR);
int lMonth = lCal.get(Calendar.MONTH) + 1;
int lDay = lCal.get(Calendar.DATE);
Calendar dob = Calendar.getInstance();
Calendar today = Calendar.getInstance();
dob.set(lYear, lMonth, lDay);
age = today.get(Calendar.YEAR) - dob.get(Calendar.YEAR);
if (today.get(Calendar.DAY_OF_YEAR) < dob.get(Calendar.DAY_OF_YEAR)) {
age--;
}
} catch (ParseException e) {
e.printStackTrace();
}
return age;
}
// Download image if not available
protected void downloadAndSaveImage() {
SharedPreferences prefs = PreferenceManager
.getDefaultSharedPreferences(this.context);
String imagePath = prefs.getString(IMAGE_PATH + getUserId(), "");
File file = new File(imagePath);
// If image path not stored in user defaults or image does not exists
// then
if ((imagePath == null || !file.exists()) && this.imageUrl.length() > 0) {
// Download on separate thread
Thread t = new Thread(new Runnable() {
#Override
public void run() {
setImage(downloadImage(getImageUrl()));
}
});
t.start();
}
}
// Download an image
private Bitmap downloadImage(String imageUrl) {
Log.d(TAG, "Image url : " + imageUrl);
Bitmap image = null;
try {
// Download an image from url
InputStream in = new java.net.URL(imageUrl.trim()).openStream();
image = BitmapFactory.decodeStream(in);
} catch (Exception e) {
e.printStackTrace();
}
Log.d(TAG, "Image downloading complete. image : " + image);
return image;
}
// Get default image
protected Bitmap getDefaultProfileImage() {
Bitmap image = BitmapFactory.decodeResource(
this.context.getResources(), R.drawable.default_male);
if (this.gender.toUpperCase(Locale.US).startsWith("F")) {
image = BitmapFactory.decodeResource(this.context.getResources(),
R.drawable.default_female);
}
return image;
}
}
Link posted by damian was helpful to solve my problem. However, in my case there was no view component in custom object.
According to my observation if you find multiple JSON fields for ANY_VARIABLE_NAME, then it is likely that it is because GSON is not able to convert the object. And you can try below code to solve it.
Add below class to to tell GSON to save and/or retrieve only those variables who have Serialized name declared.
class Exclude implements ExclusionStrategy {
#Override
public boolean shouldSkipClass(Class<?> arg0) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean shouldSkipField(FieldAttributes field) {
SerializedName ns = field.getAnnotation(SerializedName.class);
if(ns != null)
return false;
return true;
}
}
Below is the class whose object you need to save/retrieve.
Add #SerializedName for variables that needs to saved and/or retrieved.
class myClass {
#SerializedName("id")
int id;
#SerializedName("name")
String name;
}
Code to convert myObject to jsonString :
Exclude ex = new Exclude();
Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();
String jsonString = gson.toJson(myObject);
Code to get object from jsonString :
Exclude ex = new Exclude();
Gson gson = new GsonBuilder().addDeserializationExclusionStrategy(ex).addSerializationExclusionStrategy(ex).create();
myClass myObject = gson.fromJson(jsonString, myClass.class);

Categories

Resources