Intent from AsyncTask startActivity not working (FAILED BINDER TRANSACTION) - java

I have the following AsyncTask. In the onPostExecute method I am trying to start another activity using the Intent. However, I noticed that the new activity doesn't start and the finish() line is simply called closing the current activity. I do not know what the cause of this can be.
private void uploadImage(final String city, final String offset, final int currImage, final View itemView, final Animation animation) {
class UploadImage extends AsyncTask<String, Void, String> {
private Context context;
public UploadImage(Context context){
this.context=context;
}
// ProgressDialog loading;
RequestHandler rh = new RequestHandler();
#Override
protected String doInBackground(String... params) {
HashMap<String, String> data = new HashMap<>();
data.put("city", city);
data.put("offset",offset);
String result = rh.sendPostRequest(SL_URL, data);
return result;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
//loading = ProgressDialog.show(SlideShow.this, "Uploading Image", "Please wait...", true, true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// loading.dismiss();
JSONArray jsonArray = null;
try {
jsonArray = new JSONArray(s);
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject a = jsonArray.getJSONObject(i);
imageDisplayerArrayList.add(new ImageDisplayer(a.getString("user_id"),a.getString("image"),a.getString("longitude"),a.getString("latitude"),a.getString("city"),a.getString("geo_name_id"),a.getString("description"),a.getString("score"),a.getString("Categories")));
} catch (JSONException e) {
e.printStackTrace();
}
}
itemView.clearAnimation();
itemView.setVisibility(View.INVISIBLE);
if (imageDisplayerArrayList.size() > 0) {
Intent intent = new Intent(context, SlideShow.class);
intent.putExtra("key",imageDisplayerArrayList);
intent.putExtra("city", city);
context.startActivity(intent);
((Activity) context).finish();
}
else {
Toast.makeText(getApplicationContext(), "No new content available", Toast.LENGTH_LONG)
.show(); }
}}
UploadImage ui = new UploadImage(this);
ui.execute(city);
}
PARCELABLE IMAGEDISPLAYER CLASS:
public class ImageDisplayer implements Parcelable {
private String user_id;
private String image;
private String longitude;
private ImageDisplayer(Parcel in) {
this.user_id = in.readString();
this.image = in.readString();
this.longitude = in.readString();
this.latitude = in.readString();
this.city = in.readString();
this.geo_name_id = in.readString();
this.description = in.readString();
this.score = in.readString();
this.categories = in.readString();
}
public ImageDisplayer(String user_id, String image, String longitude, String latitude, String city, String geo_name_id, String description, String score, String categories) {
this.user_id = user_id;
this.image = image;
this.longitude = longitude;
this.latitude = latitude;
this.city = city;
this.geo_name_id = geo_name_id;
this.description = description;
this.score = score;
this.categories = categories;
}
public String getUser_id() {
return user_id;
}
public void setUser_id(String user_id) {
this.user_id = user_id;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public String getLongitude() {
return longitude;
}
public void setLongitude(String longitude) {
this.longitude = longitude;
}
public String getLatitude() {
return latitude;
}
public void setLatitude(String latitude) {
this.latitude = latitude;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getGeo_name_id() {
return geo_name_id;
}
public void setGeo_name_id(String geo_name_id) {
this.geo_name_id = geo_name_id;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getScore() {
return score;
}
public void setScore(String score) {
this.score = score;
}
public String getCategories() {
return categories;
}
public void setCategories(String categories) {
this.categories = categories;
}
private String latitude;
private String city;
private String geo_name_id;
private String description;
private String score;
private String categories;
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeString(user_id);
dest.writeString(image);
dest.writeString(longitude);
dest.writeString(latitude);
dest.writeString(city);
dest.writeString(geo_name_id);
dest.writeString(description);
dest.writeString(score);
dest.writeString(categories);
}
public static final Parcelable.Creator<ImageDisplayer> CREATOR
= new Parcelable.Creator<ImageDisplayer>() {
// This simply calls our new constructor (typically private) and
// passes along the unmarshalled `Parcel`, and then returns the new object!
#Override
public ImageDisplayer createFromParcel(Parcel in) {
return new ImageDisplayer(in);
}
// We just need to copy this and change the type to match our class.
#Override
public ImageDisplayer[] newArray(int size) {
return new ImageDisplayer[size];
}
};
}
SLIDESHOW
public class SlideShow extends Activity {
private ArrayList<ImageDisplayer> imageDisplayerArrayList = new ArrayList<>();
private String city;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_slide_show);
imageDisplayerArrayList = getIntent().getParcelableExtra("key");
TextView time_rem = (TextView) findViewById(R.id.time_rem);
time_rem.bringToFront();
city = getIntent().getStringExtra("city");
slideshow(imageDisplayerArrayList, 0, 0);
}
private void uploadImage2(final String city, final String offset, final int currImage) {
class UploadImage extends AsyncTask<String, Void, String> {
//ProgressDialog loading;
RequestHandler rh = new RequestHandler();
#Override
protected String doInBackground(String... params) {
HashMap<String, String> data = new HashMap<>();
data.put("city", city);
data.put("offset",offset);
String result = rh.sendPostRequest(SL_URL, data);
return result;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
// loading = ProgressDialog.show(SlideShow.this, "Uploading Image", "Please wait...", true, true);
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
// loading.dismiss();
JSONArray jsonArray = null;
try {
jsonArray = new JSONArray(s);
} catch (JSONException e) {
e.printStackTrace();
}
for (int i = 0; i < jsonArray.length(); i++) {
try {
JSONObject a = jsonArray.getJSONObject(i);
imageDisplayerArrayList.add(new ImageDisplayer(a.getString("user_id"),a.getString("image"),a.getString("longitude"),a.getString("latitude"),a.getString("city"),a.getString("geo_name_id"),a.getString("description"),a.getString("score"),a.getString("Categories")));
} catch (JSONException e) {
e.printStackTrace();
}
}
}}
UploadImage ui = new UploadImage();
ui.execute(city);
}
public Bitmap ConvertToImage(String image){
byte[] decodedByte = Base64.decode(image, 0);
return BitmapFactory.decodeByteArray(decodedByte, 0, decodedByte.length);
}
public void slideshow(ArrayList<ImageDisplayer> a, final int currImage, final int offset) {
ImageView imageView = (ImageView) findViewById(R.id.picturedisplay);
int currphoto = 0;
final long DELAY = 300; // milliseconds
final long VIEW_TIME = 10000;
Timer timer = new Timer();
final TimerTask update_time = new TimerTask() {
#Override
public void run() {
SlideShow.this.runOnUiThread(new Runnable() {
#Override
public void run() {
TextView time_rem = (TextView) findViewById(R.id.time_rem);
int timeRem = Integer.parseInt(time_rem.getText().toString());
timeRem--;
time_rem.setText(Integer.toString(timeRem));
}});
}};
timer.scheduleAtFixedRate(
new TimerTask() {
int i = currImage;
int off = 0;
#Override
public void run() {
SlideShow.this.runOnUiThread(new Runnable() {
#Override
public void run() {
if (i < imageDisplayerArrayList.size()) {
TextView time_rem = (TextView) findViewById(R.id.time_rem);
time_rem.setText("10");
Bitmap myBitmap = ConvertToImage(imageDisplayerArrayList.get(i).getImage());
ImageView imageView = (ImageView) findViewById(R.id.picturedisplay);
imageView.setImageBitmap(myBitmap);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
Toast.makeText(getApplicationContext(),
Integer.toString(imageDisplayerArrayList.size()), Toast.LENGTH_LONG)
.show();
i++;
off = (int)(Math.rint(Math.ceil((double) i / 10) * 10));
if (i % 5 == 0 && i % 10 != 0) {
uploadImage2(city,Integer.toString(off),i);
}
}
else {
update_time.cancel();
Intent i = new Intent(SlideShow.this,ViewScreen.class);
startActivity(i);
finish();
}
}});
}
},
DELAY,VIEW_TIME
);
timer.scheduleAtFixedRate(update_time, 0, 1000);
}
}
UPDATE
This is caused by the following error FAILED BINDER TRANSACTION !!! as my image arraylist exceeds the 1MB limit. Can someone please help me create an alternative solution to passing this arraylist between the two activities?

