I'm Using Android Universal Image loader in my news app i'm currently working on. I'm using NewsAPI to fetch news. After parsing the JSON from the website. I populate a list view using a custom adapter and universal image loader is used to get the images in background. But for some pictures UIL doesn't support scheme(protocol) by default [null].You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...)) exception is displayed.
I think in some images the URI is not in the format of Library expecting.
So my question is how do i fill the image's position which gave me the error from a picture that i have in the Drawable Folder. (404 picture indicating the image could not be downloaded)
i found where i should put the code.
protected InputStream getStreamFromOtherSource(String imageUri, Object extra) throws IOException {
throw new UnsupportedOperationException(String.format("UIL doesn't support scheme(protocol) by default [%s]. You should implement this support yourself (BaseImageDownloader.getStreamFromOtherSource(...))", new Object[]{imageUri}));
}
I need to know what kind of code i should put here to put a 404 image from my drawable file if the image is not downloadable.
Bro.. you can use Piccasso image library for android. It can solve your issue.
Sample code:
if(!image.equals("default")){
Picasso.with(Profile.this).load(image).networkPolicy(NetworkPolicy.OFFLINE)
.placeholder(R.drawable.default).into(mDisplayImage, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
Picasso.with(Profile.this).load(image).placeholder(R.drawable.default).into(mDisplayImage);
}
});
}
Here it can replace the default (i.e) 404 found image while Error condition
And small suggesstion that, you can use Easy News Library for simple retrieval of news from NewsAPI. Here we don't need to parse the JSON. It gives the data by single method call
Related
EDIT:
I asked a similar question a day before and I wrote this post based on information I gathered since that question -
First Cache Question. I know they are similar but this question is more concise to avoid extra information. I also didn't want to delete that post since it was answered, even though the answer didn't suffice.
I use a recyclerview to show photos I get from google places api. I know that I am not allowed to legally cache photos outside of runtime. I didn't know that was happening until I randomly opened my phone's gallery to see a lot of copies of the photos I get from google.
My first guess was that my use of Picasso was the issue so I added code to fix it,
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE)
finding these in StackOverflow was pretty simple, but this didn't fix anything except that now it seems to only download them once especially when I delete them. I believe I eliminated the possible issues and am outlining the last one in this question.
private Uri getImageUri(Context inContext, Bitmap inImage) {
ByteArrayOutputStream bytes = new ByteArrayOutputStream();
inImage.compress(Bitmap.CompressFormat.JPEG, 100, bytes);
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
return Uri.parse(path);
}
#Override
public void onBindViewHolder(#NonNull VenueViewHolder venueViewHolder, int i) {
Collections.sort(vIAL, (o1, o2) -> o1.getVenueName().compareToIgnoreCase(o2.getVenueName()));
VenueItem currentItem = vIAL.get(i);
Picasso.with(context)
.load(getImageUri(context, currentItem.getVenueImage()))
.fit()
.memoryPolicy(MemoryPolicy.NO_CACHE, MemoryPolicy.NO_STORE)
.networkPolicy(NetworkPolicy.NO_CACHE)
.into(venueViewHolder.vIV);
venueViewHolder.vTV.setText(currentItem.getVenueName());
Log.i(TAG, "The photo should have been on screen");
}
The URI method getImageUri is something I found as an answer to another problem I had, that I needed a URI to implement the Picasso library so that I can manipulate the photos before displaying them.
My question is - How do I remove the photos when the app closes?
UPDATE:
I changed my tactic to see what would happened and used Glide
#Override
public void onBindViewHolder(#NonNull VenueViewHolder venueViewHolder, int i) {
Collections.sort(vIAL, (o1, o2) -> o1.getVenueName().compareToIgnoreCase(o2.getVenueName()));
VenueItem currentItem = vIAL.get(i);
Glide.with(context)
.load(currentItem.getVenueImage())
.into(venueViewHolder.vIV);
venueViewHolder.vTV.setText(currentItem.getVenueName());
}
and it gave a fatal Error
E/JavaBinder: !!! FAILED BINDER TRANSACTION !!! (parcel size = 4344032)
This was one of the errors and it didn't occur the first time I ran this new code but it got worse the second and third time I ran it.
I shifted my code based on an answer I got early from #Padmini S but they used a url in the load part and I pass a bitmap because for the life of me I can't figure out how to get a URL from Google Places API instead of the code they provide in
Google Place Photos.
I'm relatively new to coding so this is me trying to piece together what I need to learn more. I'm just out of ideas of what to search for so I ask here,
based on the new information I gathered from the answer, can I replace
MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
in my code so that my photos don't get saved to my phone's photos?
Final Update
I ended up rewriting a lot of the code surrounding this and deleting this code. I ended up making an arraylist class to hold the array list for the duration of runtime and it let me remove most of the extra code I wrote out of ignorance.
I really don't know whether it'll solve your problem or not , but you are storing the images in device local storage here,
private Uri getImageUri(Context inContext, Bitmap inImage) {
String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), inImage, "Title", null);
}
I have never used google places api but usually apis will return you with an image url you can store that url in POJO class and display it directly in recyclerview row image view like I am doing in below code,
public void onBindViewHolder(#NonNull ViewHolder viewHolder, final int i) {
viewHolder.description.setText(links.get(i).getTitle());
Glide.with(context).load(links.get(i).getImage_url()).into(viewHolder.image);
}
I am building my application using Android Studio, this app can upload an image from raspberry to my emulator. It works fine. What I want to do now is uploading this image and showing it directly to the user without searching it in the gallery. I thought about creating another class and setting this image as a background image in my xml file, but this is too much like I have to create another class every time I want to upload an image from my raspberry.
Can someone help me please. Thank you
If I'm understanding your question correctly, you'd like to load an image from the Android filesystem into your app and display it to the user.
Drawable, Android's generalized image class, allows you to load from file via Drawable#createFromPath.
This SO question suggests Drawable#createFromPath doesn't work on paths beginning with file://, so depending on your use case you may want to precede that with Uri#parse/Uri#getPath.
Once you have a Drawable, you can display it in one of two ways: put an ImageView in your app and call its setImageDrawable method, or set the Drawable as your background image via View#setBackground (note that setBackground was only added in API 16 - in prior versions, you should call View#setBackgroundDrawable).
Putting all of this together, we end up with the following (untested):
private void loadImage(String imagePath) {
Uri imageUri;
String fullImagePath;
Drawable image;
ImageView imageDisplay;
imageUri = Uri.parse(imagePath);
fullImagePath = imageUri.getPath();
image = Drawable.createFromPath(fullImagePath);
imageDisplay = (ImageView) findViewById(R.id.imageDisplay);
/*if image is null after Drawable.createFromPath, this will simply
clear the ImageView's background */
imageDisplay.setImageDrawable(image);
/*if you want the image in the background instead of the foreground,
comment the line above and uncomment this bit instead */
//imageDisplay.setBackground(image);
}
You should be able to modify this to work with any View just by replacing imageDisplay's declared type with the appropriate View type and changing the cast on findViewById. Just make sure you're calling setBackground, not setImageDrawable, for a non-ImageView View.
I'm making this netflix style app in which images are loaded into different categories. Let's say Dog videos (has 15 images), Cat videos (15 images), etc... All the images are loaded from a URL, it kind of takes a while for all to load. I was wondering if there was anything I could do to speed up the process? Or maybe show an empty container then fill it as the images load (that would be cool).
This is what I have done:
I have multiple async calls in one Activity, (1 async call per category)
JSONTask1 dogTask = new JSONTask1();
JSONTask2 catTask = new JSONTask2();
JSONTask3 pigTask = new JSONTask3();
JSONTask4 horseTask = new JSONTask4();
dogTask.execute("");
catTask.execute("");
pigTask.execute("");
horseTask.execute("");
I have all of those in a row in my actual code. Thanks.
I would use the "proxy pattern". Basically, you need to create a class that contains the minimal informations required for the display. In which, you have a preview image.
When ever you load everything you start by showing the preview content, ie : a loading gif for everypicture with the title of the movie or whatever. and basically the proxy would have a "loadImage" method that would make an ajax call or async call and the photos would load one by one. Plus, to make the loading easier, make sure the photos are not oversized.
You can see Picasso answers , in picasso i suggest you this way :
Picasso.with(getApplicationContext()).load("your url").placeholder(R.drawable.your_place_holder).error(R.drawable.showing_when_error_occured)
.into(imageView, new Callback() {
#Override
public void onSuccess() {
}
#Override
public void onError() {
}
});
Also another suggestion from me : convert your thumb images to base64 format in backend, then firstly retrieve your thumbs and show them. Then start an async task and change images when successfull.
Like whatsapp. In whatsapp you have thumb images they have so low resolution and super fast. When you click image if you have internet connection they load actual thumb images, and click again they load larger image.
Picasso website :http://square.github.io/picasso/
Load them asynchronously with Picasso, you can even show a placeholder image until the real one is loaded
In my Android app I use Picasso to load images. This normally works perfectly well.
Today I tried loading a static image from the google maps api, but this doesn't seem to work. When I open the example link as provided on their info page, I get to see the static map image perfectly well. When I load it in my Android app using the line below, I get nothing at all.
Picasso.with(getContext()).load("http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=370x250&maptype=roadmap%20&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318%20&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false").into(mapView);
I also tried to download the image and uploading it to my personal webspace, from which it loads perfectly well, but somehow, it doesn't seem to load directly from the direct google API url.
Does anybody know why this is so, and how I can solve it?
The only programmatic point-of-failure that comes to mind is in parsing the URI. Looking at the current Picasso code (https://github.com/square/picasso/blob/master/picasso/src/main/java/com/squareup/picasso/Picasso.java) I see the following:
public RequestCreator load(String path) {
if (path == null) {
return new RequestCreator(this, null, 0);
}
if (path.trim().length() == 0) {
throw new IllegalArgumentException("Path must not be empty.");
}
return load(Uri.parse(path));
}
So I'd first debug
Uri.parse("http://maps.googleapis.com/maps/api/staticmap?center=Brooklyn+Bridge,New+York,NY&zoom=13&size=370x250&maptype=roadmap%20&markers=color:blue|label:S|40.702147,-74.015794&markers=color:green|label:G|40.711614,-74.012318%20&markers=color:red|color:red|label:C|40.718217,-73.998284&sensor=false")
and see what that Object looks like. Does it drop or confuse any of your parameters?
If that doesn't lead you anwhere, try downloading the file manually using a HttpClient [or similar]. Then at least you can fully debug the request/response.
Also, I know Google maps has some limits -- are you sure you haven't reached them?
replace http with https
replace | with %7C
add api key
The .loadMap() function has many declared variables. This is the heart of the whole process.
So what is required for the static maps API to give us an image is that we make an http request with a given url, for which an image response (URL) is received. Let us run through the meaning and utility of these variables. Yes, all of them have a completely different meaning!
The mapUrlInitial variable is always the same while making an API call. It has a query of center ( ?center ) which specifies that we want the location to be centered in the map.
The mapUrlProperties variable contains a string where you control the actual zooming of the image response you will get, the size ofthe image and the color of the marker which will point out our place.
The mapUrlMapType variable is a string where you can actually determine the marker size you want and the type of the map. We are using a roadtype map in the app.
Finally latLong is a string which concatenates the latitude and the longitude of the place we want to pinpoint!
We then concatenate all of these strings to form a feasible Url. The Url is then loaded as we have seen above, in the Picasso code. One thing we can notice is that an event object is always required for all of this to happen, because we are able to fetch the position details using the event object! Final Code:-
fun loadMap(event: Event): String{
//location handling
val mapUrlInitial = “https://maps.googleapis.com/maps/api/staticmap?center=”
val mapUrlProperties = “&zoom=12&size=1200×390&markers=color:red%7C”
val mapUrlMapType = “&markers=size:mid&maptype=roadmap”
val latLong: String = “” +event.latitude + “,” + event.longitude
return mapUrlInitial + latLong + mapUrlProperties + latLong + mapUrlMapType
}
//load image
Picasso.get()
.load(loadMap(event))
.placeholder(R.drawable.ic_map_black_24dp)
.into(rootView.image_map)
In my application I'd like to show some animations at the startup in some special events like Halloween, Thanksgiving, Christmas etc.
I didn't find a hot to show an animated .gif in a View. The closest solution I found is to make an AnimationDrawable with the gif frames.
I'm trying to implement that but have some questions about how to store (currently i'm using a LAMP server), transfer and recover the resources needed from the server to the Android device.
Downloading the .gif data to the phone and extract there the frames and framerate programmatically is a nice solution or it will add an unnecessary load to the client? If its appropriated is there some library or source for guiding me in with that task?
If I want to handle the gif in the server and then I want to serve it to the client frame-by-frame, how can I do that? I've thought in making a JSON with the URL's of the images and download them but maybe is not a nice option since I'd need a lot of http connections and the load could be slower if the network latency is high
Where can I find the internal structure of a gif? I have searched in Google but nothing found
Thanks in advance
Downloading the .gif data to the phone and extract there the frames and framerate
programmatically is a nice solution or it will add an unnecessary load to the client?
If its appropriated is there some library or source for guiding me in with that task?
if you want to extract the gif file to get the frames and the frame rate you need a GIF decoder and then applay them to the AnimationDrawable this will help you to add frames diagrammatically.
this two links can help you to extract the gif image in android
http://www.basic4ppc.com/android/help/gifdecoder.html
http://code.google.com/p/loon-simple/source/browse/trunk/android/LGame-Android-0.2.6S/org/loon/framework/android/game/core/GIFDecoder.java?r=7
Definitely do it on the client side. Have you seen this? Splitting the animation into multiple images and rendering it on the client side with an AnimationDrawable may be the only way to go.
You will require to extend a view to make it to play .gif
Consider the following code
private class GifView extends View{
Movie movie;
InputStream in=null;
long moviestart;
Url url
public GifView(Context context,String downloadUrl) {
super(context);
this.url=new Url(downloadUrl);
URLConnection con = url.openConnection();
in=con.getInputStream()
movie=Movie.decodeStream(in);
}
#Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(Color.WHITE);
super.onDraw(canvas);
long now=android.os.SystemClock.uptimeMillis();
Log.v("tag","now="+now);
if (moviestart == 0) { // first time
moviestart = now;
}
Log.v("tag","\tmoviestart="+moviestart);
int relTime = (int)((now - moviestart) % movie.duration()) ;
Log.v("tag""time="+relTime+"\treltime="+movie.duration());
movie.setTime(relTime);
movie.draw(canvas,this.getWidth()/2-20,this.getHeight()/2-40);
this.invalidate();
}
}
Use This view in you xml and supply the url,
If network Latency is present download the gif in separate thread and supply the input stream to the constructor
Change it to
public GifView(Context context,InputStream in) {
super(context);
movie=Movie.decodeStream(in);
}