Files
UnrealEngine/Engine/Build/Android/Java/JavaTemplates/DownloaderActivity.java.template
2025-05-18 13:04:45 +08:00

810 lines
32 KiB
Plaintext

/*
* Copyright (C) 2012 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package $$PackageName$$;
import com.android.vending.expansion.zipfile.ZipResourceFile;
import com.android.vending.expansion.zipfile.ZipResourceFile.ZipEntryRO;
import com.google.android.vending.expansion.downloader.Constants;
import com.google.android.vending.expansion.downloader.DownloadProgressInfo;
import com.google.android.vending.expansion.downloader.DownloaderClientMarshaller;
import com.google.android.vending.expansion.downloader.DownloaderServiceMarshaller;
import com.google.android.vending.expansion.downloader.Helpers;
import com.google.android.vending.expansion.downloader.IDownloaderClient;
import com.google.android.vending.expansion.downloader.IDownloaderService;
import com.google.android.vending.expansion.downloader.IStub;
import android.app.Activity;
import android.app.PendingIntent;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.content.Intent;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.Messenger;
import android.os.SystemClock;
import android.provider.Settings;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ProgressBar;
import android.widget.TextView;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.util.zip.CRC32;
import java.util.Map;
import java.util.HashMap;
import java.util.List;
import java.util.ArrayList;
import com.epicgames.unreal.GameActivity;
/**
* This is sample code for a project built against the downloader library. It
* implements the IDownloaderClient that the client marshaler will talk to as
* messages are delivered from the DownloaderService.
*/
public class DownloaderActivity extends Activity implements IDownloaderClient {
private static final String LOG_TAG = "LVLDownloader";
private ProgressBar mPB;
private TextView mStatusText;
private TextView mProgressFraction;
private TextView mProgressPercent;
private TextView mAverageSpeed;
private TextView mTimeRemaining;
private View mDashboard;
private View mCellMessage;
private Button mPauseButton;
private Button mWiFiSettingsButton;
private boolean mStatePaused;
private int mState;
private IDownloaderService mRemoteService;
private IStub mDownloaderClientStub;
private final CharSequence[] OBBSelectItems = { "Use Store Data", "Use Development Data" };
private void setState(int newState) {
if (mState != newState) {
mState = newState;
mStatusText.setText(Helpers.getDownloaderStringResourceIDFromState(newState));
}
}
private void setButtonPausedState(boolean paused) {
mStatePaused = paused;
int stringResourceID = paused ? R.string.text_button_resume :
R.string.text_button_pause;
mPauseButton.setText(stringResourceID);
}
static DownloaderActivity _download;
private Intent OutputData;
/**
* Go through each of the APK Expansion files defined in the structure above
* and determine if the files are present and match the required size. Free
* applications should definitely consider doing this, as this allows the
* application to be launched for the first time without having a network
* connection present. Paid applications that use LVL should probably do at
* least one LVL check that requires the network to be present, so this is
* not as necessary.
*
* @return true if they are present.
*/
boolean expansionFilesDelivered() {
for (OBBData.XAPKFile xf : OBBData.xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion, OBBData.AppType);
GameActivity.Log.debug("Checking for file : " + fileName);
String fileForNewFile = Helpers.generateSaveFileName(this, fileName);
String fileForDevFile = Helpers.generateSaveFileNameDevelopment(this, fileName);
GameActivity.Log.debug("which is really being resolved to : " + fileForNewFile + "\n Or : " + fileForDevFile);
if (!Helpers.doesFileExist(this, fileName, xf.mFileSize, false) &&
!Helpers.doesFileExistDev(this, fileName, xf.mFileSize, false))
return false;
}
return true;
}
boolean onlySingleExpansionFileFound() {
for (OBBData.XAPKFile xf : OBBData.xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion, OBBData.AppType);
GameActivity.Log.debug("Checking for file : " + fileName);
String fileForNewFile = Helpers.generateSaveFileName(this, fileName);
String fileForDevFile = Helpers.generateSaveFileNameDevelopment(this, fileName);
if (Helpers.doesFileExist(this, fileName, xf.mFileSize, false) &&
Helpers.doesFileExistDev(this, fileName, xf.mFileSize, false))
return false;
}
return true;
}
File getFileDetailsCacheFile() {
return new File(this.getExternalFilesDir(null), "cacheFile.txt");
}
boolean expansionFilesUptoData() {
File cacheFile = getFileDetailsCacheFile();
// Read data into an array or something...
Map<String, Long> fileDetailsMap = new HashMap<String, Long>();
if(cacheFile.exists()) {
try {
FileReader fileCache = new FileReader(cacheFile);
BufferedReader bufferedFileCache = new BufferedReader(fileCache);
List<String> lines = new ArrayList<String>();
String line = null;
while ((line = bufferedFileCache.readLine()) != null) {
lines.add(line);
}
bufferedFileCache.close();
for(String dataLine : lines)
{
GameActivity.Log.debug("Splitting dataLine => " + dataLine);
String[] parts = dataLine.split(",");
fileDetailsMap.put(parts[0], Long.parseLong(parts[1]));
}
}
catch(Exception e)
{
GameActivity.Log.debug("Exception thrown during file details reading.");
e.printStackTrace();
fileDetailsMap.clear();
}
}
for (OBBData.XAPKFile xf : OBBData.xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(this, xf.mIsMain, xf.mFileVersion, OBBData.AppType);
String fileForNewFile = Helpers.generateSaveFileName(this, fileName);
String fileForDevFile = Helpers.generateSaveFileNameDevelopment(this, fileName);
// check to see if time/data on files match cached version
// if not return false
File srcFile = new File(fileForNewFile);
File srcDevFile = new File(fileForDevFile);
long lastModified = srcFile.lastModified();
long lastModifiedDev = srcDevFile.lastModified();
if(!(srcFile.exists() && fileDetailsMap.containsKey(fileName) && lastModified == fileDetailsMap.get(fileName))
&&
!(srcDevFile.exists() && fileDetailsMap.containsKey(fileName) && lastModifiedDev == fileDetailsMap.get(fileName)))
return false;
}
return true;
}
static private void RemoveOBBFile(int OBBToDelete) {
for (OBBData.XAPKFile xf : OBBData.xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(DownloaderActivity._download, xf.mIsMain, xf.mFileVersion, OBBData.AppType);
switch(OBBToDelete)
{
case 0:
String fileForNewFile = Helpers.generateSaveFileName(DownloaderActivity._download, fileName);
File srcFile = new File(fileForNewFile);
srcFile.delete();
break;
case 1:
String fileForDevFile = Helpers.generateSaveFileNameDevelopment(DownloaderActivity._download, fileName);
File srcDevFile = new File(fileForDevFile);
srcDevFile.delete();
break;
}
}
}
private void ProcessOBBFiles()
{
if(GameActivity.Get().VerifyOBBOnStartUp && !expansionFilesUptoData()) {
validateXAPKZipFiles();
} else {
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);
setResult(RESULT_OK, OutputData);
finish();
overridePendingTransition(R.anim.noaction, R.anim.noaction);
}
}
/**
* Calculating a moving average for the validation speed so we don't get
* jumpy calculations for time etc.
*/
static private final float SMOOTHING_FACTOR = 0.005f;
/**
* Used by the async task
*/
private boolean mCancelValidation;
/**
* Go through each of the Expansion APK files and open each as a zip file.
* Calculate the CRC for each file and return false if any fail to match.
*
* @return true if XAPKZipFile is successful
*/
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.setVisibility(View.GONE);
// mPauseButton.setText(R.string.text_button_cancel_verify);
super.onPreExecute();
}
@Override
protected Boolean doInBackground(Object... params) {
for (OBBData.XAPKFile xf : OBBData.xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(
DownloaderActivity.this,
xf.mIsMain, xf.mFileVersion, OBBData.AppType);
boolean normalFile = Helpers.doesFileExist(DownloaderActivity.this, fileName, xf.mFileSize, false);
boolean devFile = Helpers.doesFileExistDev(DownloaderActivity.this, fileName, xf.mFileSize, false);
if (!normalFile && !devFile )
return false;
if(normalFile)
{
fileName = Helpers.generateSaveFileName(DownloaderActivity.this, fileName);
}
else
{
fileName = Helpers.generateSaveFileNameDevelopment(DownloaderActivity.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);
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) {
// save details to cache file...
try {
File cacheFile = getFileDetailsCacheFile();
FileWriter fileCache = new FileWriter(cacheFile);
BufferedWriter bufferedFileCache = new BufferedWriter(fileCache);
for (OBBData.XAPKFile xf : OBBData.xAPKS) {
String fileName = Helpers.getExpansionAPKFileName(DownloaderActivity.this, xf.mIsMain, xf.mFileVersion, OBBData.AppType);
String fileForNewFile = Helpers.generateSaveFileName(DownloaderActivity.this, fileName);
String fileForDevFile = Helpers.generateSaveFileNameDevelopment(DownloaderActivity.this, fileName);
GameActivity.Log.debug("Writing details for file : " + fileName);
File srcFile = new File(fileForNewFile);
File srcDevFile = new File(fileForDevFile);
if(srcFile.exists()) {
long lastModified = srcFile.lastModified();
bufferedFileCache.write(fileName);
bufferedFileCache.write(",");
bufferedFileCache.write(new Long(lastModified).toString());
bufferedFileCache.newLine();
GameActivity.Log.debug("Details for file : " + fileName + " with modified time of " + new Long(lastModified).toString() );
}
else {
long lastModified = srcDevFile.lastModified();
bufferedFileCache.write(fileName);
bufferedFileCache.write(",");
bufferedFileCache.write(new Long(lastModified).toString());
bufferedFileCache.newLine();
GameActivity.Log.debug("Details for file : " + fileName + " with modified time of " + new Long(lastModified).toString() );
}
}
bufferedFileCache.close();
}
catch(Exception e)
{
GameActivity.Log.debug("Exception thrown during file details writing.");
e.printStackTrace();
}
/*
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) {
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);
setResult(RESULT_OK, OutputData);
finish();
}
});
mPauseButton.setText(android.R.string.ok);
*/
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);
setResult(RESULT_OK, OutputData);
finish();
} else {
// clear cache file if it exists...
File cacheFile = getFileDetailsCacheFile();
if(cacheFile.exists()) {
cacheFile.delete();
}
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) {
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_INVALID);
setResult(RESULT_OK, OutputData);
finish();
}
});
mPauseButton.setText(android.R.string.cancel);
}
super.onPostExecute(result);
}
};
validationTask.execute(new Object());
}
/**
* If the download isn't present, we initialize the download UI. This ties
* all of the controls into the remote service calls.
*/
private void initializeDownloadUI() {
mDownloaderClientStub = DownloaderClientMarshaller.CreateStub
(this, OBBDownloaderService.class);
setContentView(R.layout.downloader_progress);
mPB = (ProgressBar) findViewById(R.id.progressBar);
mStatusText = (TextView) findViewById(R.id.statusText);
mProgressFraction = (TextView) findViewById(R.id.progressAsFraction);
mProgressPercent = (TextView) findViewById(R.id.progressAsPercentage);
mAverageSpeed = (TextView) findViewById(R.id.progressAverageSpeed);
mTimeRemaining = (TextView) findViewById(R.id.progressTimeRemaining);
mDashboard = findViewById(R.id.downloaderDashboard);
mCellMessage = findViewById(R.id.approveCellular);
mPauseButton = (Button) findViewById(R.id.pauseButton);
mWiFiSettingsButton = (Button) findViewById(R.id.wifiSettingsButton);
mPauseButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (mStatePaused) {
mRemoteService.requestContinueDownload();
} else {
mRemoteService.requestPauseDownload();
}
setButtonPausedState(!mStatePaused);
}
});
mWiFiSettingsButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
}
});
Button resumeOnCell = (Button) findViewById(R.id.resumeOverCellular);
resumeOnCell.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
mRemoteService.setDownloadFlags(IDownloaderService.FLAGS_DOWNLOAD_OVER_CELLULAR);
mRemoteService.requestContinueDownload();
mCellMessage.setVisibility(View.GONE);
}
});
}
/**
* Called when the activity is first create; we wouldn't create a layout in
* the case where we have the file and are moving to another activity
* without downloading.
*/
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
GameActivity.Log.debug("Starting DownloaderActivity...");
_download = this;
// Create somewhere to place the output - we'll check this on 'finish' to make sure we are returning 'something'
OutputData = new Intent();
/**
* Both downloading and validation make use of the "download" UI
*/
initializeDownloadUI();
GameActivity.Log.debug("... UI setup. Checking for files.");
/**
* Before we do anything, are the files we expect already here and
* delivered (presumably by Market) For free titles, this is probably
* worth doing. (so no Market request is necessary)
*/
if (!expansionFilesDelivered()) {
GameActivity.Log.debug("... Whoops... missing; go go go download system!");
try {
// Make sure we have a key before we try to start the service
if(OBBDownloaderService.getPublicKeyLength() == 0) {
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false)
.setTitle("No Google Play Store Key")
.setMessage("No OBB found and no store key to try to download. Please set one up in Android Project Settings")
.setPositiveButton("Exit", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_NO_PLAY_KEY);
setResult(RESULT_OK, OutputData);
finish();
}
});
AlertDialog alert = builder.create();
alert.show();
}
else
{
Intent launchIntent = DownloaderActivity.this
.getIntent();
Intent intentToLaunchThisActivityFromNotification = new Intent(
DownloaderActivity
.this, DownloaderActivity.this.getClass());
intentToLaunchThisActivityFromNotification.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK |
Intent.FLAG_ACTIVITY_CLEAR_TOP);
intentToLaunchThisActivityFromNotification.setAction(launchIntent.getAction());
if (launchIntent.getCategories() != null) {
for (String category : launchIntent.getCategories()) {
intentToLaunchThisActivityFromNotification.addCategory(category);
}
}
// Build PendingIntent used to open this activity from
// Notification
PendingIntent pendingIntent = PendingIntent.getActivity(
DownloaderActivity.this,
0, intentToLaunchThisActivityFromNotification,
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_IMMUTABLE);
// Request to start the download
int startResult = DownloaderClientMarshaller.startDownloadServiceIfRequired(this,
pendingIntent, OBBDownloaderService.class);
if (startResult != DownloaderClientMarshaller.NO_DOWNLOAD_REQUIRED) {
// The DownloaderService has started downloading the files,
// show progress
initializeDownloadUI();
return;
} // otherwise, download not needed so we fall through to saying all is OK
else
{
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_FILES_PRESENT);
setResult(RESULT_OK, OutputData);
finish();
}
}
} catch (NameNotFoundException e) {
Log.e(LOG_TAG, "Cannot find own package! MAYDAY!");
e.printStackTrace();
}
} else {
GameActivity.Log.debug("... Can has! Check 'em Dano!");
if(!onlySingleExpansionFileFound()) {
// Do some UI here to figure out which we want to keep
AlertDialog.Builder builder = new AlertDialog.Builder(this);
builder.setCancelable(false)
.setTitle("Select OBB to use")
.setItems(OBBSelectItems, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int item) {
DownloaderActivity.RemoveOBBFile(item);
ProcessOBBFiles();
}
});
AlertDialog alert = builder.create();
alert.show();
}
else {
ProcessOBBFiles();
}
}
}
/**
* Connect the stub to our service on start.
*/
@Override
protected void onStart() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.connect(this);
}
super.onStart();
}
@Override
protected void onPause() {
super.onPause();
GameActivity.Log.debug("In onPause");
if(OutputData.getIntExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_NO_RETURN_CODE) == GameActivity.DOWNLOAD_NO_RETURN_CODE)
{
GameActivity.Log.debug("onPause returning that user quit the download.");
OutputData.putExtra(GameActivity.DOWNLOAD_RETURN_NAME, GameActivity.DOWNLOAD_USER_QUIT);
setResult(RESULT_OK, OutputData);
}
}
/**
* Disconnect the stub from our service on stop
*/
@Override
protected void onStop() {
if (null != mDownloaderClientStub) {
mDownloaderClientStub.disconnect(this);
}
super.onStop();
setResult(RESULT_OK, OutputData);
}
/**
* Critical implementation detail. In onServiceConnected we create the
* remote service and marshaler. This is how we pass the client information
* back to the service so the client can be properly notified of changes. We
* must do this every time we reconnect to the service.
*/
@Override
public void onServiceConnected(Messenger m) {
mRemoteService = DownloaderServiceMarshaller.CreateProxy(m);
mRemoteService.onClientUpdated(mDownloaderClientStub.getMessenger());
}
/**
* The download state should trigger changes in the UI --- it may be useful
* to show the state as being indeterminate at times. This sample can be
* considered a guideline.
*/
@Override
public void onDownloadStateChanged(int newState) {
setState(newState);
boolean showDashboard = true;
boolean showCellMessage = false;
boolean paused;
boolean indeterminate;
switch (newState) {
case IDownloaderClient.STATE_IDLE:
// STATE_IDLE means the service is listening, so it's
// safe to start making calls via mRemoteService.
paused = false;
indeterminate = true;
break;
case IDownloaderClient.STATE_CONNECTING:
case IDownloaderClient.STATE_FETCHING_URL:
showDashboard = true;
paused = false;
indeterminate = true;
break;
case IDownloaderClient.STATE_DOWNLOADING:
paused = false;
showDashboard = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_FAILED_CANCELED:
case IDownloaderClient.STATE_FAILED:
case IDownloaderClient.STATE_FAILED_FETCHING_URL:
case IDownloaderClient.STATE_FAILED_UNLICENSED:
paused = true;
showDashboard = false;
indeterminate = false;
break;
case IDownloaderClient.STATE_PAUSED_NEED_CELLULAR_PERMISSION:
case IDownloaderClient.STATE_PAUSED_WIFI_DISABLED_NEED_CELLULAR_PERMISSION:
showDashboard = false;
paused = true;
indeterminate = false;
showCellMessage = true;
break;
case IDownloaderClient.STATE_PAUSED_BY_REQUEST:
paused = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_PAUSED_ROAMING:
case IDownloaderClient.STATE_PAUSED_SDCARD_UNAVAILABLE:
paused = true;
indeterminate = false;
break;
case IDownloaderClient.STATE_COMPLETED:
showDashboard = false;
paused = false;
indeterminate = false;
validateXAPKZipFiles();
return;
default:
paused = true;
indeterminate = true;
showDashboard = true;
}
int newDashboardVisibility = showDashboard ? View.VISIBLE : View.GONE;
if (mDashboard.getVisibility() != newDashboardVisibility) {
mDashboard.setVisibility(newDashboardVisibility);
}
int cellMessageVisibility = showCellMessage ? View.VISIBLE : View.GONE;
if (mCellMessage.getVisibility() != cellMessageVisibility) {
mCellMessage.setVisibility(cellMessageVisibility);
}
mPB.setIndeterminate(indeterminate);
setButtonPausedState(paused);
}
/**
* Sets the state of the various controls based on the progressinfo object
* sent from the downloader service.
*/
@Override
public void onDownloadProgress(DownloadProgressInfo progress) {
mAverageSpeed.setText(getString(R.string.kilobytes_per_second,
Helpers.getSpeedString(progress.mCurrentSpeed)));
mTimeRemaining.setText(getString(R.string.time_remaining,
Helpers.getTimeRemaining(progress.mTimeRemaining)));
progress.mOverallTotal = progress.mOverallTotal;
mPB.setMax((int) (progress.mOverallTotal >> 8));
mPB.setProgress((int) (progress.mOverallProgress >> 8));
mProgressPercent.setText(Long.toString(progress.mOverallProgress
* 100 /
progress.mOverallTotal) + "%");
mProgressFraction.setText(Helpers.getDownloadProgressString
(progress.mOverallProgress,
progress.mOverallTotal));
}
@Override
protected void onDestroy() {
this.mCancelValidation = true;
super.onDestroy();
}
}