Currently I am preparing a demo for including Expansion File into a developed project. I have followed this Tutorial.
After a lot of struggle I am able to run the demo application but having issues in displaying progress for downloaded data.
I have uploaded obb file on play store which is 1,060,024 bytes and on disk size is 1,060,864 bytes.
following is code snippet where I think problem can be.
private static final XAPKFile[] xAPKS = { new XAPKFile(true,6,1060024L) };
void validateXAPKZipFiles() {
AsyncTask<Object, DownloadProgressInfo, Boolean> validationTask = new AsyncTask<Object, DownloadProgressInfo, Boolean>() {
@Override
protected void onPreExecute() {
mDashboard.setVisibility(View.VISIBLE);
mCellMessage.setVisibility(View.GONE);
mStatusText.setText(R.string.text_verifying_download);
mPauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mCancelValidation = true;
}
});
mPauseButton.setText(R.string.text_button_cancel_verify);
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Object... params) {
for (XAPKFile xf : xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(
MainActivity.this, xf.mIsMain, xf.mFileVersion);
if (!Helpers.doesFileExist(MainActivity.this, fileName,
xf.mFileSize, true)) {
return false;
}
fileName = Helpers.generateSaveFileName(MainActivity.this,
fileName);
ZipResourceFile zrf;
byte[] buf = new byte[1024 * 256];
try {
zrf = new ZipResourceFile(fileName);
ZipEntryRO[] entries = zrf.getAllEntries();
/**
* First calculate the total compressed length
*/
long totalCompressedLength = 0;
for (ZipEntryRO entry : entries) {
totalCompressedLength += entry.mCompressedLength;
}
float averageVerifySpeed = 0;
long totalBytesRemaining = totalCompressedLength;
long timeRemaining;
/**
* Then calculate a CRC for every file in the Zip file,
* comparing it to what is stored in the Zip directory.
* Note that for compressed Zip files we must extract
* the contents to do this comparison.
*/
for (ZipEntryRO entry : entries) {
if (-1 != entry.mCRC32) {
long length = entry.mUncompressedLength;
CRC32 crc = new CRC32();
DataInputStream dis = null;
try {
dis = new DataInputStream(
zrf.getInputStream(entry.mFileName));
long startTime = SystemClock.uptimeMillis();
while (length > 0) {
int seek = (int) (length > buf.length ? buf.length
: length);
dis.readFully(buf, 0, seek);
crc.update(buf, 0, seek);
length -= seek;
long currentTime = SystemClock
.uptimeMillis();
long timePassed = currentTime
- startTime;
if (timePassed > 0) {
float currentSpeedSample = (float) seek
/ (float) timePassed;
if (0 != averageVerifySpeed) {
averageVerifySpeed = SMOOTHING_FACTOR
* currentSpeedSample
+ (1 - SMOOTHING_FACTOR)
* averageVerifySpeed;
} else {
averageVerifySpeed = currentSpeedSample;
}
totalBytesRemaining -= seek;
timeRemaining = (long) (totalBytesRemaining / averageVerifySpeed);
Log.e("Remaining Size is :: ",
" "
+ (totalCompressedLength - totalBytesRemaining));
this.publishProgress(new DownloadProgressInfo(
totalCompressedLength,
totalCompressedLength
- totalBytesRemaining,
timeRemaining,
averageVerifySpeed));
}
startTime = currentTime;
if (mCancelValidation)
return true;
}
if (crc.getValue() != entry.mCRC32) {
Log.e(Constants.TAG,
"CRC does not match for entry: "
+ entry.mFileName);
Log.e(Constants.TAG, "In file: "
+ entry.getZipFileName());
return false;
}
} finally {
if (null != dis) {
dis.close();
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
return false;
}
}
return true;
}
@Override
protected void onProgressUpdate(DownloadProgressInfo... values) {
onDownloadProgress(values[0]);
super.onProgressUpdate(values);
}
@Override
protected void onPostExecute(Boolean result) {
if (result) {
mDashboard.setVisibility(View.VISIBLE);
mCellMessage.setVisibility(View.GONE);
mStatusText.setText(R.string.text_validation_complete);
mPauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
mPauseButton.setText(android.R.string.ok);
} else {
mDashboard.setVisibility(View.VISIBLE);
mCellMessage.setVisibility(View.GONE);
mStatusText.setText(R.string.text_validation_failed);
mPauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
finish();
}
});
mPauseButton.setText(android.R.string.cancel);
}
super.onPostExecute(result);
}
};
validationTask.execute(new Object());
}
I am not using patch file , using only main file.
Every time I download data it shows random progress as below
And in actual its downloading full data but can not verify full data.Following is the logcat entries when printing remaining bytes to verify.
11-08 12:22:12.205: E/Remaining Size is ::(20326): 46804 11-08 12:22:13.370: E/Remaining Size is ::(20326): 99054 11-08 12:22:13.460: E/Remaining Size is ::(20326): 203827 11-08 12:22:14.035: E/Remaining Size is ::(20326): 465971 11-08 12:22:14.115: E/Remaining Size is ::(20326): 728115 11-08 12:22:14.155: E/Remaining Size is ::(20326): 813899 11-08 12:22:14.270: E/Remaining Size is ::(20326): 850970 11-08 12:22:14.295: E/Remaining Size is ::(20326): 868781 11-08 12:22:14.320: E/Remaining Size is ::(20326): 1041595
I am not able to identify the issue , if any body has face the issue it would be great help.
Thanks in advance.
The problem here is, the total size is being calculated on the entries within the zipped file, which is resulting in uncompressed size of the files within the zipped file. And the progress is being displayed on the basis of the same.
First solution is that for checking expansion file availability, keep the check as it is in your app, but for calculation supply the original size. The calculations are being done for zipped entries in zip file library, modify it accordingly, if possible. (I have not tried this solution.)
Second one is, compress the files in a way that files inside the folder are uncompressed. In this case you will have nothing to do, but drawback will be that user has to download a bit larger size of file.
来源:https://stackoverflow.com/questions/19835580/expansion-file-download-sample-not-showing-full-progress