Gamecraftler Gamecraftler - 1 month ago 12
Android Question

Download and unzip files in While-Loop

I tried to Download and Unzip files if there is an update on a server. It starts checking but after a short time this Error comes:


10-13 19:31:30.122 2895-3007/com.example W/System.err: at
java.lang.IndexOutOfBoundsException: Invalid index 13, size is 13
10-13 19:31:30.122 2895-3007/com.example W/System.err: at
java.util.ArrayList.throwIndexOutOfBoundsException(ArrayList.java:255)
10-13 19:31:30.122 2895-3007/com.example W/System.err: at
java.util.ArrayList.get(ArrayList.java:308) 10-13 19:31:30.122
2895-3007/com.example W/System.err: at
com.example.Update$AsyncTaskRunner.doInBackground(Update.java:156)
10-13 19:31:30.122 2895-3007/com.example W/System.err: at
com.example.Update$AsyncTaskRunner.doInBackground(Update.java:130)
10-13 19:31:30.122 2895-3007/com.example W/System.err: at
android.os.AsyncTask$2.call(AsyncTask.java:295) 10-13 19:31:30.122
2895-3007/com.example W/System.err: at
java.util.concurrent.FutureTask.run(FutureTask.java:237) 10-13
19:31:30.122 2895-3007/com.example W/System.err: at
android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:234) 10-13
19:31:30.122 2895-3007/com.example W/System.err: at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1113)
10-13 19:31:30.122 2895-3007/com.example W/System.err: at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:588)
10-13 19:31:30.122 2895-3007/com.example W/System.err: at
java.lang.Thread.run(Thread.java:818)


This is my Activity:

package com.example;

import android.app.ProgressDialog;
import android.content.Context;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Environment;
import android.os.PowerManager;
import android.os.StrictMode;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.WindowManager;
import android.widget.Toast;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

public class Update extends AppCompatActivity {

private ProgressDialog ringProgressDialog;

private static Boolean finished = false;

private String read(String fileName) {
StringBuilder retString = new StringBuilder();
String zeilenumbruch = "\n";
BufferedReader reader = null;

try {
File file = new File(fileName);
FileInputStream in = new FileInputStream(Environment.getExternalStorageDirectory().toString() + "/.elero/Anleitungen/.data/Versions/" + fileName);
reader = new BufferedReader(new InputStreamReader(in));

String zeile;
while ((zeile = reader.readLine()) != null) {
retString.append(zeile);
}
reader.close();
} catch (IOException ex) {
Log.e(getPackageName(), ex.getMessage());
}

return retString.toString();
}

public static String getTextOfUrl(String uri) throws Exception {

StringBuilder result = new StringBuilder();

URL url = new URL(uri);

String line = null;
BufferedReader reader = null;
finished = false;
try {
reader = new BufferedReader(new InputStreamReader(url.openStream()));

while ((line = reader.readLine()) != null) {
result.append(line);

}
return result.toString();
} finally {
if (reader != null) {
reader.close();
}
finished = true;
}

}

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_update);

if (android.os.Build.VERSION.SDK_INT > 9) {
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);
}

PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
final PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK, "Updating");
wl.acquire();
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);

AsyncTaskRunner runner = new AsyncTaskRunner();
runner.execute();

}

private void downloadAndUnzipContent(String path, String urlPath) {
String url = urlPath;
DownloadFileAsync download = new DownloadFileAsync(path, this, new DownloadFileAsync.PostDownload() {
@Override
public void downloadDone(File file) {
Log.i(getPackageName(), "file download completed");


// check unzip file now
Decompress unzip = new Decompress(Update.this, file, true);
unzip.unzip();

Log.i(getPackageName(), "File unzip completed");

Toast.makeText(Update.this, "F", Toast.LENGTH_LONG).show();

}
});
download.execute(url);
}

private void downloadContent(String path, String urlPath) {
DownloadFileAsync download = new DownloadFileAsync(path, this, new DownloadFileAsync.PostDownload() {
@Override
public void downloadDone(File file) {
Log.i(getPackageName(), "file download completed");

}
});
download.execute(urlPath);
}

private class AsyncTaskRunner extends AsyncTask<String, String, String> {

private String resp;

@Override
protected String doInBackground(String... params) {
try {
List<String> files = new ArrayList<String>();
files.add("Archiv");
files.add("Funkempfaenger");
files.add("Funkhandsender");
files.add("Funksender");
files.add("Funksensoren");
files.add("Hausautomatisierung");
files.add("Jalousieantriebe");
files.add("Rohrantriebe");
files.add("SensorenKabelgebunden");
files.add("Sonderantriebe");
files.add("Torantriebe");
files.add("Torsteuerungen");
files.add("WandgeraeteKabelgebunden");

Integer uI = 0;

while (uI < 14) {
try {
String newVersion = getTextOfUrl("http://www.example.com/zip/Versions/" + files.get(uI) + ".txt");
publishProgress("Info");
int nV = Integer.parseInt(newVersion);
String readString = files.get(uI) + ".txt";
String oldVersion = read(readString);
int iV = Integer.parseInt(oldVersion);
if (iV < nV) {
while (!finished) {
Log.i(getPackageName(), "Finished = False");
}
String dlPath = Environment.getExternalStorageDirectory() + "/.example/Anleitungen/.data/" + files.get(uI) + ".zip";
String dlPath2 = Environment.getExternalStorageDirectory() + "/.example/Anleitungen/.data/Versions/" + files.get(uI) + ".txt";
downloadAndUnzipContent(dlPath, "http://www.example.com/zip/Versions/" + files.get(uI) + ".zip");
downloadContent(dlPath2, "http://www.example.com/zip/Versions/" + files.get(uI) + ".txt");
}
uI++;
} catch (Exception e) {
e.printStackTrace();
publishProgress(e.toString());
}
}

} catch (Exception e) {
e.printStackTrace();
}

return "HI!";
}

/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPostExecute(java.lang.Object)
*/
@Override
protected void onPostExecute(String result) {
// execution of result of Long time consuming operation
Toast.makeText(Update.this, "Jay!", Toast.LENGTH_LONG).show();
}

/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onPreExecute()
*/
@Override
protected void onPreExecute() {

}

/*
* (non-Javadoc)
*
* @see android.os.AsyncTask#onProgressUpdate(Progress[])
*/
@Override
protected void onProgressUpdate(String... text) {
Toast.makeText(Update.this, text[0], Toast.LENGTH_SHORT).show();
}
}

