我已经制作了Android应用程序,使用Android Download Manager类从服务器下载zip文件,然后解压缩文件并将其存储到图片文件夹中的SD卡上。在某些手机上。
zip文件没有下载,即使我保留了几个小时,下载管理器进度条也从未显示进度。而在其他手机上这完美无缺。
文件大小为40 MB。是否有任何已知的Android Download Manager限制或.zip文件的情况?
答案 0 :(得分:0)
我一直在使用此类的变体(使用另一个类进行解压缩,但是由于这里的问题与下载有关,所以我建议使用)此类用于下载(文件名保留了特定的实现,但这只是重命名的问题...)。可以从Runnable对象的run方法内部调用此类的work()方法进行并行线程处理,如最初的注释所示:
package com.package;
/*
This class is intended to download file filtering purpose and suffix from the server.
IMPORTANT:This is intended to be instantiated within a separate thread (i.e., != UI Thread)
*/
import android.support.v7.app.AppCompatActivity;
import android.widget.Toast;
final class FileDownloader
{
// Declaring a the maximum buffer size
private static final int MAXIMUM_BUFFER_SIZE = 1024;
// Declaring static final byte fields for coding the status
protected static final byte ISDOWNLOADING = 0;
protected static final byte ERROROCCURRED = 1;
protected static final byte DOWNLOADISCOMPLETE = 2;
// Declaring a private URL field for storing the file for downloading
private java.net.URL url = null;
// Declaring a private int field for storing the file size in bytes
private int filesize;
// Declaring a private int field for storing the amount of downloaded bytes
private int bytesDownloaded;
// Declaring a private byte field for storing the current status of the download
private byte currentStatus;
// A private static final string for storing the server contents location
private static final String SERVER = "https://server.com/zipfiles/";
// Declaring a private field for storing the caller context, used for defining
// the path for saving files
private android.content.Context callerContext = null;
// The following rule is going to be applied for distributing purpose and their contents:
// 'purpose.x.zip' zip file to store the folders of the the x purpose_id and its inherent
// structure
private static final String PURPOSE= "purpose";
private String x = null;
private static final String SUFFIX = "zip";
// The remote file to be downloaded is going to be [stringed as]:
// SERVER + PURPOSE + "." + ((String.valueOf(x)).trim()) + "." + suffix
private String remoteFile = null;
// Defining a private static final File field for storing the purposes' contents within it.
// Specifically, this is being designed to be:
// java.io.File seekingRegisteredUserFolder =
// new java.io.File(callerContext.getFilesDir(), "RegisteredUser");
private final java.io.File seekingRegisteredUserFolder;
// The class constructor. The constructor depends on constructing elements for downloading
// the remoteFile respective to the element_ [cf. constructor parameter] under consideration,
// viz.:
protected FileDownloader(final String x_, final android.content.Context callerContext_)
throws
java.net.MalformedURLException,
java.io.FileNotFoundException,
java.lang.SecurityException
{
this.x = x_;
this.remoteFile = SERVER + PURPOSE + "." + ((String.valueOf(this.x)).trim()) + "." + SUFFIX;
int parsedW = 0;
try
{
parsedW = Integer.parseInt(x_);
}
catch (Exception throwableThrownParsingW)
{
throw new java.net.MalformedURLException();
}
// Implementation specific
if (parsedW < 1)
{
throw new java.net.MalformedURLException();
}
this.callerContext = callerContext_;
this.seekingRegisteredUserFolder = new java.io.File((this.callerContext).getFilesDir(), "RegisteredUser");
if (!((this.seekingRegisteredUserFolder).exists()))
{
throw new java.io.FileNotFoundException();
}
this.url = new java.net.URL(this.remoteFile);
this.filesize = -1;
this.bytesDownloaded = 0;
this.currentStatus = ISDOWNLOADING;
}
// Begins the file download. This is to be called under an object of this class instantiation
boolean work()
{
final java.io.RandomAccessFile[] randomAccessFile = {null};
final java.io.InputStream[] inputStream = {null};
final java.io.File[] purpose = {null};
try
{
purpose[0] = new java.io.File(seekingRegisteredUserFolder, (PURPOSE + "." + x + "." + SUFFIX));
// Opens a connection to the URL via ssl
final javax.net.ssl.HttpsURLConnection[] connection = {null};
connection[0] = (javax.net.ssl.HttpsURLConnection) url.openConnection();
// Defines the file part to download
connection[0].setRequestProperty("Range", "bytes=" + bytesDownloaded + "-");
// Connects to the server
connection[0].connect();
// The response code must be within the 200 range
if ((connection[0].getResponseCode() / 100) != 2)
{
currentStatus = ERROROCCURRED;
}
// Inferring the validity of the content size
final int[] contentLength = {0};
contentLength[0] = connection[0].getContentLength();
if (contentLength[0] < 1)
{
currentStatus = ERROROCCURRED;
}
// Configuring the download size, case not yet configured
if (filesize == -1)
{
filesize = contentLength[0];
}
// Opens the file, seeking its final
randomAccessFile[0] = new java.io.RandomAccessFile(purpose[0], "rw");
randomAccessFile[0].seek(bytesDownloaded);
inputStream[0] = connection[0].getInputStream();
while (currentStatus == ISDOWNLOADING)
{
// Defines the buffer according to the left amount of file to complete
byte[] byteBuffer = null;
if ((filesize - bytesDownloaded) > MAXIMUM_BUFFER_SIZE)
{
byteBuffer = new byte[MAXIMUM_BUFFER_SIZE];
}
else
{
byteBuffer = new byte[filesize - bytesDownloaded];
}
// Reads from server to the buffer
int read = inputStream[0].read(byteBuffer);
if (read == -1)
{
break;
}
// Writes from buffer to file
randomAccessFile[0].write(byteBuffer, 0, read);
bytesDownloaded += read;
}
// Changing the status for complete since this point of code has been reached
if (currentStatus == ISDOWNLOADING)
{
currentStatus = DOWNLOADISCOMPLETE;
}
}
catch (java.lang.Exception connectionException)
{
currentStatus = ERROROCCURRED;
}
finally
{
// Closes the [RandomAccessFile] file
if (randomAccessFile[0] != null)
{
try
{
randomAccessFile[0].close();
}
catch (java.lang.Exception closingFileException)
{
currentStatus = ERROROCCURRED;
}
}
if (inputStream[0] != null)
{
try
{
inputStream[0].close();
}
catch (java.lang.Exception closingConnectionException)
{
currentStatus = ERROROCCURRED;
}
}
}
if ((currentStatus == DOWNLOADISCOMPLETE) && (purpose[0] != null) &&
(purpose[0]).isFile() && (purpose[0].length() > 0) && (purpose[0].length() == filesize))
{
((AppCompatActivity) callerContext).runOnUiThread
(
new Runnable()
{
@Override
public final void run()
{
Toast.makeText(callerContext, "Downloaded: " + remoteFile.substring(remoteFile.indexOf(SERVER) + SERVER.length()), Toast.LENGTH_LONG).show();
}
}
);
return true;
}
return false;
}
}