Retrofit 2: Async download many images and store in Android folder - android

I need to download 20 images from remote server and store in Android folder.
Here my code:
Interface:
#GET
Call<ResponseBody> downloadFile(#Url String url);
In fragment:
private void downloadImagesList(List<Image> imagesList) {
for (Image image : imagesList) {
final String imageSourceUrl = imageSource.getUrl();
Call<ResponseBody> call = RestClientFactory.getRestClient().downloadFile(imageSourceUrl);
call.enqueue(new DefaultRestClientCallback<ResponseBody>() {
#Override
public void onSuccess(Response<ResponseBody> response) {
Toast.makeText(context, "Success download from url: " + imageSourceUrl, Toast.LENGTH_LONG).show();
// code to write downloaded image to Android's local folder
}
});
}
}
As you can see I iterate loop and call call.enqueue() for every image.
Is it good solution? Is this can perform my android app?

You can use dependencies like Glide , Pissaco etc for downloading images from remote server. Because these provide better caching and error handling. Have a look at the code below. It is using Pissaco to load the image
First add the Pissaco dependency in your build.gradle
compile 'com.squareup.picasso:picasso:2.5.2'
Picasso.with(context)
.load(url)
.resize(50, 50)
.centerCrop()
.into(imageView)

Related

Using Glide to load an image from remote storage

I am developing an android app that needs to load many images from a folder that is located on my online server (in this case a GoDaddy hosting shared-plan).
All of the images are stored in an image folder inside the FileManager folder provided by GoDaddy.
Glide needs a URL to load an image, but in my case these images are not public and can't be reached from a HTTP URL (and should remain that way).
I would like to use glide to load these remotely stored images just like I am able to do so locally by providing a local path to the images on my local machine
For example this code works locally where path = (C:\Users\user\images\myImage.png) notice that it is not https:// url .
Glide.with(mContext)
.load(C:\Users\user\images\myImage.png)
.into(mImageView);
The path provided here is local and works on my local machine, I would like to replace localPath with remoteStorageFolderPath but I am unsure how it is done. Any help would be greatly appreciated!
Thank you.
so I think this has already been brought up as an issue in Glides Github, and was solved by TWiStErRob on 10 Nov 2016. The way to do it is to add an authorisation header as follows:
LazyHeaders auth = new LazyHeaders.Builder() // This can be cached in a field and reused later.
.addHeader("Authorization", new BasicAuthorization(username, password))
.build();
Glide
.with(context)
.load(new GlideUrl(url, auth)) // GlideUrl is created anyway so there's no extra objects allocated.
.into(imageView);
}
public class BasicAuthorization implements LazyHeaderFactory {
private final String username;
private final String password;
public BasicAuthorization(String username, String password) {
this.username = username;
this.password = password;
}
#Override
public String buildHeader() {
return "Basic " + Base64.encodeToString((username + ":" + password).getBytes(), Base64.NO_WRAP);
}
}

How to load image from aws with picasso with private access

