当从没有互联网的WLAN请求下载时,下载无法在Android 9上开始

jle*_*ee7 5 android wifi flask android-download-manager android-9.0-pie

我正在研究一个Android应用,该应用使用WiFi连接到本地Flask服务器。然后,该应用程序显示存储在服务器(RPi3)上的图像。单击图像会触发下载请求,我希望Android DownloadManager将请求加入队列并下载图像。 WiFi网络不提供互联网访问。

到目前为止,我已经能够在Android 6和Android 8.1设备上对其进行测试,并且一切正常。在多个Android 9设备上进行测试后,下载未开始,但是从本地网络断开连接后,将显示失败的尝试。

阅读有关此内容的其他主题,我尝试了以下方法:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>
Run Code Online (Sandbox Code Playgroud)

并添加在AndroidManifest.xml中

android:networkSecurityConfig="@xml/network_security_config"
Run Code Online (Sandbox Code Playgroud)
.setRequiresCharging(false)
.setAllowedOverMetered(false)
.setAllowedOverRoaming(false)
.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, (String) url);
Run Code Online (Sandbox Code Playgroud)
  • 再次检查权限。这些已启用:
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
Run Code Online (Sandbox Code Playgroud)

这是我创建的下载请求

DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url))
        .setTitle("Some Title")
        .setDescription("Downloading a file")
        .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)
        .setDestinationInExternalPublicDir("some_path", (String) url)
        .setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI);
DownloadManager downloadManager= (DownloadManager) getSystemService(Context.DOWNLOAD_SERVICE);
downloadID = downloadManager.enqueue(request);

Run Code Online (Sandbox Code Playgroud)

瓶服务器(Python3)这个使用返回的图像:

<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>
Run Code Online (Sandbox Code Playgroud)

如前所述,在Android 6和8.1上,它可以正常工作,但没有Android 9设备可以开始下载。如果有我不知道的任何设置或方法,我很乐意了解。

谢谢。

Lan*_*nce 2

这个问题的关键是将进程与网络绑定。这允许您的应用程序使用 wifi,即使 wifi 没有互联网连接。

这是我的代码,它是用 kotlin 编写的,但你也可以将其转换为 Java

在尝试执行请求之前,只需在任何地方调用它即可。对我来说,我将其放置在用作网络实用程序的单例类的初始化中。

fun bindProcessToNetwork() {
    // Unbind the process from the network
    getConnectivityManager().bindProcessToNetwork(null)

    // Bind the process to the network
    getConnectivityManager().bindProcessToNetwork(getWifiNetwork())
}
Run Code Online (Sandbox Code Playgroud)

这些是我在bindProcessToNetwork 中使用的其他方法。您会注意到,我使用了 for 循环来迭代所有网络,并尝试确定哪个是 wifi,而不是使用 using,connectionManager.activeNetworkInfo因为当 wifi 没有互联网连接时,这将返回蜂窝网络。

private fun getConnectivityManager() : ConnectivityManager {
    val context = ApplicationContextProvider.getContext()
    return context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
}

private fun getWifiNetwork(): Network? {
    val networks = getConnectivityManager().allNetworks
    for (network in networks) {
        if (isNetworkWifi(network)) {
            return network
        }
    }
    return null
}

private fun isNetworkWifi(network: Network): Boolean {
    return this.getConnectivityManager().getNetworkCapabilities(network)
        .hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
}
Run Code Online (Sandbox Code Playgroud)

您可以阅读WifiManagerConnectivityManager的文档以获取更多信息。第 28 级 (Android 9) 中已弃用了很多内容。确保您仅在 Android 9 或更高版本中使用此代码。

if(android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.P){
    bindProcessToNetwork(); 
}
Run Code Online (Sandbox Code Playgroud)