Firstly, you have to fetch the ParcelableArrayList
imagesArrayList = getIntent().getParcelableArrayListExtra("key");
Secondly, You are doing too much I/O work in slide show function which is causing delay
Thirdly You are doing bitmaps work and displaying bitmaps on Ui Thread, you have to move your bitmaps work off the ui thread, its worth using Universal Image Loader https://github.com/nostra13/Android-Universal-Image-Loader
Hope this helps.

Checkout this code. and when you call asynctask pass activity context thats it.
Intent intent = new Intent(((Activity) context), SlideShow.class);
intent.putParcelableArrayListExtra("key",imageDisplayerArrayList);
intent.putExtra("city", city);
((Activity) context).startActivity(intent);
((Activity) context).finish();
Now you retrieve your array list in another activity like this
imageDisplayerArrayList = getIntent().getParcelableArrayListExtra("key");
If you are passing bitmap in list don't do that just pass url in it.

Create a pair of ParcelFileDescriptors using createSocketPair and pass one of the objects to the activity by putting the object into the intent. Then you can pass data by creating File[Input|Output]Stream object from the underlying FileDescriptor for the parcel file descriptor. (usegetFileDescriptor() to obtain FileDescriptor)

Related

not able to show data in Recycler View

I am getting some data from server in json format. I have a model class where I got all data from server and I put all data in a Array List. Now I am not able to get data in recyclerView.
MainActivity
public CopyOnWriteArrayList<PrisonerModel> inside1
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
recyclerViewInside = findViewById(R.id.rv);
signature_calculation_prisonerList();
new PrisonerListAsyncTask().execute(NetworkUtils.PRISONER_LIST, ctimestamp,
cnonce, cappkey, csign);
inside1 = new CopyOnWriteArrayList<>();
MyAdapter myAdapter = new MyAdapter(inside1, this, this);
recyclerViewInside.setAdapter(myAdapter);
}
Model.java file
public class PrisonerModel {
private String name;
private int image;
private int total_prisoner;
private int outside;
private int inside;
private String imageUri;
private String device;
public PrisonerModel() {
}
public PrisonerModel(String name, int image) {
this.name = name;
this.image = image;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getImage() {
return image;
}
public void setImage(int image) {
this.image = image;
}
public int getTotal_prisoner() {
return total_prisoner;
}
public int getOutside() {
return outside;
}
public int getInside() {
return inside;
}
public String getImageUri() {
return imageUri;
}
public String getDevice() {
return device;
}
public static PrisonerModel fromJson(JSONObject jsonObject)
{
PrisonerModel pm1 = new PrisonerModel();
MainActivity ma = new MainActivity();
try {
pm1.total_prisoner = jsonObject.getInt("total");
Log.e("total: ", String.valueOf(pm1.getTotal_prisoner()));
JSONArray jsonArray = jsonObject.getJSONArray("list");
ma.inside1 = pm1.fromJson(jsonArray);
Log.e("inside: ", String.valueOf(ma.inside1.get(0).getName()));
pm1.inside = pm1.x;
pm1.outside = pm1.getTotal_prisoner() - pm1.x;
} catch (JSONException e) {
e.printStackTrace();
return null;
}
return pm1;
}
I am getting data of inside1 in this model class but when I use Log.e("") in Main Activity it throw error "ArrayOutOfBoundIndex"
could you help me where am i doing mistake?

Updating cluster markers pictures

I am creating a social media app that helps people find their friends. One feature that I want to include is users being able to choose their profile picture. However I am having issues updating cluster marker pictures. Basically I am using volly to connect to a db to get the most recent user data. This method is called when I click a button. I did something similar to change the users profile picture with success. I am not sure why this is not working if anyone can give pointers that would be great.
private void updateMapMarkers(){
//mMap.clear(); not sure if i need to do this or not
//mClusterManager.clearItems(); also tried this
mClusterManager.removeItems(mClusterMarkers);
RequestQueue queue = Volley.newRequestQueue(MainActivity.this);
String url = "http://some ip address/update_everyones_cords.php?THIS_USER_ID=" + MainActivity.THIS_USER_ID;
JsonArrayRequest jsObjRequest = new JsonArrayRequest(Request.Method.GET, url,null,
new Response.Listener<JSONArray>() {
public void onResponse(JSONArray response){
try {
ArrayList<ClusterMarker> mClusterMarkersUpdated = new ArrayList<>();
for (int i = 0; i < response.length(); i++) {
JSONObject rec = response.getJSONObject(i);
String userName = rec.getString("userName");
String profilePicture = rec.getString("profilePicture");
int userID = rec.getInt("ID");
int avatar;
if (profilePicture.equals("default")){
avatar = R.drawable.androidlogo;
} else {
avatar = Integer.parseInt(THIS_USER_PIC);
}
if (userID == THIS_USER_ID){
ClusterMarker thisUser = new ClusterMarker(
new LatLng(THIS_CORDSV1, THIS_CORDSV2),
THIS_USER_NAME,
"This is you",
avatar,
THIS_USER_ID);
mClusterManager.addItem(thisUser);
mClusterMarkersUpdated.add(thisUser);
Log.wtf(TAG,userName);
} else {
Log.wtf(TAG,userName);
ClusterMarker thisUser = new ClusterMarker(
new LatLng(THIS_CORDSV1, THIS_CORDSV2),
userName,
"determine route to",
avatar,
userID);
mClusterManager.addItem(thisUser);
mClusterMarkersUpdated.add(thisUser);
}
}
mClusterMarkers = mClusterMarkersUpdated;
} catch (JSONException e) {
Toast.makeText(MainActivity.this, "jason obj ex:" + e.toString(), Toast.LENGTH_SHORT).show();
}
}
}, new Response.ErrorListener() {
public void onErrorResponse(VolleyError er){
Toast.makeText(MainActivity.this, "volley error:" + er.toString(), Toast.LENGTH_LONG).show();
}
}
); queue.add(jsObjRequest);
mClusterManager.cluster();
}
I also tried something like this, also didn't work. When I say it doesn't work I do not get any errors just a blank map with no markers at least for the above method. For the below attempt nothing at all happens.
int defaultImage = R.drawable.androidlogo;
mImageUrlsLarger.add(defaultImage + "");
mClusterMarkers.get(i).setIconPicture(defaultImage);
mClusterManager.cluster();
public class CustomClusterItem implements ClusterItem {
private final LatLng position;
private String title;
private String snippet;
private String tag;
private String imageUrl;
public CustomClusterItem(double lat, double lng) {
this.position = new LatLng(lat, lng);
}
//getters and setters
}
CustomClusterRenderer.Java
public class CustomClusterRenderer extends DefaultClusterRenderer<CustomClusterItem> implements GoogleMap.OnCameraIdleListener {
private CameraIdleListener listener;
//used to keep strong reference to 'Target' object, otherwise objects get garbage collected and picasso will fail to load image
private List<Target> targetList = new ArrayList<>();
private IconGenerator greenIconGenerator;
private ImageView greenImageView;
private Context context;
public CustomClusterRenderer(Context context, GoogleMap map, ClusterManager<CustomClusterItem> clusterManager) {
super(context, map, clusterManager);
this.context = context;
prepareImageViews(context);
prepareIconGenerator(context);
}
public void setCameraIdleListener(CameraIdleListener cameraIdleListener) {
this.listener = cameraIdleListener;
}
public void clearTargetList() {
targetList.clear();
}
private void prepareIconGenerator(Context context) {
greenIconGenerator = new IconGenerator(context);
greenIconGenerator.setColor(ContextCompat.getColor(context, R.color.priority_green));
greenIconGenerator.setContentView(greenImageView);
}
private void prepareImageViews(Context context) {
final int mDimension = (int) context.getResources().getDimension(R.dimen._30sdp);
final int padding = (int) context.getResources().getDimension(R.dimen._8sdp);
greenImageView = new ImageView(context);
greenImageView.setLayoutParams(new ViewGroup.LayoutParams(mDimension, mDimension));
greenImageView.setPadding(padding, padding, padding, padding);
}
#Override
protected void onBeforeClusterItemRendered(final CaseClusterItem item,
final MarkerOptions markerOptions) {
Bitmap largeIcon = BitmapFactory.decodeResource(context.getResources(), R.drawable.ic_action_settings);
getImageView(item.getPriority()).setImageBitmap(largeIcon);
Bitmap icon = greenIconGenerator.makeIcon();
markerOptions.icon(BitmapDescriptorFactory.fromBitmap(icon));
}
#Override
protected void onClusterItemRendered(final CustomClusterItem clusterItem,
final Marker marker) {
super.onClusterItemRendered(clusterItem, marker);
Target target = new Target() {
#Override
public void onBitmapLoaded(Bitmap bitmap, Picasso.LoadedFrom from) {
//TODO - find the root cause for IllegalArgumentException
try {
greenImageView.setImageBitmap(bitmap);
Bitmap icon = greenIconGenerator.makeIcon();
marker.setIcon(BitmapDescriptorFactory.fromBitmap(icon));
} catch (IllegalArgumentException e) {
LogHelper.printErrorLog("Not sure about the cause of issue, need to rectify");
}
}
#Override
public void onBitmapFailed(Drawable errorDrawable) {
}
#Override
public void onPrepareLoad(Drawable placeHolderDrawable) {
}
};
if (!TextUtils.isEmpty(clusterItem.getImageUrl())) {
getPicasso().load(clusterItem.getImageUrl()).resize(60, 60).into(target);
targetList.add(target);
}
}
#Override
public void onCameraIdle() {
if (listener != null) {
listener.onCameraIdle();
}
}
public interface CameraIdleListener {
void onCameraIdle();
}
}
HomeFragment.Java
public class HomeFragment extends BaseFragment implements OnMapReadyCallback, GoogleMap.OnCameraIdleListener, GoogleMap.OnMarkerClickListener, ClusterManager.OnClusterItemClickListener<CustomClusterItem>, ClusterManager.OnClusterClickListener<CustomClusterItem>, CustomClusterRenderer.CameraIdleListener{
private ClusterManager<CustomClusterItem> clusterManager;
private CustomClusterRenderer clusterRenderer;
private void generateMarkerFromCase(List<CustomListResponse.DataBean.CaseBean> caseList) {
clusterRenderer.clearTargetList();
if (caseList == null) {
ToastHelper.show("No cases found.");
return;
}
for (final CustomListResponse.DataBean.CustomBean caseBean : caseList) {
try {
final double lat = Double.parseDouble(caseBean.getLat());
final double lng = Double.parseDouble(caseBean.getLongX());
String markerUrl;
markerUrl = caseBean.getParent_category().getImage();
if (markerUrl == null) {
markerUrl = caseBean.getCategory().getImage();
}
CustomClusterItem clusterItem = new CustomClusterItem(lat, lng);
clusterItem.setTag(caseBean.getId());
clusterItem.setImageUrl(markerUrl);
clusterItem.setPriority(caseBean.getPriority());
clusterManager.addItem(clusterItem);
} catch (NumberFormatException e) {
LogHelper.printErrorLog("Lat or Lng is null, bcz app is still in development mode : " + caseBean.getTitle() + " , Des - " + caseBean.getDescription());
}
}
clusterManager.cluster();
zoomOutMap();
}
#Override
public void onMapReady(GoogleMap map) {
this.googleMap = map;
clusterManager = new ClusterManager<>(getContext(), googleMap);
clusterManagerAlgorithm = new NonHierarchicalDistanceBasedAlgorithm();
clusterManager.setAlgorithm(clusterManagerAlgorithm);
clusterRenderer = new CustomClusterRenderer(getContext(), googleMap, clusterManager);
clusterRenderer.setCameraIdleListener(this);
clusterManager.setRenderer(clusterRenderer);
this.googleMap.setOnCameraIdleListener(clusterManager);
this.googleMap.setOnMarkerClickListener(clusterManager);
clusterManager.setOnClusterItemClickListener(this);
clusterManager.setOnClusterClickListener(this);
}
}

Add custom markers to google maps from geopints stored on firebase

Excuse my ignorance but I am very new to Android Studio and Java. I have adapted a lot the following code from another course to my needs, but it is not working.
I am trying to add custom markers to my Google maps Android app. Lhe locations of the markers are stored as geopoints on firebase. I have attempted to do so using cluster marker. The app crashes immediately when I attempt to run it with the following shortened error.
java.lang.NullPointerException: Attempt to invoke virtual method 'com.google.firebase.firestore.CollectionReference com.google.firebase.firestore.FirebaseFirestore.collection(java.lang.String)' on a null object reference
at com.codingwithmitch.googlemaps2018.ui.MapsActivity.addMapMarkers(MapsActivity.java:400)
at com.codingwithmitch.googlemaps2018.ui.MapsActivity.onMapReady(MapsActivity.java:486)
I am attempting to display every geopoint in the Stop Locations Collection
I cannot screen shot my firebase but it looks as follows:
Collection
"Stop Locations">>>>>Documents
"KzDQ2sITZ3O8GEoZgp0I",...etc >>>>>Fields
Geo:""
Name:""
avatar:""
loc_id""
If I were to guess I would say the mLocationInformations is empty, probably originating from here >> mLocationInformations.add(document.toObject(LocationInformation.class))
code from MapsActivity:
private ClusterManager<ClusterMarker> mClusterManager;
private MyClusterManagerRenderer mClusterManagerRenderer;
private ArrayList<ClusterMarker> mClusterMarkers = new ArrayList<>();
private LocationInformation mLocationInformation;
private ArrayList<LocationInformation> mLocationInformations = new ArrayList<>();
private void addMapMarkers(){
CollectionReference locationsRef = mDb
.collection("Stop Locations");
locationsRef.get().addOnCompleteListener(new OnCompleteListener<QuerySnapshot>() {
#Override
public void onComplete(#NonNull Task<QuerySnapshot> task) {
if(task.isSuccessful()){
for (QueryDocumentSnapshot document : task.getResult()) {
mLocationInformations.add(document.toObject(LocationInformation.class));
}
} else {
Log.d(TAG, "Error getting documents: ", task.getException());
}
}
});
if(mMap != null){
if(mClusterManager == null){
mClusterManager = new ClusterManager<ClusterMarker>(this.getApplicationContext(), mMap);
}
if(mClusterManagerRenderer == null){
mClusterManagerRenderer = new MyClusterManagerRenderer(
this,
mMap,
mClusterManager
);
mClusterManager.setRenderer(mClusterManagerRenderer);
}
for(LocationInformation locationInformation: mLocationInformations){
Log.d(TAG, "addMapMarkers: location: " + locationInformation.getGeo().toString());
try{
String snippet = "";
snippet = "";
int avatar = R.drawable.cartman_cop; // set the default avatar
try{
avatar = Integer.parseInt(locationInformation.getAvatar());
}catch (NumberFormatException e){
Log.d(TAG, "addMapMarkers: no avatar ");
}
ClusterMarker newClusterMarker = new ClusterMarker(
new LatLng(locationInformation.getGeo().getLatitude(), locationInformation.getGeo().getLongitude()),
//locationInformation.getName().getUsername(),
locationInformation.getLoc_id(),
snippet,
avatar,
locationInformation.getName()
);
mClusterManager.addItem(newClusterMarker);//adding to the map
mClusterMarkers.add(newClusterMarker);//making an easy access array list
}catch (NullPointerException e){
Log.e(TAG, "addMapMarkers: NullPointerException: " + e.getMessage() );
}
}
mClusterManager.cluster();
}
}
#Override
public void onMapReady(GoogleMap googleMap) {
mMap = googleMap;
if(mLocationPermissionGranted){
getDeviceLocation();
}else{
Toast.makeText(this, "mLocationpermission denied at origin", Toast.LENGTH_SHORT).show();
}
addMapMarkers();
}
}
LocationInfromation.java
import com.google.firebase.firestore.GeoPoint;
public class LocationInformation {
private String Name;
private GeoPoint Geo;
private String avatar;
private String loc_id;
public LocationInformation(String Name, GeoPoint Geo, String avatar, String loc_id) {
this.Name = Name;
this.Geo = Geo;
this.avatar = avatar;
this.loc_id = loc_id;
}
public LocationInformation(){
}
public String getLoc_id() {
return loc_id;
}
public void setLoc_id(String loc_id) {
this.loc_id = loc_id;
}
public Double getLongitude() {
return longitude;
}
public void setLongitude(Double longitude) {
this.longitude = longitude;
}
private Double longitude;
public String getName() {
return Name;
}
public void setName(String name) {
this.Name = Name;
}
public GeoPoint getGeo() {
return Geo;
}
public void setGeo(GeoPoint geo) {
this.Geo = Geo;
}
public String getAvatar() {
return avatar;
}
public void setAvatar(String avatar) {
this.avatar = avatar;
}
#Override
public String toString() {
return "LocationInformation{" +
"Name=" + Name +
", Geo=" + Geo +
", avatar='" + avatar +
", loc_id='" + loc_id +
'}';
}
}
ClusterMArker.java
import com.google.android.gms.maps.model.LatLng;
import com.google.maps.android.clustering.ClusterItem;
public class ClusterMarker implements ClusterItem {
private LatLng position; // required field
private String title; // required field
private String snippet; // required field
private int iconPicture;
private String name;
public ClusterMarker(LatLng position, String title, String snippet, int iconPicture, String name) {
this.position = position;
this.title = title;
this.snippet = snippet;
this.iconPicture = iconPicture;
this.name = name;
}
public ClusterMarker() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getIconPicture() {
return iconPicture;
}
public void setIconPicture(int iconPicture) {
this.iconPicture = iconPicture;
}
public void setPosition(LatLng position) {
this.position = position;
}
public void setTitle(String title) {
this.title = title;
}
public void setSnippet(String snippet) {
this.snippet = snippet;
}
public LatLng getPosition() {
return position;
}
public String getTitle() {
return title;
}
public String getSnippet() {
return snippet;
}
}
[enter image description here][1]
To solve this, please add the following line of code:
FirebaseFirestore mDb = FirebaseFirestore.getInstance();
Right before this line:
CollectionReference locationsRef = mDb.collection("Stop Locations");
So your FirebaseFirestore object is initialized correctly.

Data parsed from Json cant fetch properly when add another argument in constructor

This is Fist time i'm asking question!! so bear with me.
The application is project(popular movie stage 2) from udacity where i need to fetch info of movies like tilte or poster_path or backdrop_path.
so when i fetch data from json it works perfectly fine but when i add another argument String backdrop in my Movies.java class.then getmBackdrop() shows empty and i couldn't get the data of backdrop overview and vote.but if i delete backdrop from constructor than it works fine. i dont know what is happening please help me.
this is Movies.javaclass
public class Movies implements Parcelable {
//Movies Data
public long mID;
private String mPosterPath;
private String mReleaseDate;
private String mTitle;
private String mVote;
private String mOverview;
private String mBackdrop;
private ArrayList<Trailers> trailers;
private ArrayList<Reviews> reviews;
public Movies() {
}
public Movies(String title, String releaseDate, String posterPath,
String backdrop,String vote, String overview) {
// this.mID=id;
this.mTitle = title;
this.mReleaseDate = releaseDate;
this.mPosterPath = posterPath;
this.mBackdrop = backdrop;
this.mVote = vote;
this.mOverview = overview;
this.trailers = new ArrayList<>();
this.reviews = new ArrayList<>();
}
public long getID(){ return mID ;}
public String getmBackdrop() { return mBackdrop; }
public String getPosterPath() {
return mPosterPath;
}
public String getTitle() {
return mTitle;
}
public String getReleaseDate() {
return mReleaseDate;
}
public String getOverview() {
return mOverview;
}
public String getVote() {
return mVote +"/10";
}
public void setTrailers(ArrayList<Trailers> trailers) {
this.trailers = trailers;
}
public void setReviews(ArrayList<Reviews> reviews) {
this.reviews = reviews;
}
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeLong(mID);
dest.writeString(mTitle);
dest.writeString(mReleaseDate);
dest.writeString(mPosterPath);
dest.writeValue(mBackdrop);
dest.writeString(mVote);
dest.writeString(mOverview);
}
protected Movies(Parcel in) {
mID = in.readLong();
mTitle = in.readString();
mReleaseDate = in.readString();
mPosterPath = in.readString();
mBackdrop = in.readString();
mVote = in.readString();
mOverview = in.readString();
}
public static final Creator<Movies> CREATOR = new Creator<Movies>() {
public Movies createFromParcel(Parcel source) {
return new Movies(source);
}
public Movies[] newArray(int size) {
return new Movies[size];
}
};
}
MoviepediaJsonUtils.java where i'm parsing data
public class MoviepediaJsonUtils {
public static ArrayList<Movies> getParseMovieJson(String jsonMovies) throws JSONException {
final String IMAGE_BASE_URL = "https://image.tmdb.org/t/p/w500/";
final String BACKDROP_URL= "https://image.tmdb.org/t/p/w1280/";
JSONObject movieJson = new JSONObject(jsonMovies);
JSONArray movieArray = movieJson.getJSONArray("results");
ArrayList<Movies> movieArrayList = new ArrayList<>();
for (int i = 0; i < movieArray.length(); i++) {
JSONObject movieObject = movieArray.getJSONObject(i);
long id = movieObject.getLong("id");
String title = movieObject.getString("title");
String release_date = movieObject.getString("release_date");
String poster_path = movieObject.getString("poster_path");
String backdrop = movieObject.getString("backdrop_path");
String vote_average = movieObject.getString("vote_average");
String overview = movieObject.getString("overview");
Movies movies = new Movies(title, release_date,
IMAGE_BASE_URL + poster_path, BACKDROP_URL+backdrop,vote_average, overview);
movieArrayList.add(movies);
}
return movieArrayList;
}
public static String getResponseFromHttpUrl(InputStream stream) throws IOException {
Scanner scanner = new Scanner(stream);
scanner.useDelimiter("\\A");
boolean hasInput = scanner.hasNext();
if (hasInput) {
return scanner.next();
} else {
return null;
}
}
}
MainActivityFragments.java
public class MainActivityFragments extends Fragment {
private static final int COLUMN = 2;
private RecyclerView mRecyclerView;
SharedPreferences mSettings;
GridLayoutManager mGridLayoutManager;
private SharedPreferences.Editor mEditor;
private static final String SHARED_KEY_SORT = "sort";
private static final String POPULARITY = "popular";
private static final String RATINGS = "top_rated";
public static String[] backdrop;
public static final String SAVE_LAST_UPDATE_ORDER = "save_last_update_order";
private String mLastUpdateOrder;
#Nullable
#Override
public View onCreateView(LayoutInflater inflater,
#Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.poster_fragment, container, false);
if (getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT){
mGridLayoutManager = new GridLayoutManager(getActivity(),2, LinearLayoutManager.VERTICAL,false);
}else{
mGridLayoutManager = new GridLayoutManager(getActivity(), 4,LinearLayoutManager.VERTICAL,false);
}
mRecyclerView = view.findViewById(R.id.rv_movies);
mRecyclerView.setHasFixedSize(true);
mRecyclerView.setLayoutManager(mGridLayoutManager);
mSettings = PreferenceManager.getDefaultSharedPreferences(getActivity());
mEditor = mSettings.edit();
mEditor.apply();
mRecyclerView.setAdapter(new MoviesAdapter(getActivity(), new ArrayList<Movies>()));
return view;
}
#Override
public void onStart() {
super.onStart();
if (needToUpdateUi()) {
updateUi();
}
}
#Override
public void onSaveInstanceState(Bundle outState) {
super.onSaveInstanceState(outState);
outState.putString(SAVE_LAST_UPDATE_ORDER, mLastUpdateOrder);
}
#Override
public void onActivityCreated(#Nullable Bundle savedInstanceState) {
super.onActivityCreated(savedInstanceState);
if (savedInstanceState != null) {
mLastUpdateOrder = savedInstanceState.getString(SAVE_LAST_UPDATE_ORDER);
}
}
#Override
public void onCreate(#Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setHasOptionsMenu(true);
updateUi();
}
// OnCreateOptionMenues will be here
#Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
inflater.inflate(R.menu.poster_fragment, menu);
Drawable drawable = menu.findItem(R.id.icon).getIcon();
if (drawable != null) {
drawable.mutate();
drawable.setColorFilter(Color.WHITE, PorterDuff.Mode.SRC_ATOP);
}
}
// OnOptionitemSelected
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.poularity:
mEditor.putString(SHARED_KEY_SORT, POPULARITY);
mEditor.apply();
updateUi();
item.setChecked(true);
return true;
case R.id.top_rated:
mEditor.putString(SHARED_KEY_SORT, RATINGS);
mEditor.apply();
updateUi();
item.setChecked(true);
return true;
}
return super.onOptionsItemSelected(item);
}
#Override
public void onPrepareOptionsMenu(Menu menu) {
super.onPrepareOptionsMenu(menu);
String sortBy = mSettings.getString(SHARED_KEY_SORT, POPULARITY);
if (sortBy.equals(POPULARITY)) {
menu.findItem(R.id.poularity).setChecked(true);
} else {
menu.findItem(R.id.top_rated).setChecked(true);
}
}
private void updateUi() {
if (isNetworkAvailable()) {
OnTaskCompleted taskCompleted = new OnTaskCompleted() {
#Override
public void onFetchMoviesTaskCompleted(ArrayList<Movies> movies) {
mRecyclerView.setAdapter(new MoviesAdapter(getActivity(), movies));
}
};
MoviesAsyncTask moviesAsyncTask = new MoviesAsyncTask(taskCompleted);
mSettings = PreferenceManager.getDefaultSharedPreferences(getActivity());
String sortBy = mSettings.getString(SHARED_KEY_SORT, POPULARITY);
mLastUpdateOrder = sortBy;
moviesAsyncTask.execute(sortBy);
} else {
Toast.makeText(this.getActivity().getApplicationContext(), "Need Internet Connection", Toast.LENGTH_LONG).show();
}
}
private boolean needToUpdateUi() {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getActivity());
if (!mLastUpdateOrder.equals(prefs.getString(SHARED_KEY_SORT, POPULARITY))) {
return true;
} else {
return false;
}
}
//Based on a stackoverflow snippet
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) this.getActivity().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
DeatailActivityFragment
public class DetailActivityFragments extends Fragment {
private final String TAG = this.getClass().getSimpleName();
private static final String PARCEL_KEY = "movie_parcel";
Movies mMovie;
OnTaskCompleted mlistener;
ArrayList<Trailers> mTrailers;
ArrayList<Reviews> mReviews;
ImageView poster;
ImageView backdrop;
public DetailActivityFragments() {
}
#Nullable
#Override
public View onCreateView(LayoutInflater inflater, #Nullable ViewGroup container, Bundle savedInstanceState) {
View view = inflater.inflate(R.layout.activity_detail_fragment,
container, false);
Movies parceableExtra = getActivity().getIntent().getParcelableExtra(PARCEL_KEY);
poster = view.findViewById(R.id.poster_IV);
TextView title = view.findViewById(R.id.title_TV);
TextView releaseDate = view.findViewById(R.id.relaesedate_TV);
TextView vote = view.findViewById(R.id.vote_TV);
TextView overView = view.findViewById(R.id.overview_TV);
backdrop = view.findViewById(R.id.image_id);
final FloatingActionButton fab1 = view.findViewById(R.id.fab);
//String gotPosition = getStringExtra("position");
//intGotPosition=Integer.parseInt(gotPosition);
// String url = "https://image.tmdb.org/t/p/w1280"+DetailActivityFragments.backdrop[intGotPosition];
title.setText(parceableExtra.getTitle());
releaseDate.setText(parceableExtra.getReleaseDate());
vote.setText(parceableExtra.getVote());
overView.setText(parceableExtra.getOverview());
Picasso.with(view.getContext()).load(parceableExtra.getPosterPath())
.into(poster);
Picasso.with(this.getActivity()).load( parceableExtra.getmBackdrop())
.error(R.drawable.sam).into(backdrop);
fab1.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
Context context = view.getContext();
Intent i=new Intent(context , TrailerActivity.class);
startActivity(i);
}
});
return view;
}
}
MoviesAsyncTask.java
public class MoviesAsyncTask extends AsyncTask<String, Void, ArrayList<Movies>> {
private final String LOG_TAG = MoviesAsyncTask.class.getSimpleName();
final String MY_API_KEY = "removed deliberately";
ArrayList<Movies> mMovies;
private OnTaskCompleted mListener;
public MoviesAsyncTask(OnTaskCompleted listener) {
mListener = listener;
}
#Override
protected void onPreExecute() {
super.onPreExecute();
}
#Override
protected ArrayList<Movies> doInBackground(String... params) {
if (params.length == 0) {
return null;
}
final String MOVIEDB_BASE_URL =
"https://api.themoviedb.org/3/movie/";
final String APIKEY = "api_key";
Uri builtUri = Uri.parse(MOVIEDB_BASE_URL).buildUpon()
.appendPath(params[0])
.appendQueryParameter(APIKEY, MY_API_KEY)
.build();
URL url = null;
try {
url = new URL(builtUri.toString());
} catch (MalformedURLException e) {
e.printStackTrace();
}
URLConnection connection = null;
try {
connection = url.openConnection();
} catch (IOException e) {
e.printStackTrace();
}
String response = null;
try {
response = MoviepediaJsonUtils.getResponseFromHttpUrl(connection.getInputStream());
} catch (IOException e) {
e.printStackTrace();
}
try {
return MoviepediaJsonUtils.getParseMovieJson(response);
} catch (JSONException e) {
e.printStackTrace();
}
return null;
}
#Override
protected void onPostExecute(ArrayList<Movies> movies) {
super.onPostExecute(movies);
mListener.onFetchMoviesTaskCompleted(movies);
mMovies = movies;
}
}
Try to add your string at the end of your class or remove all the parcelable generated code, add your string, then apply again the parcelable implementation.
This happens because you're not updating the parcel methods.

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.

Categories

Resources