I'm saving 5 images to my class in parse.com. I'm able to download one image based on objectid in a imageView. I need to download all 5 images to my 5 ImageViews. How can I do this. Any help would be appreciated. Thanks
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("Footer");
// Locate the objectId from the class
query.getInBackground("tNp607WyQD", new GetCallback<ParseObject>() {
public void done(ParseObject object,ParseException e) {
// TODO Auto-generated method stub
// Locate the column named "ImageName" and set
// the string
ParseFile fileObject = (ParseFile) object.get("imageFile");
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data,ParseException e) {
if (e == null) {
Log.d("test","We've got data in data.");
// Decode the Byte[] into
// Bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0,data.length);
// Get the ImageView from main.xml
//ImageView image = (ImageView) findViewById(R.id.ad1);
ImageView ad1=(ImageView) findViewById(R.id.ad1);
// Set the Bitmap into the
// ImageView
ad1.setImageBitmap(bmp);
// Close progress dialog
progressDialog.dismiss();
} else {
Log.d("test",
"There was a problem downloading the data.");
}
}
});
}
});
}}
I'm able to resolve this with help of imageloader class:
public class Login extends Activity {
public ImageLoader imgl;
EditText fullname, mobilenumber, occupation;
Button save;
ImageView ad1,ad2,ad3,ad4,ad5,ad6;
List<ParseObject> ob;
private ImageView[] imgs = new ImageView[5];
ProgressDialog progressDialog;
int i=0;
HorizontalScrollView horizontalScrollView1;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.userdata);
imgl=new ImageLoader(getApplicationContext());
fullname = (EditText) findViewById(R.id.fullname) ;
mobilenumber = (EditText) findViewById(R.id.mobile) ;
occupation = (EditText) findViewById(R.id.occupation) ;
save=(Button) findViewById(R.id.btnSave);
horizontalScrollView1=(HorizontalScrollView) findViewById(R.id.horizontalScrollView1);
ad1=(ImageView) findViewById(R.id.ad1);
ad2=(ImageView) findViewById(R.id.ad2);
ad3=(ImageView) findViewById(R.id.ad3);
ad4=(ImageView) findViewById(R.id.ad4);
ad5=(ImageView) findViewById(R.id.ad5);
ad6=(ImageView) findViewById(R.id.ad6);
imgs[0] = ad2;
imgs[1] = ad3;
imgs[2] = ad4;
imgs[3] = ad5;
imgs[4] = ad6;
progressDialog= ProgressDialog.show(Login.this, "","Downloading Image...", true);
// Locate the class table named "Footer" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"Footer");
query.orderByDescending("updatedAt");
try {
ob = query.find();
} catch (ParseException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
for (ParseObject country : ob) {
ParseFile image = (ParseFile) country.get("imageFile");
imgl.DisplayImage(image.getUrl(), imgs[i]);
i=i+1;
System.out.println("the urls are"+image.getUrl());
progressDialog.dismiss();
}
}
}
How about this? (Maybe it's a very crude way)
Since you have 5 (defined) imageviews, create an array of imageviews.
private ImageView iv1, iv2, iv3, iv4, iv5;
private ImageView[] imgs;
In onCreate(),
imgs = new ImageView[5];
iv1 = (ImageView) findViewById(R.id.iv1);
iv2 = (ImageView) findViewById(R.id.iv2);
iv3 = (ImageView) findViewById(R.id.iv3);
and so on
then set the imageview array, like this,
imgs[0] = iv1;
imgs[1] = iv2;
imgs[2] = iv3;
//so on
In your ParseQuery, assuming you get the required list of ParseObjects (5, I believe),
in done method of GetCallBack,
public void done(List<ParseObject> objects,ParseException e) {
for(int i =0 ; i < objects.size(); i++){
ParseObject object = objects.get(i);
ParseFile fileObject = (ParseFile) object.get("imageFile");
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data,ParseException e) {
if (e == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0,data.length);
imgs[i].setImageBitmap(bmp);
} else {
Log.d("test",
"There was a problem downloading the data.");
}
}
});
}
progressDialog.dismiss();
}
In the ParseQuery, to get images in ascending order of createdAt, use
query.orderByAscending("createdAt");
Just incase if you face any problem with the variable 'i' in the ParseQuery, (particularly, you may not be allowed to use i inside done() and will ask you to declare it as final), let me know!
You need to refactor your code in such a way that you can create a customised instance of your download task.
For example, create a FooterQuery class which wraps the ParseQuery. When you construct the object, you pass in the parseId and the resource id of the ImageView that it should be loaded into.
If the ImageView is controlled by an AdapterView (list a List or Grid view), it is going to be more complex.
Related
I need to update the list with images retrieved in the background using Parse service. Using below code, I could retrieve images and display but interaction is quite slow. Is there any better way to update the ListView dynamically without impacting user interaction speed?
ParseQuery<ParseObject> userFeedQuery = ParseQuery.getQuery("Offers");
userFeedQuery.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
if (e == null){
if (objects.size() > 0){
for (ParseObject object:objects){
final String offerName = object.getString("offerName");
final String offerDetail = object.getString("offerDetails");
final Bitmap[] offerImage = new Bitmap[1];
ParseFile file = (ParseFile) object.getParseFile("offerImage");
file.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e == null){
offerImage[0] = BitmapFactory.decodeByteArray(data,0,data.length);
offerModelList.add(new OfferModel(offerName,offerDetail, offerImage[0]));
adapter.notifyDataSetChanged();
}
}
});
}
}
adapter = new OffersAdapter(getApplicationContext(),R.layout.offers_table,offerModelList);
offersListView.setAdapter(adapter);
}
}
});
Yes, you can replace ParseImageView with Picaso or Glide, but i prefere Picaso.
Replace
ParseFile file = (ParseFile) object.getParseFile("offerImage");
With this
String OfferImageUrl = object.getParseFile("offerImage");
if (!TextUtils.isEmpty(OfferImageUrl)) {
Picasso.with(this) // use getContext or contex for fragments or adapter
.load(OfferImageUrl)
.error(android.R.drawable.error) // your own error image
.into(mOfferImage); // mOfferImage = (ImageView) findViewById(R.id.offer_image);
}
Hope this help. Let me know for any assistance about this question.
I am trying to download the image from parse.com and display in a image view in an Activity extending AppCompatActivity.
I got this code from one of many searches:
ParseImageView mImage = (ParseImageView) findViewById(R.id.image);
ParseObject object = new ParseObject("Appetizers"); // class name
ParseFile postImage = object.getParseFile("imageFiles"); // column name
String imageUrl = postImage.getUrl() ;//live url
Uri imageUri = Uri.parse(imageUrl);
Picasso.with(getBaseContext()).load(imageUri.toString()).into(mImage);
File format: jpg
Here's my solution. On my activity, extending AppCompatActivity, this is the code to download an image inside ImageView:
ImageLoader.ImageCache imageCache = new BitmapLruCache();
ImageLoader imageLoader = new ImageLoader(Volley.newRequestQueue(getApplicationContext()), imageCache);
NetworkImageView headshot = (NetworkImageView) findViewById(R.id.speaker_headshot);
headshot.setImageResource(R.drawable.loading);
headshot.setImageUrl("http://www.anydomain.com/anyimage.jpg", imageLoader);
As you see you will need an addicional class in your project, a file named BitmapLruCache.java. Here is the entire content of it:
public class BitmapLruCache extends LruCache<String, Bitmap> implements ImageLoader.ImageCache {
public BitmapLruCache() { this(getDefaultLruCacheSize()); }
public BitmapLruCache(int sizeInKiloBytes) { super(sizeInKiloBytes); }
#Override
protected int sizeOf(String key, Bitmap value) { return value.getRowBytes() * value.getHeight() / 1024; }
#Override
public Bitmap getBitmap(String url) { return get(url); }
#Override
public void putBitmap(String url, Bitmap bitmap) { put(url, bitmap); }
public static int getDefaultLruCacheSize() {
final int maxMemory = (int) (Runtime.getRuntime().maxMemory() / 1024);
final int cacheSize = maxMemory / 8;
return cacheSize;
}
}
Finally, for this to work you have to setup a special ImageView inside your layout XML:
<com.android.volley.toolbox.NetworkImageView
android:id="#+id/speaker_headshot"
android:layout_width="match_parent"
android:layout_height="150dp"
android:scaleType="centerCrop"/>
EDIT: For all of this to work you have to import:
1) the Volley library. Do this on your Android Studio: menu File/Project Structure/Modules-app/Tab Dependencies. There you add (+ sign) a Library Dependency and find or search for com.android.volley:volley:1.0.0. That's it. OR simple include this in your build.gradle (module app) file:
dependencies {
compile 'com.android.volley:volley:1.0.0'
}
If you already have a "dependencies" section then just include the line inside it.
AND
2) Put a copy of disklrucache-2.0.2.jar into your "libs" folder ( get the .jar from here https://search.maven.org/remote_content?g=com.jakewharton&a=disklrucache&v=LATEST ) OR insert another "compile" directive inside your "dependencies":
compile 'com.jakewharton:disklrucache:2.0.2'
try on this way.
ParseObject object = new ParseObject("Appetizers"); // class name
ParseFile postImage = object.getParseFile("imageFiles"); // column name
ParseQuery<ParseObject> getimage = new ParseQuery<ParseObject>("Appetizers"); // class
getimage.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> objects, ParseException e) {
// TODO Auto-generated method stub
if (e == null) {
// success
for (ParseObject parseObject : objects) {
ParseFile fileObject = (ParseFile) parseObject.get("imageFiles");
Log.d("test", "get your image ... " + fileObject.getUrl());
Picasso.with(getBaseContext()).load(fileObject.getUrl()).placeholder(R.drawable.ic_launcher)
.into(mImage);
}
} else {
// fail
Log.d("test", "error Message... " + e.getMessage());
}
}
});
your have not set picasso place holder for clear catch memory form picasso lib.
I figured it out by debugging and setting logs everywhere ...
In the sending class:
ParseObject po = mAppetizers.get(position); // get position
String ID = po.getObjectId().toString();
Intent intent = new Intent(Appetizer.this, AppetizerRecipe.class);
intent.putExtra("ID", ID);
startActivity(intent);
In the receiver's class:
final ParseImageView mImage = (ParseImageView) findViewById(R.id.image);
String ID = getIntent().getStringExtra("ID");
ParseQuery<ParseObject> getimage = new ParseQuery<>("Appetizers");
getimage.addAscendingOrder("appetizer");
getimage.whereEqualTo("ID", ID);
Log.d("AppetizerRecipe2", "object: " + ID);
getimage.getInBackground(ID, new GetCallback<ParseObject>() {
#Override
public void done(ParseObject object, ParseException e) {
if (e == null) {
Log.v("what is e?", "e = " + e);
// success
final ParseFile fileObject = (ParseFile)object.get("imageFiles");
fileObject.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
Log.d("test", "We've got data in data.");
// use data for something
Log.d("test", "Get your image..." + fileObject.getUrl());
Picasso.with(getBaseContext()).load(fileObject.getUrl()).placeholder
(R.drawable.ic_launcher).into(mImage);
} else {
Log.d("test", "There was a problem downloading the data.");
}
}
});
} else {
// fail
Log.d("test", "Error Message..." + e.getMessage());
}
}
});
I have an app that downloads an image from Parse.com and displays that image in an Image View
The problem is that whenever I exit the app (with the back button) and return the image is gone.
How can I make the image stay?
(For example: when you update your profile pic on Twitter and leave the app and return your profile pic will still be displayed)
Any help would be greatly appreciated this is very important.
MainActivity:
public class MainActivity extends Activity {
Button button;
private ProgressDialog progressDialog;
/** Called when the activity is first created. */
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the view from main.xml
setContentView(R.layout.activity_main);
// Show progress dialog
// Locate the button in main.xml
button = (Button) findViewById(R.id.button);
// Capture button clicks
button.setOnClickListener(new OnClickListener() {
public void onClick(View arg0) {
progressDialog = ProgressDialog.show(MainActivity.this, "",
"Downloading Image...", true);
// Locate the class table named "ImageUpload" in Parse.com
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>(
"ImageUploads");
// Locate the objectId from the class
query.getInBackground("h3FvFzrHPr",
new GetCallback<ParseObject>() {
public void done(ParseObject object,
ParseException e) {
// TODO Auto-generated method stub
// Locate the column named "ImageName" and set
// the string
ParseFile fileObject = (ParseFile) object
.get("imageContent");
fileObject
.getDataInBackground(new GetDataCallback() {
public void done(byte[] data,
ParseException e) {
if (e == null) {
Log.d("test",
"We've got data in data.");
// Decode the Byte[] into
// Bitmap
Bitmap bmp = BitmapFactory
.decodeByteArray(
data, 0,
data.length);
// Get the ImageView from
// main.xml
ImageView image = (ImageView) findViewById(R.id.image);
// Set the Bitmap into the
// ImageView
image.setImageBitmap(bmp);
// Close progress dialog
progressDialog.dismiss();
} else {
Log.d("test",
"There was a problem downloading the data.");
}
}
});
}
});
}
});
}
}
Try using an image library that can handle picture caching.
You could try Glide or Picasso.
First add the library to your project. Them instead of downloading the file and decoding by yourself use the library to download and cache the object for you.
(Glide example)
After searching for the object and extracting parsefile use Glide:
ParseFile fileObject = (ParseFile) object.get("imageContent");
String url = fileObject.getUrl();
ImageView image = (ImageView) findViewById(R.id.image);
Glide.with(getContext())
.load(url)
.into(image);
Next time you open the app Glide will search object in cache and only fetch if needed.
try to this way better to use BitMap.
ParseQuery<ParseObject> query = new ParseQuery<ParseObject>("subclass");
query.findInBackground(new FindCallback<ParseObject>() {
#Override
public void done(List<ParseObject> List, ParseException e) {
// TODO Auto-generated method stub
if (e == null) {
// success
if (List.size() > 0) {
for (ParseObject parseObject : List) {
// here fetch image like..
ParseFile image = (ParseFile) parseObject.get("fieldName");
if (image != null) {
Log.e("getting Image", "Image URL " + image.getUrl());
// here add to your adapter array
Picasso.with(getApplicationContext()).load(image.getUrl()).fit().into("imageView");
}
}
// and here call your adapter for fill array data
}
} else {
// e.getMessage() here getting error ...
}
}
});
The answer to this question is here: How To Create An App That Allows For Profile Picture Upload/Change?
I have resolved the problems I have been facing
I am using this code to get Strings of names and ages from my ParseObject
in Parse. I assumed I can do the same for imagefiles as well. But this code doesn't work for the images. I may have done it wrong. or maybe I need to do something totally different. Can someone help me to get my imagefile from parseObject?
Thank you
public class MyAdapter extends ArrayAdapter<ParseObject> {
protected Context mContext;
protected List<ParseObject> MyPerson;
public MyAdapter (Context context, List<ParseObject> MyPerson){
super(context, R.layout.scustomlayout, MyPerson);
mContext = context;
mPerson = MyPerson;
}
#Override
public View getView (final int position, View convertView, ViewGroup Parent){
final ViewHolder holder;
if(convertView == null) {
convertView = LayoutInflater.from(mContext).inflate(R.layout.personcustomlayout, null);
holder = new ViewHolder();
holder.NameMain = (TextView) convertView.findViewById(R.id.NameHP);
holder.AgeMain = (TextView) convertView.findViewById(R.id.AgeHP);
holder.ImageMain = (ImageView) convertView.findViewById(R.id.ImageHP);
convertView.setTag(holder);
}else {
holder = (ViewHolder) convertView.getTag();
}
ParseObject personObject = mPerson.get(position);
//name
String name = personObject.getString("Name");
holder.NameMain.setText(name);
//Age
String age = personObject.getString("Age");
holder.AgeMain.setText(age);
ParseFile image = (ParseFile) personObject.get("Image");
image.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
// Decode the Byte[] into bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
// Set the Bitmap into the imageView
holder.ImageMain.setImageBitmap(bmp);
} else {
Log.d("test", "There was a problem downloading the data.");
}
}
});
return convertView;
}
public static class ViewHolder {
ImageView ImageMain;
TextView NameMain;
TextView AgeMain;
}
}
ParseFile image = (ParseFile) personObject.get("Image");
image.getDataInBackground(new GetDataCallback() {
public void done(byte[] data, ParseException e) {
if (e == null) {
// Decode the Byte[] into bitmap
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0,data.length);
// Set the Bitmap into the imageView
holder.ImageMain.setImageBitmap(bmp);
} else {
Log.d("test", "There was a problem downloading the data.");
}
}
});
Also, add this to the imports:
import com.parse.ParseException;
An easier and better option would be to get the file URL and load it into the ImageView via a third party library such as Picasso or Glide. This way, your code is less cumbersome, your ListView will scroll smoothly and your won't encounter OOM error too often.
ParseFile image = (ParseFile) personObject.get("Image");
String url = image.getUrl();
// With Picasso
Picasso.with(mContext).load(url).into(holder.ImageMain);
// With Glide
Glide.with(mContext).load(url).into(holder.ImageMain);
There is no need to create the new String object url, you could do it directly, I just did it to make it easier to understand.
Also, it would be better to save the URL to the MyPerson object when you run the ParseQuery, this will make your images load faster
I'm trying to find a ParseObject by " objectId ", then retrieve the image " ImageFile " and then Load it to the imageview, it doesn't work and i'm getting the USER String, can you help me out with this, it works when i use another query like : query.find()
ParseImageView mealImage = (ParseImageView) findViewById(R.id.icon);
ParseQuery<ParseObject> query1 = ParseQuery.getQuery("Annonces");
query1.getInBackground("ux3Af0cwEx", new GetCallback<ParseObject>() {
public void done(ParseObject Annonces, ParseException e) {
photoFile = (ParseFile) Annonces.get("ImageFile");
text1.setText((CharSequence) Annonces.get("USER"));
}
});
mealImage.setParseFile(photoFile);
mealImage.loadInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
}
});
}
The code for displaying image in imageview:
ParseFile image = (ParseFile) userData.getParseFile("user_image");
then call following function.
loadImages( photoFile, mealImage);
private void loadImages(ParseFile thumbnail, final ImageView img) {
if (thumbnail != null) {
thumbnail.getDataInBackground(new GetDataCallback() {
#Override
public void done(byte[] data, ParseException e) {
if (e == null) {
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
img.setImageBitmap(bmp);
} else {
}
}
});
} else {
img.setImageResource(R.drawable.menu);
}
}// load image
If you are using Picasso or Glide for image loading and don't want to change the image loading logic, you can extract image url from ParseFile and load it in background.
Like:
ParseFile thumbnail = parseObject.getParseFile("image");
if(thumbnail != null) {
String imageUrl = thumbnail.getUrl();
Picasso.with(mContext).load(imageUrl).into(imageView);
}
No need to load thumbnail ParseFile data separately.