Loading Image File from AWS with Picasso - android

New to Picasso here. I'm trying to load an image stored on AWS (specifially S3) into my Android app using Picasso but I keep getting a blank image with no errors in my logcat and nothing obvious to me from general debugging around the relevant lines of code.
The image is stored on AWS which is in development mode and currently public so it shouldn't be an issue of logins etc. I also have internet permissions enabled in my manifest.
The code does seems to work when I save a random image link on the internet but I noticed when I use my browser to go to those links it opens up a page displaying nothing but that image. The database on S3, however, is set up to auto-download the file instead of displaying such a page. Perhaps that's the cause of my problem?
Here are 2 versions of my code, neither has worked for my image on AWS (note I'm substituting my real link to AWS with AWSLink but my actual code uses the real link):
Version 1
mApartmentImageView = (ImageView) v.findViewById(R.id.details_page_apartment_picture);
Picasso.with(getActivity()).load("//AWSLink.jpg").into(mApartmentImageView);
Version 2 (tries to account for auto-download of file)
mApartmentImageView = (ImageView) v.findViewById(R.id.details_page_apartment_picture);
String path = "//AWSLink.jpg";
Picasso.with(getActivity()).load(new File(path)).into(mApartmentImageView);

String path = "//AWSLink.jpg";
path is not a valid one, Use appropriate path and check
Picasso have callbacks, use those and check.
Picasso.with(getActivity()).load(new File(path)).into(mApartmentImageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
}
});
Before that, pass proper file path. Try to hit the file path in browser, If the path is giving image then use it as a parameter in load method
Picasso picasso = new Picasso.Builder(getContext())
.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
//Here your log
}
})
.build(); picasso.load(new File(path)).into(mApartmentImageView);

Related

displaying an image from drive in Android

