You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何实现移动数据下载启停控制?求类似Google Play的下载策略切换方案

实现“仅Wi-Fi下载”/“移动数据+Wi-Fi下载”开关的实用方案

嘿,这个需求我之前做媒体类应用时刚好碰过,实现起来其实很清晰,分几个核心步骤来就行:

1. 先给用户整个设置选项入口

首先得让用户能切换模式,一般放在应用的设置页面里就行。我习惯用单选按钮组来做,和Google Play的样式保持一致,用户看着也眼熟:

<!-- 布局里的单选组 -->
<RadioGroup
    android:id="@+id/download_mode_group"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">

    <RadioButton
        android:id="@+id/wifi_only_option"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="仅Wi-Fi下载" />

    <RadioButton
        android:id="@+id/mobile_allowed_option"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="移动数据+Wi-Fi下载" />
</RadioGroup>

然后要把用户的选择存起来,下次打开应用能记住,用SharedPreferences就够了,简单又实用:

// 保存用户选择的模式
val settingsPref = getSharedPreferences("AppDownloadSettings", Context.MODE_PRIVATE)
download_mode_group.setOnCheckedChangeListener { _, checkedId ->
    val isWifiOnly = checkedId == R.id.wifi_only_option
    settingsPref.edit().putBoolean("wifi_only_download", isWifiOnly).apply()
}

// 页面加载时恢复之前的设置
val defaultToWifiOnly = true // 默认给个仅Wi-Fi,避免用户不小心耗流量
val savedWifiOnly = settingsPref.getBoolean("wifi_only_download", defaultToWifiOnly)
if (savedWifiOnly) {
    wifi_only_option.isChecked = true
} else {
    mobile_allowed_option.isChecked = true
}

2. 做个网络状态判断的工具方法

接下来得能判断当前是Wi-Fi还是移动数据,这里要注意Android版本适配,旧的getActiveNetworkInfo()已经废弃了,用新的NetworkCapabilities来做:

// 判断当前是否连的Wi-Fi
fun isOnWifi(context: Context): Boolean {
    val connManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork = connManager.activeNetwork ?: return false
    val networkCapabilities = connManager.getNetworkCapabilities(activeNetwork) ?: return false
    return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)
}

// 判断当前是否连的移动数据
fun isOnMobile(context: Context): Boolean {
    val connManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
    val activeNetwork = connManager.activeNetwork ?: return false
    val networkCapabilities = connManager.getNetworkCapabilities(activeNetwork) ?: return false
    return networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)
}

别忘了在AndroidManifest.xml里加必要的权限:

<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />

3. 下载前的校验逻辑

最后就是在触发下载前,先检查用户设置和当前网络是否匹配:

fun startMediaDownload(context: Context, mediaUrl: String) {
    val settingsPref = context.getSharedPreferences("AppDownloadSettings", Context.MODE_PRIVATE)
    val isWifiOnly = settingsPref.getBoolean("wifi_only_download", true)
    
    val wifiConnected = isOnWifi(context)
    val mobileConnected = isOnMobile(context)
    
    when {
        wifiConnected -> {
            // Wi-Fi可用,直接开下
            startActualDownload(mediaUrl)
        }
        mobileConnected && !isWifiOnly -> {
            // 移动数据可用,且用户允许,开始下载
            startActualDownload(mediaUrl)
        }
        else -> {
            // 不符合条件,给用户弹个提示
            Toast.makeText(context, "当前网络不允许下载,请切换Wi-Fi或修改下载设置", Toast.LENGTH_LONG).show()
        }
    }
}

// 这里写你实际的下载逻辑,比如用OkHttp、DownloadManager都可以
private fun startActualDownload(mediaUrl: String) {
    // 你的下载代码写这儿~
}

额外的优化小技巧

  • 监听网络变化:如果用户下载到一半切了网络(比如从Wi-Fi切到移动数据,且设置是仅Wi-Fi),可以暂停下载并提示用户,用ConnectivityManager.NetworkCallback就能监听网络状态变化。
  • 大文件二次确认:如果用户用移动数据下大文件,最好弹个对话框让用户确认,避免不小心耗太多流量,用户体验会好很多。
  • 适配高版本Android:如果你的应用目标SDK是31+,注意权限的变化,ACCESS_NETWORK_STATE是正常权限,不需要动态申请,监听网络变化也不用位置权限了,直接用NetworkCallback就行。

内容的提问来源于stack exchange,提问作者Shayan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:46:56