【问题标题】:Android API 26 (Oreo) downloading data files from the InternetAndroid API 26 (Oreo) 从互联网下载数据文件
【发布时间】: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();
    }
}

我需要做什么来解决这个问题?我无计可施!

【问题讨论】:

  • 如果您找到了解决方案,何不在这里与社区分享?
  • 好吧,没有人表现出任何兴趣,并且由于我对代码进行了一些更改,因此这里描述的问题不再存在。但是,我将解释我遇到的实际问题以及我如何在答案中解决它。

标签: android android-8.0-oreo


【解决方案1】:

更改代码以更正确地处理请求权限后,原来描述的问题不再存在。但是,我解决了一个完全不同的问题。问题概述:在调试和发布版本中使用 API27 模拟器。在华为 P20 (API27) 上,进行调试,发布失败。一旦我发现我可以为发布版本启用调试,我就能找到问题并修复它。

应用程序的SharedPreferences 似乎以某种方式保留在手机上,即使应用程序已被卸载。问题是 SharedPreferences 说某些文件已经下载,而它们当然不再存在于手机上。我的解决方法是在这种情况下检查文件是否存在,如果不存在,我会重置首选项以便进行下载。

(我怀疑它从应用程序的早期版本中获取以前的 SharedPreferences,从 Google Play 商店安装并卸载,以便我可以测试新版本。)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-19
    • 2011-10-14
    相关资源
    最近更新 更多