1

This is my attempt. My files are hosted on my own servers mostly JPGs files. I'm trying to download them into my app. I failed to generate those images into my app. I follow the guide from this blog http://getablogger.blogspot.gr/2008/01/android-download-image-from-server-and.html

My xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView 
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World, HTTPImage load test"
/>
<Button android:id="@+id/get_imagebt"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Get an image"
android:layout_gravity="center"
/> 
<ImageView android:id="@+id/imview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>

Coding

package com.example.downloadimages;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;




public class MainActivity extends Activity {

    ImageView imView;
    String imageUrl="http://myfilehosting.com/";
    Random r;


    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        r= new Random();

        Button bt3= (Button)findViewById(R.id.get_imagebt);
        bt3.setOnClickListener(getImgListener);
        imView = (ImageView)findViewById(R.id.imview);
    }

    View.OnClickListener getImgListener = new View.OnClickListener()
    {

        public void onClick(View view) {
        // TODO Auto-generated method stub

        //i tried to randomize the file download, in my server i put 4 files with name like
        //jpg0.jpg, jpg1.jpg, jpg2.jpg so different file is downloaded in button press
        int i =r.nextInt()%4;
        downloadFile(imageUrl+i+".jpg");

        }

        Bitmap bmImg;
        void downloadFile(String fileUrl){
        URL myFileUrl =null; 
        try {
        myFileUrl= new URL(fileUrl);
        } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }
        try {
        HttpURLConnection conn= (HttpURLConnection)myFileUrl.openConnection();
        conn.setDoInput(true);
        conn.connect();
        int length = conn.getContentLength();
        int[] bitmapData =new int[length];
        byte[] bitmapData2 =new byte[length];
        InputStream is = conn.getInputStream();

        bmImg = BitmapFactory.decodeStream(is);
        imView.setImageBitmap(bmImg);
        } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        }





};
};
}
KC Chai
  • 1,607
  • 9
  • 30
  • 59
  • You need to use an `AsyncTask` to do this. Read [the Android documentation on it](http://developer.android.com/reference/android/os/AsyncTask.html) and see this [one of many, many SO solutions](http://stackoverflow.com/questions/3090650/android-loading-an-image-from-the-web-with-asynctask). – Ken Y-N Jul 26 '12 at 06:05

1 Answers1

1

there are several problems with your code:

  • you are trying to perform network operation (download file from remote server) from the UI thread. network operation must be executed from another thread. otherwise - exception been thrown.

one of the ways to launch the code from another thread is:

new Thread(new Runnable() {

        @Override
        public void run() {
            downloadFile(imageUrl+i+".jpg");
        }
    }).start();

better approach would be using AsyncTask or IntentService (which also performing the code on separate thread)

  • second thing - you can't just create int array with the size of the input stream: if the image is too big, it can fail. try break the download to segments with fixed size (say 2058 bytes each segment) for example:

    private HttpURLConnection conn;
    private InputStream stream;
    private FileOutputStream out;
    
    private double fileSize;
    private double downloaded;
    
    
    public void downloadFile(String fileURL, String fileName) {
    try {
    
        conn = (HttpURLConnection) new URL(fileURL).openConnection();
        fileSize = conn.getContentLength();
        File file = new File(fileName);
    
        out = new FileOutputStream(file);
        conn.connect();
    
        stream = conn.getInputStream();
    
        while (status == DOWNLOADING) {
            byte buffer[];
    
            if (fileSize - downloaded > MAX_BUFFER_SIZE) {
                buffer = new byte[MAX_BUFFER_SIZE];
            } else {
                buffer = new byte[(int) (fileSize - downloaded)];
            }
            int read = stream.read(buffer);
    
            if (read == -1) {
    
                out.close();
                if (conn != null) {
                    conn.disconnect();
                }
    
                break;
            }
    
            out.write(buffer, 0, read);
            downloaded += read;
        }
    
    } catch (Exception e) {
        Log.e("downloadFile():", e.getMessage());
        if (conn != null) {
            conn.disconnect();
        }
    }
    
    }
    
BenMorel
  • 34,448
  • 50
  • 182
  • 322
Tal Kanel
  • 10,475
  • 10
  • 60
  • 98
  • Thanks Tal Kanel . The above code you mentioned will only get images from a specific URL written on string(URL). I want to list out a wide range of url that updates/changes regularly without modifying the codes each time i have a new image. I used String imageUrl="http://myfilehosting.com/"; so i can list out all the images that ends with .jpg in my web server. Please kindly assist me. – KC Chai Jul 26 '12 at 06:25
  • What i'm trying to do is, i want to load 100++ images from my web server(URL is something like this http://myfilehosting.com/100.jpg) without specifying each image URL in my string. – KC Chai Jul 26 '12 at 07:23
  • @kcchai: if you want to get from your server random data (not specifying the specific resource/image) then it's the server's responsibility to bring you randomly a specific resource. I don't see any way your application can ask for random resource, without knowing what options can be on the server (image name/ exact image path) – Tal Kanel Jul 26 '12 at 10:16
  • @kcchai: if your sever is FTP server, I guess there is a function returning you all files under specified path (directory), if you want to download all files in the specific directory, then you can iterate about each file, get his name, and download it. – Tal Kanel Jul 26 '12 at 10:19
  • ok. I'll give a scenario, My app has around 10 image urls in my strings.xml . Then I uploaded it into google play. The next day, I add in 10 more new images into my app. Do I need to add the new image URLs into my strings.xml ? then re-upload again to google play market. – KC Chai Jul 26 '12 at 12:05
  • @kcchai: that depends on a lot of reasons. there is not a "yes/no" answer about that issue... – Tal Kanel Jul 26 '12 at 12:45