I'm trying to load image stored on aws S3 into my android app using Picasso but I am getting a blank image with no errors in my logcat and nothing to me from general debugging around the relevant lines of code.
We are having private access on images so image url can't work on browser.
i need to display image into my android app using Picasso. but it doesn't work.
My code snippet below
new Picasso.Builder(getApplicationContext()).downloader(new S3Downloader(getApplicationContext(), s3Client, bucket))
.build()
.load("https://s3-ea-east-8.amazonaws.com/music/MusicApp_3.jpg")
.placeholder(R.drawable.img_placeholder)
.memoryPolicy(MemoryPolicy.NO_CACHE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(imageView);
By using above code image is displaying only very first time after installing app. next time its only showing placeholder image
I am using this library for displaying image.
The problem isn't with Picasso, it's with loading an image from a "private" url.
please suggest solutions
You need to generate a presigned Url from S3 client and you can pass that url to picasso.
That url will be public and will have an expriy date.
You can use the below set of code , which is a aynctask which will use glide to attach private images from s3 by generating presignedurl.
public class sets3imageasync extends AsyncTask<Object, Void, String> {
// The list of objects we find in the S3 bucket
static final String s3bucket=bucket_name;
Context scontext;
ImageView image;
#Override
protected String doInBackground(Object... objects) {
// Queries files in the bucket from S3.
Calendar cal = Calendar.getInstance();
Log.d(TAG, "doInBackground: in progress");
cal.setTime(new Date());
cal.add(Calendar.HOUR, +1);
Date oneHourLater = cal.getTime();
AmazonS3Client s3 = (AmazonS3Client) objects[0];
scontext= (Context) objects[1];
image=(ImageView) objects[2];
String imagekey=(String) objects[3];
GeneratePresignedUrlRequest generatePresignedUrlRequest =
new GeneratePresignedUrlRequest(s3bucket, imagekey)
.withMethod(HttpMethod.GET)
.withExpiration(oneHourLater);
URL url = s3.generatePresignedUrl(generatePresignedUrlRequest);
Log.e("url was", url.toString());
return url.toString();
}
#Override
protected void onPostExecute(String s) {
super.onPostExecute(s);
Log.d(TAG, "onPostExecute: completed "+s);
Glide.with(scontext).load(s)
.apply(new RequestOptions()
.centerCrop())
.placeholder(scontext.getResources().getDrawable(R.drawable.progress_animation))
.into((image));
}
this can be called as below
new sets3imageasync().execute(s3Client,context,Image_view);
Simply use this:
Picasso.with(getApplicationContext()).load(your_url).noFade().into(imageView);
write below code to load image in Picasso.
variables:-
String file_path -->> this is your image file path
Imageview mViewHolder.img_post_photo -->> this is your imageview to load image.
Picasso.with(context)
.load(file_path)
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(mViewHolder.img_post_photo, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(context)
.load(file_path)
.placeholder(R.mipmap.ic_launcher)
.error(R.mipmap.ic_launcher)
.into(mViewHolder.img_post_photo);
}
});
Set dependencies in your app build.gradle file:-
compile 'com.squareup.picasso:picasso:2.5.2'
hope this code helps you.

how to make picasso display default image when there is an invalid path

I am having one issue on display a default image name here R.drawable.avatar_placeholder. When the link from webservice is non empty, but error 404. means there isn't any image on that link path. Which if i run this function below, the string "path not empty" is shown, but it failed to display the image. Any suggestion is welcomed. Thanks.
private void loadProfileDetails() {
Logger.d(UI_LoginFragmentWithPin.class, "loadProfileDetails profile image: " + PrefUtils.readString(Constant.PREF_PROFILE_IMAGE));
if (!TextUtils.isEmpty(PrefUtils.readString(Constant.PREF_PROFILE_IMAGE))){
Utils.println("path not empty");
LPicasso.getInstance(getActivity())
.load(PrefUtils.readString(Constant.PREF_PROFILE_IMAGE))
.config(Bitmap.Config.RGB_565)
.resize(200, 200)
.centerCrop()
.into(imgProfile);
}else {
Utils.println("path empty");
LPicasso.getInstance(getActivity())
.load(R.drawable.avatar_placeholder)
.config(Bitmap.Config.RGB_565)
.resize(200, 200)
.centerCrop()
.into(imgProfile);
}
tvEmail.setText(PrefUtils.readString(Constant.PREF_EMAIL));
tvName.setText(PrefUtils.readString(Constant.PREF_USER_NAME) + " " + PrefUtils.readString(Constant.PREF_USER_SURNAME));
}
Try this,
Set error image as your place holder image
if(!PrefUtils.readString(Constant.PREF_PROFILE_IMAGE).equals(""))
{
Picasso.with(context).load(PrefUtils.readString(Constant.PREF_PROFILE_IMAGE)).resize(200,200).centerCrop().error(R.drawable.avatar_placeholder).into(imgProfile);
}
else
{
Picasso.with(context).load(R.drawable.avatar_placeholder).error(R.drawable.avatar_placeholder).resize(200,200).centerCrop().into(imgProfile);
}
gradle:
compile 'com.squareup.picasso:picasso:2.5.2'
Try this,
Picasso.with(this)
.load("YOUR IMAGE URL HERE")
.placeholder(DRAWABLE RESOURCE)
.error(DRAWABLE RESOURCE) // Image to load when something goes wrong
.resize(width, height)
.rotate(degree)
.into(imageView);
Picasso are not manging android memorey & slow ,
so i am higley recommend you to not to use it
and instade of it just use Glide libeary .
(You can download image and make her circle with glide , download image a Bitmap and much more )
add to Gradle:
repositories { mavenCentral() // jcenter() works as well because it
pulls from Maven Central }
dependencies { compile 'com.github.bumptech.glide:glide:3.7.0'
compile 'com.android.support:support-v4:19.1.0' }
and just:
for load a pic:
Glide.with(this).load("URL").into(imageView);
and you can add a lot more functionality by glide ,
for example if you want a placeholder until the photo will load
you are just adding .placeholder():
:
Glide.with(this).load("URL").placeholder(R.drawable.placeholder).into(imageView);
and if you want a to display photo incase of the photo you are trying to load is broken or have any problem , just add .error()
:
Glide.with(this).load("URL").error(R.drawable.error).placeholder(R.drawable.placeholder).into(imageView);