I'm using Fresco library to display images in my Android app. I'd like to display some images (jpg or png) that I have set with public grants.
When I was doing quick tests, I just took any image from internet to set a URL, but when using the real ones that I need to use, I have the following url https://drive.google.com/uc?export=view&id=<>, but as it is a redirect and, once redirected, new url is not the image itself, Fresco is unable to display it.
I have tried Picasso as an alternative library, but with out any success.
I have also tried the download url for both libraries (https://drive.google.com/uc?export=download&id=<>). But no result.
Anybody knows how could it be possible to get this images? Or the only solution is to download it (using the second url) processing the object received store a bitmap of it and displaying it?
For downloading it, what should i use and how? retrofit?
Thanks in advance.
Fresco supports different network stacks. For example, you can use OkHttp with Fresco, which should follow redirects or modify the default one to allow redirects - or write your own based on them.
Guide for OkHttp: http://frescolib.org/docs/using-other-network-layers.html
Related GitHub issue: https://github.com/facebook/fresco/issues/61
I found a solution for this problem (but could be only applicable if you use Google Cloud or Google Script).
It consists on creating a doGet() service with the following code inside:
var file = DriveApp.getFileById(fileId)
return Utilities.base64Encode(file.getBlob().getBytes());
and use that base64 value in your app. With this format, Fresco can do the magic
It is not an immediate solution, and requires to do somework in other platform that is not your Android app, but it works perfectly.
Are you sure that there is no problems with your URLs?
Picasso works with direct URLs like: https://kudago.com/media/images/place/06/66/06662fda6309ce1ee9116d13bd1c66d5.jpg
Then you can download your image like:
Picasso.with(this)
.load(url)
.noFade()
.placeholder(R.drawable.placeholder_grey) //if you want to use a stub
.into(imageView, new com.squareup.picasso.Callback() {
#Override
public void onSuccess() {
//here you can operate with image after it is downloaded
}
#Override
public void onError() {
}
});
Hope it will help you.

Where do images need to be stored in and Android app?

I've been reading quite a lot on the topic, still not quite clear though. At the moment I'm creating an app, loading an image and a text on one screen. For loading the images I opted for Glide, but where is the most appropriate place to read them from? All of the tutorials I passed pass the image's URL. Isn't it slower when loaded from the net? Thanks a lot!
If you care for apk size then do not put these images static. Instead you can keep these images on server(your or free server) and easily load those images using libraries like Glide or Picasso.
Isn't it slower when loaded from the net?
No. It will download image once and then cache it for future use. So it's very fast.
If you think apk size will doesn't matter for you and user should not face problem due to unavailability of internet then you can keep those images static inside app iteself.
If you want to build an app that uses dynamic images or you want to update your images without updating your application, getting them from the server is better. And in my opition picasso is easy to use and straightforward. Also uses it's own framework caching. But if you think that your images wont change, put them in an asset folder so that they are in app's internal memory. Getting them from the server has it's downsides like you need to use a placeholder images because they won't be retrieved immediately.
You must use caching mechanisms if you want the images always from network. The system I follow is like this: (PS. I use Picasso, fast and reliable):
Picasso.with(this).load(URL).networkPolicy(NetworkPolicy.OFFLINE). //load from cache first time
into(imageView, new Callback() { //Picasso Callback
#Override
public void onSuccess() {
if(isNetworkAvailable()) { // if network available then update the cache for this URL
Picasso.with(MyActivity.this).invalidate(URL);
}
progress.setVisibility(View.GONE); // Progressbar
}
#Override
public void onError() { // Image not loaded, try again one last time
Picasso.with(MyActivity.this).load(URL).into(imageView, new Callback() {
#Override
public void onSuccess() {
progress.setVisibility(View.GONE);
}
#Override
public void onError() {
progress.setVisibility(View.GONE);
}
});
}
});

Cache images local, from google firebase storage

I am searching for a way, to cache images from the storage on google firebase platform. For now, I can download images, and show these to users, but I am not able to cache this, and access, even without internet connection. The database can be accessed offline. So I thought, there would be a way for storage too. I don't want to download every single image to storage, cause then I would need to check everytime, if the image is still up to date, it may be changed. Here are few links, what I could find, but no answer for my question. Maybe someone know a workaround, or a way how to accomplish it. Thanks!
Download files:
https://firebase.google.com/docs/storage/android/download-files
Cache (offline) database:
https://firebase.google.com/docs/database/android/offline-capabilities
UPDATE 1
Here is how I "cache" files with picasso, I added activity, that cares the download:
Picasso.with(getApplicationContext())
.load(uri.toString())
.networkPolicy(NetworkPolicy.OFFLINE)
.into(image1);
Any help is welcome. Thanks!
I'm afraid the Firebase SDK doesn't provide image caching by itself. But there are several great libraries that could do it for you. They download image, show it in an ImageView and cache it in a single line of code. Just request the Firebase for an image download url and feed it to the image caching library.
Something like this, if you choose Picasso as a caching library:
storageRef.child("users/me/profile.png").getDownloadUrl().addOnSuccessListener(new OnSuccessListener<Uri>() {
#Override
public void onSuccess(Uri uri) {
// Got the download URL for 'users/me/profile.png'
// Pass it to Picasso to download, show in ImageView and caching
Picasso.with(context).load(uri.toString()).into(imageView);
}
}).addOnFailureListener(new OnFailureListener() {
#Override
public void onFailure(#NonNull Exception exception) {
// Handle any errors
}
});
UPD: To use disk caching with Picasso you need to explicitly setup OkHttpDownloader. Look here How do I use disk caching in Picasso?
Thanks to #ATom for notice. Api has changed, and FirebaseUI 3.0 now uses Glide 4.x
Here is updated sample:
To load an image from a StorageReference, first register in your
AppGlideModule:
#GlideModule
public class MyAppGlideModule extends AppGlideModule {
#Override
public void registerComponents(Context context, Glide glide, Registry registry) {
// Register FirebaseImageLoader to handle StorageReference
registry.append(StorageReference.class, InputStream.class,
new FirebaseImageLoader.Factory());
}
}
Then you can load a StorageReference into an ImageView:
// Reference to an image file in Cloud Storage
StorageReference storageReference = ...;
// ImageView in your Activity
ImageView imageView = ...;
// Download directly from StorageReference using Glide
// (See MyAppGlideModule for Loader registration)
GlideApp.with(this /* context */)
.load(storageReference)
.into(imageView);
And don't forget to add dependency in your build.gradle:
implementation 'com.firebaseui:firebase-ui-:3.1.0'
Answer source on GitHub
Old answer:
FirebaseUI 1.0 now released. Storage example has class FirebaseImageLoader
Images displayed using FirebaseImageLoader are cached by their path in
Firebase Storage, so repeated loads will be fast and conserve
bandwidth.
// Reference to an image file in Firebase Storage
StorageReference storageReference = ...;
// ImageView in your Activity
ImageView imageView = ...;
// Load the image using Glide
Glide.with(this /* context */)
.using(new FirebaseImageLoader())
.load(storageReference)
.into(imageView);
I had the same issue. Tried all possible ways but couldn't fix that. I think the problem lies with the links generated by firebase storage. Picasso generally caches the images it loads. I have tried other cloud services like cloudinary, LibPixel whose links end with image format (Eg:.jpg) and picasso caches these link images. While firebase links end with token numbers. Strange thing it fails!

How to implement asynchronous image download with cache support in android?

I want to download all images from server and store it in a cache.In most of cases, downloaded images are directly bound to the imageView(e.g. Picasso). I want to use same functionalities in android which is provided by SDWebImage("https://github.com/rs/SDWebImage").
Shutterbug is a good library for this purpose (https://github.com/applidium/Shutterbug). I've used this myself in a few apps and it works well. You can either use the Shutterbug FetchableImageView (which extends ImageView and you give it a URL rather than a bitmap or resource ID and it will display the image when download is complete) or you can use the ShutterbugManager which allows you to control what happens after downloading and caching. All the caching is done for you, it's pretty awesome :)
There are good instructions on the GitHub page's README on how to use both, and there is a demo project too.
EDIT: Just noticed your comment. If you don't want to bind to an ImageView, you can use the ShutterbugManager to download the image and then do whatever with it. Any subsequent calls to the download method will fetch the image from the cache rather than doing an HTTP call again.
public void downloadImage(Context context, String url) {
ShutterbugManager.getSharedImageManager(context).download(url, new ShutterbugManager.ShutterbugManagerListener() {
#Override
public void onImageSuccess(ShutterbugManager manager, Bitmap bitmap, String arg2) {
// Do what you like with the Bitmap here.
}
#Override
public void onImageFailure(ShutterbugManager arg0, String arg1) {
// Failure :(
}
});
}

Picasso library stopped working today with facebook graph picture links

In my app i use Picasso library to load images from urls.
It is a nicely working easily importable and usable library, and just do the thing i need.
However, today it stopped working, and not while developping it is stopped working on a compiled apk.
So after i searched and searched for the reason i just found this buggy thing:
I use facebook graph urls to load profile pictures.
Here is one like:
profile pictre,
the link is actually "http://graph.facebook.com/1464090949/picture?type=large"
But it is redirecting to:
https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn1/t5.0-1/572518_1464090949_1222130273_n.jpg
Of course, both of url calls working in a browser, and you can see the profile picture.
However when i test both links with Picasso:
ImageView iv = (ImageView)findViewById(R.id.imageView1);
//Url1 NOT working, loads nothing.
String url1 = "http://graph.facebook.com/1464090949/picture?type=large";
//Url2 is the same as URL1, i just copied it from a browser, and this is working
String url2 = "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn1/t5.0-1/572518_1464090949_1222130273_n.jpg";
Picasso.with(this).load(url2).into(iv);
So the conclusion is, facebook maybe changed something and from now on Picasso cannot load images from graph.
Anybody can suggest me something to make this work?
Of course i can try different libraries but if there is an other way i would be really happy.
Workaround1:
Change to https from http.
Working:
https://graph.facebook.com/1464090949/picture?type=large
Not Working:
http://graph.facebook.com/1464090949/picture?type=large
Workaround2:
Found soulution on this topic.
If you want for example:
http://graph.facebook.com/1464090949/picture?type=large
This profile picture you could use:
https://graph.facebook.com/1464090949/?fields=picture.type(large)
Which returns a JSON Object:
{
"id": "1464090949",
"picture": {
"data": {
"url": "https://fbcdn-profile-a.akamaihd.net/hprofile-ak-prn1/t5.0-1/572518_1464090949_1222130273_n.jpg",
"is_silhouette": false
}
}
}
And tada! There it is. url's key is the redirected url you can use to load your images.
(This will need oAuth which i didnt tested, just stick with Workaround1)
Try this. worked for me perfectly
Dependency: compile 'com.squareup.okhttp:okhttp:2.5.0'
Picasso.Builder builder = new Picasso.Builder(mContext);
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso picasso, Uri uri, Exception exception) {
/*holder.getIvSpeakerPicture()
.setImageDrawable(context.getResources()
.getDrawable("your drawable id"));*/
}
});
builder.downloader(new OkHttpDownloader(mContext));
builder.build().load(image).into(viewHolder.image);
In case you're using Amazon AWS CloudFront just like me, you can visit this page for detailed instructions from Amazon on how to set up your URL forwarding.
At the least, for Picasso to work with your redirected URLs, your URLs must support https. That is. https://yourdomain.com should redirect to https://yourAWScloudfrontdomain.net
http://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/SecureConnections.html#CNAMEsAndHTTPS

Categories

Resources