【发布时间】:2018-07-09 16:16:37
【问题描述】:
我现在已经解决了这个问题,结果却完全不同。由于没有人回复,所以可以删除问题。
为了支持 API 26 以后,我已经使用 Android Studio 更新了我的应用程序以明确要求我需要的危险权限(WRITE_EXTERNAL_STORAGE、ACCESS_FINE_LOCATION)。它还使用普通权限 INTERNET,无需询问用户即可授予。
应用程序在首次运行时会尝试从托管这些文件的特定网站下载一些数据文件(所有文本)到本地存储。虽然它在 API 27 模拟器中运行良好,但在我的运行 Android 8.1.0(华为 P20)的手机上测试时却失败了。
成功下载了两个文件,但是在第三个文件上,当在连接上调用 getInputStream 时,它会抛出一个 IO 异常“文件过早结束”,存在 0 字节传输,并且应用程序在显示失败消息后退出。但是,如果我在应用程序的设置中(在手机上)清除数据,然后在手机上重新启动应用程序,则所有文件的完整下载都是成功的。
这是下载每个文件时调用的函数(else 子句是相关的):
// Download file from the internet
public static boolean downloadFile(String urlString, String fileName)
{
mDownloadStatus = false;
// In local file mode, download.tmp must have been pre-loaded
if (LOCAL_FILE_MODE && fileName.equals(LOCAL_FILE_NAME))
{
File f = new File(dataDir, LOCAL_FILE_NAME);
if (f.exists())
mDownloadStatus = true;
else
mErrorString = "Pre-loaded " + LOCAL_FILE_NAME + " not found";
}
else
{
CountDownLatch latch = new CountDownLatch(1);
Runnable r = new DownloadFile(urlString, fileName, latch);
new Thread(r).start();
try
{
// Wait for completion
latch.await();
}
catch (InterruptedException e) {}
}
return mDownloadStatus;
}
这是 DownloadFile 类:
public class DownloadFile implements Runnable
{
private String mUrlString;
private String mFileName;
private CountDownLatch mLatch;
public DownloadFile(String urlString, String fileName, CountDownLatch latch)
{
mUrlString = urlString;
mFileName = fileName;
mLatch = latch;
}
public void run()
{
HttpURLConnection urlConnection = null;
Spine.mDownloadStatus = false;
try
{
// set the download URL, a url that points to a file on the internet
// this is the file to be downloaded
URL url = new URL(mUrlString);
// create the new connection
urlConnection = (HttpURLConnection) url.openConnection();
// set up some things on the connection
urlConnection.setRequestMethod("GET");
urlConnection.setDoOutput(true);
urlConnection.setUseCaches(false);
// and connect!
urlConnection.connect();
// create a new file, specifying the path, and the filename
// which we want to save the file as.
File file = new File(Spine.dataDir, mFileName);
// this will be used to write the downloaded data into the file we
// created
FileOutputStream fileOutput = new FileOutputStream(file);
// this will be used in reading the data from the internet
InputStream inputStream = urlConnection.getInputStream();
// create a buffer...
byte[] buffer = new byte[1024];
int bufferLength = 0; // used to store a temporary size of the buffer
// now, read through the input buffer and write the contents to the
// file
while ((bufferLength = inputStream.read(buffer)) > 0)
{
// add the data in the buffer to the file in the file output
// stream (the file on the sd card
fileOutput.write(buffer, 0, bufferLength);
}
// close the output stream when done
fileOutput.close();
Spine.mDownloadStatus = true;
}
// catch some possible errors...
catch (IOException e)
{
Spine.mErrorString = e.getMessage();
}
if (urlConnection != null)
urlConnection.disconnect();
// Signal completion
mLatch.countDown();
}
}
我需要做什么来解决这个问题?我无计可施!
【问题讨论】:
-
如果您找到了解决方案,何不在这里与社区分享?
-
好吧,没有人表现出任何兴趣,并且由于我对代码进行了一些更改,因此这里描述的问题不再存在。但是,我将解释我遇到的实际问题以及我如何在答案中解决它。