2

I have the following method to download an image from a given URL. When I run the appropriate methods the first time, the file is saved to the sdcard. When I go to re-run these methods, and check if there is a file at the end of the given path, the image is not (i check with file.exists()), and null is returned. Any reason why this activity is going on? The code specifically fails at input = url.openStream().

public class DownloadAndReadImage {
    String strURL;
    int pos;
    Bitmap bitmap = null;

    // pass image url and Pos for example i:
    DownloadAndReadImage(String url,int position) {
        this.strURL = url;
        this.pos = position;
    }

    public String getBitmapLocation() {
        return "/sdcard/"+pos+".png";
    }

    public Bitmap getBitmapImage() {
        downloadBitmapImage();
        return readBitmapImage();
    }

    void downloadBitmapImage() {
        InputStream input;
        try {
            URL url = new URL (strURL);
            input = url.openStream();
            byte[] buffer = new byte[500*1024]; //or 500*1024
            OutputStream output = new FileOutputStream ("/sdcard/"+pos+".png");
            try {
                int bytesRead = 0;
                while ((bytesRead = input.read(buffer, 0, buffer.length)) >= 0) {
                    output.write(buffer, 0, bytesRead);
                }
            }
            finally {
                output.close();
                input.close();
                buffer = null;
            }
        }
        catch(Exception e) {
            Toast.makeText(getApplicationContext(), e.toString(), Toast.LENGTH_LONG).show();
        }
    }

    Bitmap readBitmapImage() {
        BitmapFactory.Options bOptions = new BitmapFactory.Options();
        bOptions.inTempStorage = new byte[16*1024*1024];

        String imageInSD = "/sdcard/"+pos+".png";

        bitmap = BitmapFactory.decodeFile(imageInSD,bOptions);
        boolean exists = new File(imageInSD).exists();
        return bitmap;
    }
}

This is the call code:

   private void saveImage() {
        DownloadAndReadImage dImage = new DownloadAndReadImage(imageAddress, count);
        image = dImage.getBitmapImage();
    }

Here is my Async code

public void submitFile() {
    if(URLUtil.isValidUrl(imageAddress)) {
        new AsyncTask<Void, Void, Boolean>() {
            protected Boolean doInBackground(Void... voids) {
                boolean img = false;
                boolean youtube = false;
                HttpURLConnection connection = null;
                try {
                    URL url  = new URL(imageAddress);
                    connection = (HttpURLConnection)url.openConnection();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                String contentType = connection.getHeaderField("Content-Type");
                img = contentType.startsWith("image/");
                if(img)
                    media = "image";
                if (!img) {
                    // Check host of url if youtube exists
                    Uri uri = Uri.parse(imageAddress);
                    if ("www.youtube.com".equals(uri.getHost())) {
                        media = "youtube";
                        youtube = true;
                    }
                }
                return img || youtube;
            }

            protected void onPostExecute(Boolean valid) {
                if (valid) {
                    Picasso.with(Demo.this).load(imageAddress).into(imagePreview);
                    saveImage();
                    //sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory()))); //refreshes system to show saved file
                    submitted = true;
                    submit_but.setText("Encrypt");
                }
            }
        }.execute();
    }
}

I am using android studio. Thank you for your assistance.

2 Answers2

1

Try ensuring that you close your input stream as well. If this doesn't help please post the code you use to call download bitmap.

JohanShogun
  • 2,956
  • 21
  • 30
  • I added input.close() after output.close(), but the returning bitmap is still null. – Robert Wayne Jr. Aug 20 '15 at 19:01
  • Could you print the value of bytesRead in the loop? Also, I'm assuming you're doing these operations on a background thread? Keep in mind that you can only call start on a thread instance once. – JohanShogun Aug 20 '15 at 20:05
  • I'm going to print the bytesRead. Currently, saveImage() is called by an AsyncTask. Could this be the issue? – Robert Wayne Jr. Aug 20 '15 at 20:14
  • AsyncTasks can be executed many times, could you post your AsyncTask code? – JohanShogun Aug 20 '15 at 20:17
  • I have narrowed down the issue. On the second creation of a DownloadAndReadImage, the program never goes into the method downloadBitmapImage. I do not understand why, though. – Robert Wayne Jr. Aug 20 '15 at 20:43
  • Going to need more of your code to answer that question. :) – JohanShogun Aug 20 '15 at 20:46
  • I added my Async code. I've noted that when I debug, my code does go into downloadBitmapImage() but never closes either output or input buffers. The code does not go into the "try" portion – Robert Wayne Jr. Aug 20 '15 at 21:04
  • I just used debug, and the code stops at input = url.openStream(); – Robert Wayne Jr. Aug 20 '15 at 21:09
  • You never close your connection in the AsyncTask. – JohanShogun Aug 20 '15 at 21:11
  • The URLconnection? That doesn't have a .close() or disconnect() method. – Robert Wayne Jr. Aug 20 '15 at 21:17
  • You're right, use the HttpURLConnection class instead, it should be what's returned from the URL granted it uses http or https. – JohanShogun Aug 20 '15 at 21:21
  • That did not help my problem but thank you for the advice. Again, when the code reaches downloadBitmapImage() the second time around, it seems to fail at input = url.openStream(); and go straight to the next function in the calling parent. – Robert Wayne Jr. Aug 20 '15 at 21:32
  • That's consistent with getting an exception, try logging them instead of putting them in a toast and see what the log says, – JohanShogun Aug 21 '15 at 05:15
  • On my first run, I catch a NetworkOnMainThreadException right at the location that my program fails at later. I get the same error moments later when it fails the second time around (the issue that I wrote about). The error below my exception is: at android.os.StrictMode$AndroidBlockGuardPolicy.onNetwork(StrictMode.java:1147) I thought that by setting my internet calls in an AsyncTask that would alleviate any stress on the MainNetwork? Obviously not though. How do I address this? – Robert Wayne Jr. Aug 21 '15 at 17:06
  • ^my question has been answered multiple times on SO. Thank you JohanShogun: http://stackoverflow.com/questions/26224016/android-os-networkonmainthreadexception-in-asynctasks-doinbackground – Robert Wayne Jr. Aug 21 '15 at 17:15
0

If you are calling the function with same position again, it will keep on replacing the existing file. Try with different position. Let me know if it works out. Cheers!

rajeswari ratala
  • 650
  • 7
  • 14