@Override
public void onBackPressed() {
Log.i(getPackageName(), "Back pressed");
}
}


This is my
Decompress.class
:

package com.example;

import android.content.Context;
import android.util.Log;
import android.widget.Toast;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

public class Decompress {
private File _zipFile;
private InputStream _zipFileStream;
private Context context;
private static String ROOT_LOCATION = "/sdcard";
private static final String TAG = "UNZIPUTIL";
private Boolean pathNew;

public Decompress(Context context, File zipFile, Boolean path) {
_zipFile = zipFile;
this.context = context;
pathNew = path;

if (pathNew) {
ROOT_LOCATION = "/sdcard/.example/Anleitungen";
}

_dirChecker("");
}

public Decompress(Context context, InputStream zipFile) {
_zipFileStream = zipFile;
this.context = context;

_dirChecker("");
}

public void unzip() {
try {
Log.i(TAG, "Starting to unzip");
InputStream fin = _zipFileStream;
if(fin == null) {
fin = new FileInputStream(_zipFile);
}
ZipInputStream zin = new ZipInputStream(fin);
ZipEntry ze = null;
while ((ze = zin.getNextEntry()) != null) {
Log.v(TAG, "Unzipping " + ze.getName());

if(ze.isDirectory()) {
_dirChecker(ROOT_LOCATION + "/" + ze.getName());
} else {
FileOutputStream fout = new FileOutputStream(new File(ROOT_LOCATION, ze.getName()));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int count;

// reading and writing
while((count = zin.read(buffer)) != -1)
{
baos.write(buffer, 0, count);
byte[] bytes = baos.toByteArray();
fout.write(bytes);
baos.reset();
}

fout.close();
zin.closeEntry();
}

}
zin.close();
Log.i(TAG, "Finished unzip");
} catch(Exception e) {
Log.e(TAG, "Unzip Error", e);
Toast.makeText(context, "Error while unzipping: " + e.toString(), Toast.LENGTH_LONG).show();
}

}

private void _dirChecker(String dir) {
File f = new File(dir);
Log.i(TAG, "creating dir " + dir);

if(dir.length() >= 0 && !f.isDirectory() ) {
f.mkdirs();
}
}
}


This is my
DownloadFileAsnyc.class
:

package com.example;

import android.content.Context;
import android.os.AsyncTask;
import android.util.Log;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.net.URL;
import java.net.URLConnection;

public class DownloadFileAsync extends AsyncTask<String, String, String> {

private static final String TAG ="DOWNLOADFILE";

public static final int DIALOG_DOWNLOAD_PROGRESS = 0;
private PostDownload callback;
private Context context;
private FileDescriptor fd;
private File file;
private String downloadLocation;

public DownloadFileAsync(String downloadLocation, Context context, PostDownload callback){
this.context = context;
this.callback = callback;
this.downloadLocation = downloadLocation;
}
@Override
protected void onPreExecute() {
super.onPreExecute();
}

@Override
protected String doInBackground(String... aurl) {
int count;

try {
URL url = new URL(aurl[0]);
URLConnection connection = url.openConnection();
connection.connect();

int lenghtOfFile = connection.getContentLength();
Log.d(TAG, "Length of the file: " + lenghtOfFile);

InputStream input = new BufferedInputStream(url.openStream());
file = new File(downloadLocation);
FileOutputStream output = new FileOutputStream(file); //context.openFileOutput("content.zip", Context.MODE_PRIVATE);
Log.d(TAG, "file saved at " + file.getAbsolutePath());
fd = output.getFD();

byte data[] = new byte[1024];
long total = 0;
while ((count = input.read(data)) != -1) {
total += count;
publishProgress(""+(int)((total*100)/lenghtOfFile));
output.write(data, 0, count);
}

output.flush();
output.close();
input.close();
} catch (Exception e) {}
return null;

}
protected void onProgressUpdate(String... progress) {
//Log.d(TAG,progress[0]);
}

@Override
protected void onPostExecute(String unused) {
if(callback != null) callback.downloadDone(file);
}

public static interface PostDownload{
void downloadDone(File fd);
}
}


Please help me. Sorry for my bad English.

Thank you.

Answer

This is because you have only 13 elements in your list files not 14 as you seem to assume so when you call files.get(13) it throws IndexOutOfBoundsException: Invalid index 13

so simply replace

while (uI < 14) 

with

while (uI < files.size()) 

Your while loop is unsafe because if you get an exception in the try block, uI will never be incremented such that you will get an infinite loop.

Consider using a for loop instead:

for (int uI = 0; uI < files.size(); uI++) {
    ...
}
Comments