Add pre-cached images in apk file for use with Picasso or similar library

I am using Picasso for retrieving and showing images in my Android app. To avoid downloading all images over the network I am trying to add some images with the apk file, as sort of a pre-cached set of images. These images are stored in the assets folder and then copied to the Picasso cache folder on installation. This works as expected, but Picasso still download all images through the network and caches them as .0 and .1 files like this:
root#generic_x86:/data/data/com.my.app/files/images_cache #
ls
10.JPG
100.JPG
101.JPG
102.JPG
11.JPG
1f94664dec9a8c205b7dc50f8a6f3b79.0
1f94664dec9a8c205b7dc50f8a6f3b79.1
2.JPG
4621206beccad87a0fc01df2d080c644.0
4621206beccad87a0fc01df2d080c644.1
The *.JPG images are the ones I copied and the others are the Picasso cached images. Is there a way to make Picasso cache these images properly on installation?
If not, are there any other similar libraries that supports this kind of pre-caching?
Update: trying to cache from Assets folder
I tried making a small snippet that is run at first run of the app. The idea is to iterate the files in the given assets folder and fetch those images with Picasso. However, the below does not cache anything, although I end up in the onSuccess() method of the callback. The asset file names are correct. This is also verified by using the wrong folder name, which puts me in the onError() method of the callback.
I also tried loading it into a temporary ImageView, but it did do any difference.
public static boolean cacheImagesFromAssetsFolder(Context context)
{
boolean ok = false;
try
{
String[] images = context.getAssets().list("my_images");
for (String image : images)
{
Picasso.with(context).load("file:///android_asset/my_images/" + image).fetch(new Callback()
{
#Override
public void onSuccess()
{
// This is where I end up. Success, but nothing happens.
}
#Override
public void onError()
{
}
});
}
ok = true;
}
catch (Exception e)
{
e.printStackTrace();
}
return ok;
}
You could use File URI to request the Picasso to pick the image from your asset location instead of n/w.
Picasso.with(activity) //
.load(Uri.fromFile(file)) // Location of the image from asset folder
Update: How to use your own cache
import com.squareup.picasso.LruCache;
import com.squareup.picasso.Util;
LruCache imageCache = new LruCache(context);
Request request = Request.Builder(Uri.fromFile(asset_file), 0, null).build();
String cacheKey = Util.createKey(request, new StringBuilder());
imageCache.set(cacheKey, bitmap_object_of_asset_image);
Picasso.Builder(context)
.memoryCache(imageCache)
.build().load(asset_url).fetch(callback);

Generate pre-signed url of private Image and load to a image view - S3 Client android

I am trying to load image from my S3 Bucket in my android application. My images are private so I won't be having any specific link for each image.
I'm using link generator,
s3Client.generatePresignedUrl(Constants.S3_BUCKET_NAME, key, expiration);
It generates a URL with let's say 1 hour or 2 min expiration.
Now I have problem in loading the url. I tried loading it by using picasso ,
Picasso.with(context).load(url.toString()).resize(30,38).into(holder.photo);
but it's not quite seems to be working. When I tried that link on browser I got following error
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
Try to attach error listener to Picasso and see what's going on. Also read logcat. Print URL which you pass to Picasso, does it correct?
Picasso.Builder builder = new Picasso.Builder(getApplicationContext());
builder.listener(new Picasso.Listener() {
#Override
public void onImageLoadFailed(Picasso arg0, String err) {
Log.e("Picasso Error", "Errored " + err);
}
});
builder.loggingEnabled(true);
Picasso pic = builder.build();
pic.load("image.jpg").into(iv);

Categories

Resources