Monday, May 30, 2011

The download - step 2

Well, I'm ready to tackle step 2 of the download process. In recent post, I basically dissected the async task, because a huge download is something you are definitely going to want to run asynchronously. Today, I am shooting for actually going ahead and downloading that file.

So, where is that old download logic? Oh, yeah - it was in the "download" button on the StartActivity page. Good.

Ok, it's successfully calling the onPreExecute, which displays this:

this.dialog = ProgressDialog.show(applicationContext, "Calling", "Download Service...", true);

But, nothing cancels it, so it just kind of sits there.

That's not true, the download cancels it, but the publishProgress in the doInBackground doesn't seem to be doing anything. So, let's comment it out.

Ok, that seemed to work out ok. The dialog flashed by, but since the doInB... didn't do anything, it went straight to the cancel. Now let's take the progressDialog and put it into a loop. Let's try an experiment and comment back in the publishProgress inside of a loop.

Well, it does get to the download service display - but it just hangs on that.

Ok, I'm taking my eye off the ball. I need to focus on getting the download taken care of :

Here's a URL: http://www.helloandroid.com/tutorials/how-download-fileimage-url-your-device

First, let's add these permissions:

android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.READ_PHONE_STATE


Ok, that's done. Now, the code.

Here's what seems a reasonable compromise between a couple of examples:


public void downloadFromUrl() { // this is the downloader method
try {

String PATH = Environment.getExternalStorageDirectory()
+ "/xdownload/";
Log.v(TAG, "PATH: " + PATH);
URL url = new URL(
"http://www.mysite.com/test/lib.mp3");

HttpURLConnection c = (HttpURLConnection) url.openConnection();
c.setRequestMethod("GET");
c.setDoOutput(true);
c.connect();

File file = new File(PATH);
file.mkdirs();

String fileName = "test.mp3";

File outputFile = new File(file, fileName);

long startTime = System.currentTimeMillis();
Log.d("ImageManager", "download begining");
Log.d("ImageManager", "download url:" + url);
Log.d("ImageManager", "downloaded file name:" + fileName);
/* Open a connection to that URL. */

FileOutputStream fos = new FileOutputStream(outputFile);

InputStream is = c.getInputStream();

byte[] buffer = new byte[1024];
int len1 = 0;
while ((len1 = is.read(buffer)) != -1) {
fos.write(buffer, 0, len1);
}
fos.close();
is.close();

Log.d("ImageManager",
"download ready in"
+ ((System.currentTimeMillis() - startTime) / 1000)
+ " sec");

} catch (IOException e) {
Log.d("ImageManager", "Error: " + e);
}

}


Ok, not bad - I got this:


D/ImageManager( 6501): Error: java.io.FileNotFoundException: /mnt/sdcard/xdownload/test.mp3 (No such file or directory)

Well, it seems to be doing the correct commands for creating the data, but the files just not getting created. What's going wrong?

Ok, I got it to work by adding an external storage permission in the manifest. But, unfortunately, I still can't seem to get the progress dialog to work. It also keeps showing the file not found exception.

Here's the example from google:

protected Long doInBackground(URL... urls) {
int count = urls.length;
long totalSize = 0;
for (int i = 0; i < count; i++) {
totalSize += Downloader.downloadFile(urls[i]);
publishProgress((int) ((i / (float) count) * 100));
}
return totalSize;
}

protected void onProgressUpdate(Integer... progress) {
setProgressPercent(progress[0]);
}



So, the publishProgress looks like it's called with an int percentage of the # of files downloaded. Does it have some kind of mechanism that takes whatever's passed in, turns it into an object array? Oh, yeah, that's what the middle parameter in the Async Vector is for.

Ah, ok, the problem is although it's creating the file, it's dying on the file not found exception. So, it's never making the calls to display the dialog, the file's never getting written to.

Could it be it needs read permission, too?



Wait - it's writing to "lib.mp3". I've been creating test.mp3. Change the created file to lib.mp3 instead of the test.mp3.

Nope. Still no good. File not found. Wait - now it's the url file name it's not finding! Cool. I'm making progress.

Ah, right. The url I coded includes public_html - no need to specify that. The directory names begin after that. Fix that.

Cool - it found it alright - then went into a mad loop about resources or memory exceptions. I'm not sure if it was the file or the dialogue box. I suspect it was the dialog box because I was displaying for every thousand bytes. But, I'm not sure.

Did the file get written to?

Yes, indeed it did. It's just one mp3. The zip file will be much huger.

Well, let's get rid of the dialog, and see if it goes more smoothly....

Yep. Well, as I suspected, the download is going to be less of a problem than displaying the progress dialogue.

Maybe if I tried every thousand?

Ah, right, because I'm canceling right away, nothings showing up. No, it's just not getting called. I'm doing something wrong. Ok, what I'll do is change it back to a no parameters for now.

Nah; I'll just call here. I'll figure that part out tomorrow. Right now, let's watch Die Hard!

No comments:

Post a Comment