如何实现移动数据下载启停控制?求类似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
相关产品推荐
相关产品推荐

