I have an Image on my server. The URL for the image is something like:
http://www.mydomain.com/123456uploaded_image.jpg
I am trying to set this image to my ImageView. Here is the code that I tried:
try{
String url1 = myeventimagearray[position];
URL ulrn = new URL(url1);
HttpURLConnection con = (HttpURLConnection)ulrn.openConnection();
InputStream is = (InputStream) con.getInputStream();
Bitmap bmp = BitmapFactory.decodeStream(is);
if (null != bmp)
iveventimg.setImageBitmap(bmp);
else
Log.i("Image","Not set");
} catch(Exception e) {
e.printStackTrace();
}
When I try this, my imageview is empty, i.e., it doesn't set the image view and i get this System err in my logcat:
java.lang.ClassCastException: libcore.net.http.FixedLengthInputStream cannot be cast to com.example.eventnotifier.Base64$InputStream
Base46.java is a file I found from the internet that Encodes and decodes to and from Base64 notation.
Any idea why I'm getting this System.error?
Thank you
Use URlImageViewHelper, it will take care of loading url into imageview.
Refer this
It will take care of caching, loading in background etc. by itself.
This is not an easy answer but you should use a caching system.
See https://github.com/chrisbanes/Android-BitmapCache for an excellent one!
Simply swap the ImageView for NetworkCacheableImageView and then use loadImage( "http://....", true );
You are likely getting an exception because you are trying to do network io on the main thread. Consider using a loader or an AsyncTask to load your image.
Check your logs, I bet you are printing a stack trace in the auto generated catch block.
new Thread(new Runnable() {
public void run() {
final Bitmap b = bitmap = BitmapFactory.decodeStream((InputStream)new URL(myeventimagearray[position]).getContent());
iveventimg.post(new Runnable() {
public void run() {
iveventimg.setImageBitmap(b);
}
});
}
}).start();
Use Picasso to fetch image from url. Implement 'com.squareup.picasso:picasso:2.71828' in build.gradle and in java
Picasso.get()
.load(url) // http://www.example.com/123456uploaded_image.jpg
.resize(50, 50)
.centerCrop()
.into(imageView)
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'm downloading an image from a URL and displaying it in an ImageView. I need to download the image at its full original size. I've tried Glide, Picasso and Universal Image Loader with no success. Is there any library or mehod out there to achieve this? I even tried making my own AsyncTask to do it, something like this:
public class ImageLoader extends AsyncTask<Void, Void, Bitmap> {
#Override
protected Bitmap doInBackground(Void... params) {
try {
URL url = new URL(bundle.getString("selectedImage"));
HttpURLConnection conn =
(HttpURLConnection)url.openConnection();
conn.setReadTimeout(6000);
conn.setConnectTimeout(6000);
conn.setRequestMethod("GET");
conn.setDoInput(true);
conn.connect();
int respose = conn.getResponseCode();
InputStream is = conn.getInputStream();
BufferedInputStream bufferedInputStream = new
BufferedInputStream(is);
bitmap = BitmapFactory.decodeStream(bufferedInputStream);
return bitmap;
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
but no success. Anyone have anything to help me?
1) Try to use Volley library.
https://developer.android.com/training/volley/request.html#request-image
2) Use WebView instead ImageView
I'm not really sure what you mean by "its full original size". I haven't experienced any automagic scaling of images simply by downloading them.
Maybe you could double-check that you have an appropriate android:scaleType on the target ImageView. You can read more on the different values of the scale type property here: http://developer.android.com/reference/android/widget/ImageView.ScaleType.html
If you want to pan the image, like an "unscaled" web page in the browser (typically when the image is bigger than the screen), you might need to add further logic to manage this. Maybe it could be as easy as having a ScrollView wrap your ImageView (which then would wrap its content, of course).
The error was down to photo bucket giving me a scaled down URL instead I used flikr and on my device I get an image almost identical to my original (Picasso limit is 2048x2048) but on other devices I still seem to get a 1080 x 910 image, will investigate further but it seems the answer is not to use photo bucket
Question 1: Is it possible to download image file without giving the reference to ImageView?
Question 2: Can i download each file in a separage instance of aQuery or do i have to download the file sequentially? e.g, waiting for the callback of current file download and then trigger the next file download call? Below is my code
// Ad is my custom model class
// adList is my list of Ads having URL's to the ads hosted somewhere
// imageView is an invisible imageView as downloading does not start if i don't give any reference to any imageView resource
for (String adUrl : adList) {
if (adUrl.length() > 0) {
AQuery aQuery = new AQuery(DownloadAdActivity.this);
BitmapAjaxCallback callback = new BitmapAjaxCallback();
callBack.url(adUrl);
callBack.fallback(R.id.placeHolderResource);
callBack.fileCache(true);
callBack.memCache(true);
aQuery.id(imageView).image(callBack);
}
}
I need to download 20/30 images when the app starts first time, so far i am doing it by giving a hidden imageView reference and trigging the aQuery sequentially after each image has downloaded. I tried to generate 20/30 request in a loop but only the last aQuery trigger call works which cancels the previous image download call.
Please guide me:
1- How to cache images without giving any reference to the imageView
2- How to download images in parallel manner, not in sequential manner through AQuery.
1) You can use ajax call without ImageView reference to download image.
androidQuery.ajax("url", Bitmap.class, 0, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap bitmap, AjaxStatus status) {
super.callback(url, bitmap, status);
}
});
2) By default you can download 4 images concurrently. But you can change as per your requirement like this
AjaxCallback.setNetworkLimit(8);
You can use Picasso
It will make all the downloads and also the caching for the images.
Anyway if the images are quite small you should prepare a "zip" file and dl all of them with an AsyncTask / Thread and unzip them. Opening and closing the connections to the server are "very expensive" operations in time consuming.
Here is method to obtain bitmap from url using AQuery
static Bitmap myBitmap = null;
public static Bitmap getBitmapFromURL(String src) {
try {
Log.i(TAG, "Image Url is : " + src);
AQuery androidQuery = new AQuery(ChatApplication.getInstance());
androidQuery.ajax(src, Bitmap.class, 0, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap bitmap, AjaxStatus status) {
super.callback(url, bitmap, status);
if (bitmap != null)
myBitmap = bitmap;
}
});
} catch (Exception e) {
Log.i(TAG, "Error due to " + e);
}
return myBitmap;
}
AQuery aq = new AQuery(context);
aq.ajax(url_of_image, Bitmap.class, new AjaxCallback<Bitmap>() {
#Override
public void callback(String url, Bitmap object, AjaxStatus status) {
}
});
Im sorry for replying late,But this is best library I have ever came across.
Yes,You can download. Bitmap object will give you the image.
You can create multiple instances of Aquery if you want to download or pass the each URL after one download finishes,you can use any loop for that.
I have an app where I have one banner in the top with News, when I want to put other news I need to open the code and change the resource .jpg and the Link. There is a way to change the banner and the Link (or at least the banner) without modifing the code? Idk maybe uploading it to a webpage or something like this.
thanks
My suggestion would be to upload a banner.jpg to a server that your app can access and dynamically load. This would prevent having to update your app every time you want to change the banner, and makes it cleaner (no excessive Google Play updates). To do actually load the image you can use this code:
ImageView image1 = (ImageView) findViewById(R.id.mybanner);
new Thread(new Runnable(){//create a new thread so we can do network operations
#Override
public void run() {//main thread function
try {//attempt to do network stuff
URL url = new URL("http://your-hosting-site.com/banner.jpg");//create aURL object with the path to your banner
HttpURLConnection con = (HttpURLConnection) url.openConnection();//create the connection object from the url
con.setReadTimeout(15000);
con.setConnectTimeout(15000);
con.setRequestMethod("GET");
con.setDoInput(true);
con.connect();//connect to the server
InputStream is = con.getInputStream();//get the stream so we can read the image
Drawable d = Drawable.createFromStream(is, "MyBanner");//create a drawable from the image
Bitmap bmp = ((BitmapDrawable) d).getBitmap();//create a bitmap from the drawable
final Drawable dS = new BitmapDrawable(Bitmap.createScaledBitmap(bmp, 192, 192, true));//scale it to whatever size you need
con.disconnect();//disconnect now that we're done
runOnUiThread(new Runnable(){//run UI update code on the main thread
#Override
public void run() {
image1.setImageDrawable(dS);//set the imageview to the banner we downloaded
}
});
} catch (MalformedURLException e) {//catch url error
e.printStackTrace();
} catch (IOException e) {//catch io error when downloading
e.printStackTrace();
}
}
}).start();//run the thread
Change "http://your-hosting-site.com/banner.jpg" (line 6) to wherever you uploaded the .jpg, R.id.mybanner (line 1) to the id of your ImageView, and "MyBanner" (line 14) to whatever you want to call the image.
You might want to save your banner to the phone and only check after X days/hours for an update to save data, but that is up to you.
I am having trouble loading a bitmap from a url on Android based on this answer: https://stackoverflow.com/a/8993175/1062794
I've simplified the case to the absolute minimum:
public void loadBitmap(View view) {
Bitmap b = getBitmapFromURL("http://upload.wikimedia.org/wikipedia/en/7/70/Example.png");
}
public Bitmap getBitmapFromURL(String src) {
try {
URL url = new URL(src);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
Bitmap myBitmap = BitmapFactory.decodeStream(input);
return myBitmap;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
I have enabled internet access in manifest (I believe):
<uses-permission android:name="android.permission.INTERNET"/>
When I run the app it crashes with null details when it tries to run connection.connect(). Stepping through I see it tries to throw this error from StrictMode.class:
if ((mPolicyMask & PENALTY_DEATH_ON_NETWORK) != 0) {
throw new NetworkOnMainThreadException();
}
This is my first day trying to make an Android app so I could be making an obvious mistake. I am using the emulator and Win7.
Starting with Android 3.0, synchronous operations can no longer be run directly from a UI thread. If you try to call the loadBitmap(View view) method directly in your onCreate() method, your application will crash when it is run on a device running Android 3.0 and later. Because loadBitmap() method is synchronous - that is, it will not return control until the image is downloaded - calling it directly will freeze the UI of your activity. This is not allowed in Android 3.0 and later; all synchronous code must be wrapped using an AsyncTask class. Using AsyncTask enables you to perform background tasks in a separate thread and then return the result in a UI thread. That way, you can perform background operations without needing to handle complex threading issues. To call the loadBitamp() method asynchronously, you need to wrap the code in a subclass of the AsyncTask class, as shown here:
private class DownloadImage extends AsyncTask<String, Void, Bitmap> {
protected Bitmap doInBackground(String... urls) {
return getBitmapFromUrl(urls[0]);
}
protected void onPostExecute(Bitamp result) {
ImageView img = (ImageView) findViewById(R.id.img);
img.setImageBitmap(result);
}
}
Now in the onCreate() method create a new instance of AsyncTask class and execute it:
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new DownloadImage().execute("http://upload.wikimedia.org/wikipedia/en/7/70/Example.png");
}
this is because you are trying to access the internet from the ui thread (more info here) .
create a new thread (you can use an asyncTask if you wish, but any other thread creation method would suffice) in order to access the internet , and once the bitmap is ready , pass it to the ui thread if you wish to show it
also , for a nice sample of bitmap handling read this :
http://developer.android.com/training/displaying-bitmaps/index.html
Your void will crash when image size big 5 MG. Bitmap are stacking RAM so sample 20 images * 5 = 100 mb. When you re open activity another 100 mb spend your RAM and app will crash. You add follow lines your code;
BitmapFactory.Options options = new BitmapFactory.Options();
options.inPreferredConfig = Config.RGB_565;
options.inSampleSize = 2;
Bitmap myBitmap = BitmapFactory.decodeStream(input,rect,options);