How to update ListViev with image from url
To download image I'm using:
downloadImage
public static Bitmap downloadImage(String iUrl) {
Bitmap bitmap = null;
HttpURLConnection conn = null;
BufferedInputStream buf_stream = null;
try {
Log.v(TAG, "Starting loading image by URL: " + iUrl);
conn = (HttpURLConnection) new URL(iUrl).openConnection();
conn.setDoInput(true);
conn.setRequestProperty("Connection", "Keep-Alive");
conn.connect();
buf_stream = new BufferedInputStream(conn.getInputStream(), 8192);
bitmap = BitmapFactory.decodeStream(buf_stream);
buf_stream.close();
conn.disconnect();
buf_stream = null;
conn = null;
} catch (MalformedURLException ex) {
Log.e(TAG, "Url parsing was failed: " + iUrl);
} catch (IOException ex) {
Log.d(TAG, iUrl + " does not exists");
} catch (OutOfMemoryError e) {
Log.w(TAG, "Out of memory!!!");
return null;
} finally {
if ( buf_stream != null )
try { buf_stream.close(); } catch (IOException ex) {}
if ( conn != null )
conn.disconnect();
}
return bitmap;
}
My ListView listen when button clicked, and then update ListView
try{
JSONObject jsonResponse = new JSONObject(response.toString());
JSONArray jsonMainNode = jsonResponse.getJSONArray("items");
//JSONArray Data = jsonResponse.getJSONArray("snippet");
for(int i = 0; i<jsonMainNode.length();i++){
JSONObject jsonChildNode = jsonMainNode.getJSONObject(i);
String name = jsonChildNode.optString("kind");
String number = jsonChildNode.optString("etag");
JSONObject item = jsonMainNode.getJSONObject(i);
JSONObject snippet = item.getJSONObject("snippet");
String title = snippet.getString("title");
String channelTitle = snippet.getString("channelTitle");
String pubDate = snippet.getString("publishedAt");
JSONObject thumbs = snippet.getJSONObject("thumbnails");
JSONObject thumb = thumbs.getJSONObject("default");
final String ico = thumb.getString("url");
new Thread(new Runnable() {
public void run() {
bmp = ImageManager.downloadImage(ico);
}
}).start();
countryList.add(createEmployee(title,channelTitle,pubDate, bmp));
}
simpleAdapter.notifyDataSetChanged();
ListView Updting, but without image. If Im using Image from #drawable all its ok.
The problem is that the bitmap hasn't finished being downloaded before you try to use it. When you call start() on a thread instance, that method returns immediately on the thread it was called on, while the new thread goes off and executes the run method (its own or that of the Runnable provided as a constructor parameter).
As start() returns immediately, you go straight on to create the employee before the bitmap has downloaded. As a result, bmp is null and there's no image to display.
You need to set up your code so that once an image is downloaded it is set on the appropriate view.
Related
I am trying to save data into a text file that does not yet exist online, but my urlConnection.getResponseCode() is returning a 404. I can read from files with similar urls, so I'm pretty certain the url is correct, but I've never written to an online file before.
private class SaveFile extends AsyncTask<String, Void, String> {
private String scheme = "http";
private String authority = "172.16.0.45";
private String path1 = "PrivateFile";
private String path2 = "SavedInstances";
protected void onPreExecute() {
}
protected String doInBackground(String...params) {
String result = null;
String filename = params[0] + ".txt";
String location = params[1];
OutputStream outStream = null;
HttpURLConnection urlConnection = null;
try {
// Save online as opposed to internal storage
if (location.equals("on")) {
Uri.Builder builder = new Uri.Builder();
builder.scheme(scheme);
builder.authority(authority);
builder.appendPath(path1);
builder.appendPath(path2);
builder.appendPath(filename);
String _url = builder.build().toString();
URL url = new URL(_url);
urlConnection = (HttpURLConnection) url.openConnection();
urlConnection.setDoOutput(true);
urlConnection.setRequestMethod("POST");
if (urlConnection.getResponseCode() != 200) // Runs as true
throw new IOException(Integer.toString(urlConnection.getResponseCode()));
else {
outStream = urlConnection.getOutputStream();
}
} else if (location.equals("in")) {// Saving to internal
File file = new File(getFilesDir(), filename);
outStream = new FileOutputStream(file);
}
// Writing the file
PrintWriter writer = new PrintWriter(outStream);
writer.println(utils.size());
writer.println(trans.size());
writer.println(cables.size());
for (int i = 0; i < utils.size(); i++)
writer.println(utils.get(i).getValues());
for (int i = 0; i < trans.size(); i++)
writer.println(trans.get(i).getValues());
for (int i = 0; i < cables.size(); i++)
writer.println(cables.get(i).getValues());
writer.close();
outStream.close();
if (urlConnection != null)
urlConnection.disconnect();
result = "Save Successful";
} catch (FileNotFoundException e) {
System.out.println(e.getMessage());
} catch (MalformedURLException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
result = e.getMessage();// 404
System.out.println(e.getMessage());
}
return result;
}
protected void onPostExecute(String result) {
Toast.makeText(getApplicationContext(),result,Toast.LENGTH_SHORT).show();
}
}
When I send the exception with getResponseMessage() instead, the message is "not found". What am I missing to get this connection working?
The docs say AsyncTask is designed to handle short operations(few seconds maximum) and states that Java classes like FutureTask are better for operations that last long. So I tried to send my location updates to the server using FutureTask but I am getting NetworkOnMainThreadException. I don't want to use AsyncTask because I wanted to keep the http connection open until the updates are cancelled. Here is my code:
SendLocation updates = new SendLocation(idt, String.valueOf(location.getLatitude()), String.valueOf(location.getLongitude()));
FutureTask ft = new FutureTask<String>(updates);
boolean b = ft.cancel(false);
ft.run();
class SendLocation implements Callable<String> {
String t, la, lo;
public SendLocation(String a, String b, String c){
this.t = a;
this.la = b;
this.lo = c;
}
public String call() {
sendUpdates(token, la, lo);
return "Task Done";
}
public void sendUpdates(String a, String b, String c){
HttpURLConnection urlConn = null;
try {
try {
URL url;
//HttpURLConnection urlConn;
url = new URL(remote + "driver.php");
urlConn = (HttpURLConnection) url.openConnection();
System.setProperty("http.keepAlive", "true");
//urlConn.setDoInput(true); //this is for get request
urlConn.setDoOutput(true);
urlConn.setUseCaches(false);
urlConn.setRequestProperty("Content-Type", "application/json");
urlConn.setRequestProperty("Accept", "application/json");
urlConn.setRequestMethod("POST");
urlConn.connect();
try {
//Create JSONObject here
JSONObject json = new JSONObject();
json.put("drt", a);
json.put("drlat", b);
json.put("drlon", c);
String postData = json.toString();
// Send POST output.
OutputStreamWriter os = new OutputStreamWriter(urlConn.getOutputStream(), "UTF-8");
os.write(postData);
Log.i("NOTIFICATION", "Data Sent");
os.flush();
os.close();
BufferedReader reader = new BufferedReader(new InputStreamReader(urlConn.getInputStream()));
String msg = "";
String line = "";
while ((line = reader.readLine()) != null) {
msg += line;
}
Log.i("msg=", "" + msg);
} catch (JSONException jsonex) {
jsonex.printStackTrace();
Log.e("jsnExce", jsonex.toString());
}
} catch (MalformedURLException muex) {
// TODO Auto-generated catch block
muex.printStackTrace();
} catch (IOException ioex) {
ioex.printStackTrace();
try { //if there is IOException clean the connection and clear it for reuse(works if the stream is not too long)
int respCode = urlConn.getResponseCode();
InputStream es = urlConn.getErrorStream();
byte[] buffer = null;
int ret = 0;
// read the response body
while ((ret = es.read(buffer)) > 0) {
Log.e("streamingError", String.valueOf(respCode) + String.valueOf(ret));
}
// close the errorstream
es.close();
} catch(IOException ex) {
// deal with the exception
ex.printStackTrace();
}
}
} catch (Exception e) {
e.printStackTrace();
Log.e("ERROR", "There is error in this code " + String.valueOf(e));
}
}
}
Doesn't it get executed in a worker thread? If the answer is no why does the docs say that it is an alternative to AsyncTask?
Your code must not be in the void run() method. This is where the asynchronous code is ran.
I have this codes to get Bing's photo of the day and set it as background.it works fine but I have some feelings that It's not the best way.
get json and return string :
private String GetHTTPData() {
try {
URL url = new URL(urlString);
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
if (urlConnection.getResponseCode() == 200) {
InputStream in = new BufferedInputStream(urlConnection.getInputStream());
BufferedReader r = new BufferedReader(new InputStreamReader(in));
StringBuilder sb = new StringBuilder();
String line;
while ((line = r.readLine()) != null) {
sb.append(line);
}
stream = sb.toString();
urlConnection.disconnect();
} else {
}
} catch (MalformedURLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
}
if (stream != null) {
try {
JSONObject jsonObject = new JSONObject(stream);
JSONArray jArray = jsonObject.getJSONArray("images");
for (int i = 0; i < jArray.length(); i++) {
JSONObject jsonobject = jArray.getJSONObject(i);
imageURL = "http://www.bing.com" + jsonobject.getString("url");
}
} catch (Exception e) {
e.printStackTrace();
}
}
//I replaced the original resolution with mine to change the image url
imageURL=imageURL.replace("1920x1080","1080x1920");
return imageURL;
}
default value for image is 1920x1080 and I was able to get more phone friendly image by replacing dimensions, but I'm not sure if 1080x1920 is the best one.
and then my AsyncTask
private class setWallpaper extends AsyncTask<Void,Void,Bitmap>{
#Override
protected Bitmap doInBackground(Void... strings) {
int response=-1;
InputStream in=null;
Bitmap bitmap=null;
String stream=GetHTTPData();
try {
URL url = new URL(stream);
URLConnection connection =url.openConnection();
HttpURLConnection urlConnection=(HttpURLConnection)connection;
urlConnection.setAllowUserInteraction(false);
urlConnection.setInstanceFollowRedirects(true);
urlConnection.setRequestMethod("GET");
urlConnection.connect();
response=urlConnection.getResponseCode();
if (response==HttpURLConnection.HTTP_OK){
in=urlConnection.getInputStream();
}
bitmap= BitmapFactory.decodeStream(in);
in.close();
}catch (Exception e){
return null;
}
//I dont like to scale my bitmap but on lower resolution i cant get full width image
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
Point size = new Point();
display.getSize(size);
int width = size.x;
int height = size.y;
Bitmap bitmapTouse=Bitmap.createScaledBitmap(bitmap,width,height,true);
bitmap.recycle();
return bitmapTouse;
}
#Override
protected void onPostExecute(Bitmap bitmap) {
System.gc();
WallpaperManager manager=WallpaperManager.getInstance(context.getApplicationContext());
try {
manager.setBitmap(bitmap);
Log.d("SUCCESS----", "Finished");
} catch (IOException e) {
Log.d("FAILED----",e.getMessage());
}
}
}
I also don't like to scale my bitmap image but I had to.
I'm getting a twitter feed in my Android Studio app, using Fabric
for each tweet that has an image attactched, I wish to display the image
how can I extract either a url to the image or a byte[]?
I have found what looks like an array of bytes, but when I attempt to decode it using bitmaps decodeByteArray, it returns null
String mediaString = t.entities.media.toString();
String[] mediaArray = mediaString.split("(?=#)");
byte[] mediaBytes = mediaArray[1].getBytes();
can anybody help me find a way to retrieve the image so I can display it?
Image url
String mediaImageUrl = tweet.entities.media.get(0).url;
Bitmap mediaImage = getBitmapFromURL(mediaImageUrl);
Bitmap mImage = null;
Decode the image
private Bitmap getBitmapFromURL(final String mediaImageUrl) {
try {
Thread t = new Thread() {
public void run() {
try {
URL url = new URL(mediaImageUrl);
HttpURLConnection connection = (HttpURLConnection) url.openConnection();
connection.setDoInput(true);
connection.connect();
InputStream input = connection.getInputStream();
BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
mImage = BitmapFactory.decodeStream(input, null, options);
} catch (Exception e) {
e.printStackTrace();
}
}
};
t.start();
} catch (Exception e) {
e.printStackTrace();
}
return mImage;
}
i am getting image only if it is available like:
String mediaImageUrl = null;
if (tweet.entities.media != null) {
String type = tweet.entities.media.get(0).type;
if (type.equals("photo")) {
mediaImageUrl = tweet.entities.media.get(0).mediaUrl;
}
else {
mediaImageUrl = "'";
}
System.out.println("mediaImageUrl" + mediaImageUrl);
}
If u using type attributes u can easily differentiates image/video from userTimeLine
I have a text file on a server (right now on a local server by WAMP in c:/wamp/www/android/sample.txt ) and an android application with 3 activity that read data through the WiFi.
The first one get the address (on local host use 10.0.2.2/android/sample.txt) and go to activity2. In activity2 I have a button that goes to activity3.
code is third activity:
private InputStream OpenHttpConnection(String urlString) throws Exception {
InputStream in = null;
int response = -1;
URL url = new URL(urlString);
URLConnection conn = url.openConnection();
if (!(conn instanceof HttpURLConnection)) {
throw new IOException("NOT an HTTP Connection!");
}
try {
HttpURLConnection httpCon = (HttpURLConnection) conn;
httpCon.setAllowUserInteraction(false);
httpCon.setInstanceFollowRedirects(true);
httpCon.setRequestMethod("GET");
httpCon.connect();
response = httpCon.getResponseCode();
if (response == HttpURLConnection.HTTP_OK) {
in = httpCon.getInputStream();
Log.d("myerr", response + "");
}
} catch (Exception e) {
Log.d("myerr2", e.getLocalizedMessage());
throw new IOException("Error Connection!");
}
return in;
}
private String DownloadText(String URL) {
int BUFFER_SIZE = 2000;
InputStream in = null;
try {
in = OpenHttpConnection(URL);
} catch (Exception e) {
Log.d("myerr", e.getLocalizedMessage());
return "";
}
InputStreamReader isr = new InputStreamReader(in);
int charRead;
String str = "";
char[] inputBuffer = new char[BUFFER_SIZE];
try {
while ((charRead = isr.read(inputBuffer)) > 0) {
String readString = String
.copyValueOf(inputBuffer, 0, charRead);
str += readString;
inputBuffer = new char[BUFFER_SIZE];
}
in.close();
} catch (Exception e) {
Log.d("myerr", e.getLocalizedMessage());
return "";
}
return str;
}
private class DownloadTextTask extends AsyncTask<String, Void, String> {
protected String doInBackground(String... urls) {
return DownloadText(urls[0]);
}
protected void onPostExecute(String result) {
Global.readedDataFromFile=result;
//Toast.makeText(DrawRhActivity.this,"Result: "+Global.readedDataFromFile, Toast.LENGTH_LONG).show();
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_draw_rh);
String user_address = Global.ip_address;
new DownloadTextTask().execute(user_address);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("Value: " + Global.readedDataFromFile);
}
I also define some global variable in Global.java .
AND HERE IS MY PROBLEM:
The 3rd activity doesn't show data on textview at the first time. but when I back to 2nd activity and hit the button my data loaded.
Why AsyncTask doesn't show result first time and how to fix this?
Thanks for your attention.
tv.setText("Value: " + Global.readedDataFromFile);
write this line in onPostExecute
protected void onPostExecute(String result) {
Global.readedDataFromFile=result;
//Toast.makeText(DrawRhActivity.this,"Result: "+Global.readedDataFromFile, Toast.LENGTH_LONG).show();
tv.setText("Value: " + Global.readedDataFromFile);
}
Solution:
put tv.setText("Value: " + Global.readedDataFromFile); in your onPostExecute method.
Explaination:
AsyncTask runs on separate thread instead of your UI thread.
so when it is being executed Global.readedDataFromFile may be empty.and when execution completes it goes in onPostExecute method and now Global.readedDataFromFile have some value stored in it.
Issue:
you are setting the text instantly after calling new DownloadTextTask().execute(user_address);
so it may happen that the AsyncTask is not completed yet and Global.readedDataFromFile is empty.
Reference:
AsyncTask
I hope it will be helpful !!
the problem lies within your onCreate function:
String user_address = Global.ip_address;
new DownloadTextTask().execute(user_address);
tv = (TextView) findViewById(R.id.textView1);
tv.setText("Value: " + Global.readedDataFromFile);
First you start a task, then you want to set your views, but your task is not finished.
You have to set the views with the result of your task in to onPostExecute of the task.
Keep your DownloadTextTask &
Trying this code in your Activity
DownloadTextTask textTask = new DownloadTextTask();
textTask.execute(user_address);
String strDownloaded = "";
try {
strDownloaded = textTask.get();
} catch (Exception e) {
Log.e("DownloadTextTask", "Error: " + e.getMessage());
}