here i want to display a image logo which i am receiving from a sqlite as blob database when i dont have internet, though i know its a not a good practice but i want to make it simpler this way.
Problem i am facing is i am able to receive image in log but some warning (link below) is coming because of which it is not loading it into imageView.
Here's the warning i am getting in log !!
I am unable to figure out why it still running DownloadImageTask which is a async task even when not online that is isOnline()==false !!
ImageView logo = (ImageView)findViewById(R.id.Logo);
Bundle extras = getIntent().getExtras();
if(isOnline(this)==true);
{
String link = extras.getString("Logo1");
new DownloadImageTask(logo).execute(link);
}
if(isOnline(this)==false){
Log.d("offline","image");
Log.d("offline",extras.getByteArray("Logo2").toString());
//getting these ^^ in log
byte[] outImage=(byte[]) extras.getByteArray("Logo2");
if(outImage!=null)
{
ByteArrayInputStream imageStream = new ByteArrayInputStream(outImage);
Bitmap theImage = BitmapFactory.decodeStream(imageStream);
logo.setImageBitmap(theImage);
}
}
}
if(isOnline(this)==true)//you Superfluous add a ";" in this
{
String link = extras.getString("Logo1");
new DownloadImageTask(logo).execute(link);
}
i am a newbie,hope can help you
Related
I am learning Android dev. and am developping a Hearthstone app using a Hearthstone API for fun.
My users can search for specific cards and now I wish to implement a Card Displayer that displays cards by their type, and lets the user swipe right or left to display the next one in my JSONArray. My API request gives me one and each JSONObject has an img attribute with the cards image URL.
Therefore, when the user swipes I am doing the following:
// Swipe right -> number - 1 (Previous page)
// Swipe left -> number + 1 (Next page)
public void displayCardNumber(int number) {
APIRequests apiRequests = new APIRequests();
try {
// Gets the JSONObject at 'number' and retrieves its img URL.
JSONObject card = (JSONObject) cardsArray.get(number);
String currentImageURL = (String) card.get("img");
// Here is where my problem is.
Bitmap bitmap = apiRequests.getImageBitmap(currentImageURL);
if (bitmap != null) {
setNewImage(bitmap);
}
} catch (JSONException e) {
e.printStackTrace();
}
}
But apiRequest.getImageBitmap(URL) is where I have a problem.
I must download the image in order to display it, but not only does the following block of code not work when I download more than one image, I must also find an efficient way of displaying my cards (that requires background download perhaps?).
// Returns the image's bitmap using the URL
protected Bitmap getImageBitmap(String currentImageURL) {
try {
Bitmap bitmap = BitmapFactory.decodeStream((InputStream)new URL(currentImageURL).getContent());
return bitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
Why can't I download more than 1 image? Is my way of getting my Bitmap false?
Thank you.
Use Glide https://github.com/bumptech/glide .This is faster.
Bitmap theBitmap = Glide.
with(this).
load(imgUrl). //image url as string
asBitmap().
into(100, 100). // Width and height
get();
You can also use it with another way like this:
Glide.with(context).load(url) // image url
.thumbnail(0.5f)
.crossFade()
.diskCacheStrategy(DiskCacheStrategy.ALL)
.placeholder(imgId) // If no image found the imgId is the default image id for the imageView
.into(imageView); // imageView to show the image
I have found a solution,
In order to load my image and display it I now use a library called Android Universal Image Loader that lets me do the following:
// Load image, decode it to Bitmap and display Bitmap in ImageView
ImageLoader imageLoader = ImageLoader.getInstance();
ImageView i = (ImageView)view.findViewById(R.id.cardDisplay);
imageLoader.displayImage(currentImageURL, i);
I retrieve the correct URL in my AsyncTask's doInBackground and display it with the library's method.
I currently have an arraylist as follows:
private void loadImages() {
images = new ArrayList<>();
images.add(getResources().getDrawable(R.drawable.imag1));
images.add(getResources().getDrawable(R.drawable.imag2));
images.add(getResources().getDrawable(R.drawable.imag3));
}
I want to be able to convert a url into these drawables such that:
drawable1 = "http.someimage.com/image.png"
drawable2 = "http.someimage.com/newimage.png"
followed by
private void loadImages() {
images = new ArrayList<>();
images.add(getResources().getDrawable(drawable1));
images.add(getResources().getDrawable(drawable2));
...etc }
Is there any easy way to go around this? I definitely want to stick to drawables ,but I cant find any way to convert a url to drawable
Any ideas? Thanks!
If you have a URL of the picture you need to download it first.
You can't "convert" a URL into a drawable.
you need something like this:
URL url = new URL("http.someimage.com/image.png");
Bitmap bmp = BitmapFactory.decodeStream(url.openConnection().getInputStream());
Then if you need to add the image into an ImageView object you can call the method .setImageBitmap(bmp).
Otherwise there are ways to extract a Drawable object from the Bitmap
you can check this previous answer. then once you have the drawable you can add it to your arraylist.
Hope I got your question right
P.S.: be sure not to do this on main thread since it is a network operation! use a thread or an asynctask
I'm downloading files with my app via an API (this is working perfectly). Later in my app I'm doing a call to my database to get the file info: id, name, location and return it as a HashMap:
HashMap<Integer, ArrayList<String>> imgTitle;
I take the returned HashMap, extract the ArrayList and use that to populate some buttons. the array list holds the filename and file location. When the page loads the names display correctly but the images don't always load or one loads. If I go back and reenter the activity (via a button press) I'll get different images showing up. I've sent my array to the log and the file location is present and correct for all arrays. Why are only some image showing?
for (Map.Entry<Integer, ArrayList<String>> e : imgTitle.entrySet()) {
...
ArrayList<String> catList = e.getValue();
final String catTitle = catList.get(0);
File indexImage = new File(catList.get(1));
// add images
ImageButton imgButton = new ImageButton(this);
imgButton.setImageURI(Uri.fromFile(indexImage));
...
}
The above is inside a method called on the onCreate. My assumption is maybe the setImageURI is too slow? Any ideas?
Prior to using the setImageURI I used
imgButton.setImageResource(R.drawable.test_vehicle);
as a placeholder it was working fine. However, now I have to use a file that was downloaded and saved locally.
You could try to decode a Bitmap from a stream, like this:
File indexImage = new File(catList.get(1));
InputStream imageStream = new FileInputStream(indexImage);
Bitmap backgroundImage = null;
try {
backgroundImage = BitmapFactory.decodeStream(imageStream);
}
catch(Exception e) {
e.printStackTrace();
}
finally {
try {
//Dispose of the temporary resources
imageStream.close();
imageStream = null //So that the stream is deleted on next GC
}
catch(IOException e) {
e.printStackTrace();
}
}
if (backgroundImage != null) {
ImageButton imgButton = new ImageButton(this);
imgButton.setImageBitmap(backgroundImage);
backgroundImage.recycle();
}
Note: This is pure speculation, I haven't tested any of this. It's simply the first solution that came to my mind
I have an image url I parse form json that I want to load into an android widget onto the homescreen. Right now I am trying to do it this way but its wrong:
ImageDownloadTask imageD = new ImageDownloadTask(image);
views.setImageViewBitmap(R.id.image, imageD.execute(image));
image is a string holding a url to an image that needs to be downloaded and I am trying to set it to R.id.image
I found another stack question and tried this as a result:
views.setBitmap(R.id.image, "setImageBitmap",BitmapFactory.decodeStream(new URL(image).openStream()));
And when I use that nothing in the app loads at all, none of the text views get set.
My third try was this:
//get beer data
JSONObject o = new JSONObject(result);
String name = getName(o);
String image = getImage(o);
String abv = getABV(o);
String ibu = getIBU(o);
String glass = getGlass(o);
String beerBreweryName = getBreweryName(o);
String beerBreweryStyle = getBreweryStyle(o);
String beerDescription = getDescription(o);
InputStream in = new java.net.URL(image).openStream();
Bitmap bitmap = BitmapFactory.decodeStream(in);
views.setTextViewText(R.id.beerTitle, name);
views.setTextViewText(R.id.beerBreweryName, beerBreweryName);
views.setTextViewText(R.id.beerStyleName, beerBreweryStyle);
views.setImageViewBitmap(R.id.image, bitmap);
This gave the same result as the last attempt, it would not even set any text views....
Just tried another attempt after one of the answers posted below:
RemoteViews views = new RemoteViews(c.getPackageName(), R.layout.widget_test);
//get beer data
JSONObject o = new JSONObject(result);
String name = getName(o);
String imageURL = getImage(o);
String abv = getABV(o);
String ibu = getIBU(o);
String glass = getGlass(o);
String beerBreweryName = getBreweryName(o);
String beerBreweryStyle = getBreweryStyle(o);
String beerDescription = getDescription(o);
Log.d("widgetImage" , imageURL);
views.setImageViewUri(R.id.image, Uri.parse(imageURL));
views.setTextViewText(R.id.beerTitle, name);
views.setTextViewText(R.id.beerBreweryName, beerBreweryName);
views.setTextViewText(R.id.beerStyleName, beerBreweryStyle);
mgr.updateAppWidget(appWidgetIds, views);
This attempt lets all the text views load, but no image ever shows up.
The way to do this reliably is to use setImageViewURI on the remote ImageView. The trick is that the URI you give it is a content:// URI which then points back to a content provider that you export from your application. In your content provider you can do anything you need to do to supply the image bytes.
For example, in your manifest:
<provider android:name=".ImageContentProvider" android:authorities="com.example.test" android:exported="true" />
And your provider:
public class ImageContentProvider extends ContentProvider {
// (Removed overrides that do nothing)
#Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
List<String> segs = uri.getPathSegments();
// Download the image content here, get the info you need from segs
return ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY);
}
}
And then your URL is something like:
content://com.example.test/something-you-can-define/here
This is necessary because your remote image view is not running in your process. You are much more limited in what you can do because everything must be serialized across the process boundary. The URI can serialize just fine but if you try to send a megabyte of image data with setImageViewBitmap, it's probably going to fail (depending on available device memory).
Got a lot of help from multiple sources for this question. The big problem for me why a bunch of the attempts I tried listed above seemed to lock the widget app and not load anything is because I can not download the image and set it in a UI thread.
To accomplish this I had to move everything to the do in background of my async task and not in the onPostExecute.
The problem
Hi there,
I'm developing an application where the user specifies some pictures and how long they are going to be on the screen.So sometimes he wants to create something like a small animation or viewing the images for a small amount of time.The problem is that after some time the images are not previewed when they should and we have a few ms of error.In the application that i'm developing time matters so I would like some help on what the problem might be.
The code
So let me explain how it works.I take the pictures from my web app and then I save them in a HashMap
Bitmap image = ImageOperations(url,String.valueOf(frameNum) + ".jpg");
ImageMap.put(String.valueOf(frameNum), image);
where the mathod ImageOperations is like that:
private Bitmap ImageOperations(String url, String saveFilename) {
try {
Display display = getWindowManager().getDefaultDisplay();
InputStream is = (InputStream) this.fetch(url);
Bitmap theImage = BitmapFactory.decodeStream(is);
if (theImage.getHeight() >= 700 || theImage.getWidth() >= 700) {
theImage = Bitmap.createScaledBitmap(theImage,
display.getWidth(), display.getHeight() - 140, true);
}
return theImage;
} catch (MalformedURLException e) {
e.printStackTrace();
return null;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
So later I run a thread that updates the UI when the user specified.The method that updates it is this one.
public void setPictures(int NumOfFrame) {
if (frameArray.get(NumOfFrame - 1).frame_pic.contains("n/a") != true) {
ImagePlace.setImageBitmap(ImageMap.get(String.valueOf(NumOfFrame)));
} else {
ImagePlace.setImageDrawable(null);
}
}
After we update the image we put the thread for sleep and when runs again it updates the thread.Is there something that creates the problem?Does it have to do with Garbage collection?
Thank you in advance
Probably the issue is in increasing heap size when it loads additional images. I would suggest You to do some profiling so things will be much clearer and You'll get full picture of timings for the app.
First you are missing a null check at here:
ImageMap.get(String.valueOf(NumOfFrame))
And you do not recycle the old bitmap at here:
theImage.recycle(); // missing line
theImage = Bitmap.createScaledBitmap(theImage,
display.getWidth(), display.getHeight() - 140, true);
It may lead to outofmemory exceptions, with is most likely from your description of the problem.
Also I am not sure if BitmapFactory.decodeStream throw exception when he fails. You need to add a null point check there too.