gpt4 book ai didi

android - Android Kotlin刷新textview

转载 作者:行者123 更新时间:2023-12-02 13:41:20 25 4
gpt4 key购买 nike

我想在textview中每次更改时更新android系统的本地ip,这是我的代码。
获取ip的功能是这个

fun getIpv4HostAddress(): String {
NetworkInterface.getNetworkInterfaces()?.toList()?.map { networkInterface ->
networkInterface.inetAddresses?.toList()?.find {
!it.isLoopbackAddress && it is Inet4Address
}?.let { return it.hostAddress }
}
return ""
}
而MainActivity.tk的onCreate中的代码是这样的
val textView: TextView = findViewById(R.id.getIP)
textView.setText("IP local: " + getIpv4HostAddress())
textView.invalidate()
我希望它在texview中进行实时更新和显示,例如在设置和删除飞行模式或更改网络后wifi->移动设备-> wifi
如申请表所示,我离开了这里,请有人帮助我

最佳答案

除了提取IPv4地址外,我几乎已经准备好使用该问题的解决方案,因此我将其张贴在这里,以便您可以使用它。
基本上,该解决方案由两个主要组件组成:一个“服务”,用于侦听网络更改;一个RX subject,您向其订阅并发布有关网络更改的更新。
步骤0:准备
确保您的AndroidManifest.xml文件具有下一个权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
您的应用必须启用兼容性选项才能使用Java 8功能。在 build.gradle文件中添加以下行:
android {
...
compileOptions {
targetCompatibility = "8"
sourceCompatibility = "8"
}
}
为了使用RX Kotlin,添加下一个依赖项:
implementation 'io.reactivex.rxjava3:rxandroid:3.0.0'
implementation 'io.reactivex.rxjava3:rxkotlin:3.0.0'
步骤1:实施网络更改监听器服务
为了使代码尽可能简洁,省略了导入。 NetworkReachabilityService不是您可以启动的常规Android服务,即使该应用被终止,它也将运行。这是一个将侦听器设置为 ConnectivityManager 并处理与网络状态有关的所有更新的类。
任何类型的更新都以类似的方式处理:有所更改->使用适当的值发布 NetworkState对象。每次更改时,我们都可以请求将IPv4显示在UI中(请参阅第3步)。
sealed class NetworkState {
data class Available(val type: NetworkType) : NetworkState()
object Unavailable : NetworkState()
object Connecting : NetworkState()
object Losing : NetworkState()
object Lost : NetworkState()
}

sealed class NetworkType {
object WiFi : NetworkType()
object CELL : NetworkType()
object OTHER : NetworkType()
}

class NetworkReachabilityService private constructor(context: Application) {

private val connectivityManager: ConnectivityManager =
context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager

private val networkCallback = object : ConnectivityManager.NetworkCallback() {
// There are more functions to override!

override fun onLost(network: Network) {
super.onLost(network)
postUpdate(NetworkState.Lost)
}

override fun onUnavailable() {
super.onUnavailable()
postUpdate(NetworkState.Unavailable)
}

override fun onLosing(network: Network, maxMsToLive: Int) {
super.onLosing(network, maxMsToLive)
postUpdate(NetworkState.Losing)
}

override fun onAvailable(network: Network) {
super.onAvailable(network)
updateAvailability(connectivityManager.getNetworkCapabilities(network))
}

override fun onCapabilitiesChanged(
network: Network,
networkCapabilities: NetworkCapabilities
) {
super.onCapabilitiesChanged(network, networkCapabilities)
updateAvailability(networkCapabilities)
}
}

companion object {
// Subscribe to this subject to get updates on network changes
val NETWORK_REACHABILITY: BehaviorSubject<NetworkState> =
BehaviorSubject.createDefault(NetworkState.Unavailable)

private var INSTANCE: NetworkReachabilityService? = null

@RequiresPermission(android.Manifest.permission.ACCESS_NETWORK_STATE)
fun getService(context: Application): NetworkReachabilityService {
if (INSTANCE == null) {
INSTANCE = NetworkReachabilityService(context)
}
return INSTANCE!!
}
}

private fun updateAvailability(networkCapabilities: NetworkCapabilities?) {
if (networkCapabilities == null) {
postUpdate(NetworkState.Unavailable)
return
}
var networkType: NetworkType = NetworkType.OTHER

if (networkCapabilities.hasTransport(TRANSPORT_CELLULAR)) {
networkType = NetworkType.CELL
}
if (networkCapabilities.hasTransport(TRANSPORT_WIFI)) {
networkType = NetworkType.WiFi
}

postUpdate(NetworkState.Available(networkType))
}

private fun postUpdate(networkState: NetworkState) {
NETWORK_REACHABILITY.onNext(networkState)
}

fun pauseListeningNetworkChanges() {
try {
connectivityManager.unregisterNetworkCallback(networkCallback)
} catch (e: IllegalArgumentException) {
// Usually happens only once if: "NetworkCallback was not registered"
}
}

fun resumeListeningNetworkChanges() {
pauseListeningNetworkChanges()
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
connectivityManager.registerDefaultNetworkCallback(networkCallback)
} else {
connectivityManager.registerNetworkCallback(
NetworkRequest.Builder().build(),
networkCallback
)
}
}
}
步骤2:实施一种提取IPv4(奖励IPv6)的方法
我必须对您的IPv4提取进行一些修改,因为在设备明显有一个IPv4地址的情况下,它没有返回任何IPv4地址。这是分别提取IPv4和IPv6地址的两种方法。使用 this SO answer修改了有关如何提取IP地址的方法。总体而言, inetAddresses与IP地址值的映射相同率为90%。
将这两个方法添加到 NetworkReachabilityService类:
fun getIpv4HostAddress(): String? =
NetworkInterface.getNetworkInterfaces()?.toList()?.mapNotNull { networkInterface ->
networkInterface.inetAddresses?.toList()
?.filter { !it.isLoopbackAddress && it.hostAddress.indexOf(':') < 0 }
?.mapNotNull { if (it.hostAddress.isNullOrBlank()) null else it.hostAddress }
?.firstOrNull { it.isNotEmpty() }
}?.firstOrNull()

fun getIpv6HostAddress(): String? =
NetworkInterface.getNetworkInterfaces()?.toList()?.mapNotNull { networkInterface ->
networkInterface.inetAddresses?.toList()
?.filter { !it.isLoopbackAddress && it is Inet6Address }
?.mapNotNull { if (it.hostAddress.isNullOrBlank()) null else it.hostAddress }
?.firstOrNull { it.isNotEmpty() }
}?.firstOrNull()
步骤3:更新使用者介面
与UI相关的简单解决方案是直接订阅 NETWORK_REACHABILITY主题,并且通过该主题收到的每次更改,我们都会从 NetworkReachabilityService中提取IPv4数据并将其显示在UI中。您要查看的两个主要方法是 subscribeToUpdatesupdateIPv4Address。并且不要忘记使用 unsubscribeFromUpdates取消订阅,以防止内存泄漏。
class MainActivity : AppCompatActivity() {

private val compositeDisposable = CompositeDisposable()
private lateinit var textView: TextView

override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
textView = findViewById(R.id.text_view)

val service = NetworkReachabilityService.getService(application)
service.resumeListeningNetworkChanges()

subscribeToUpdates()
}

override fun onDestroy() {
super.onDestroy()
unsubscribeFromUpdates()
}

private fun unsubscribeFromUpdates() {
compositeDisposable.dispose()
compositeDisposable.clear()
}

private fun subscribeToUpdates() {
val disposableSubscription =
NetworkReachabilityService.NETWORK_REACHABILITY
.observeOn(AndroidSchedulers.mainThread())
.subscribe({ networkState ->
// We do not care about networkState right now
updateIPv4Address()
}, {
// Handle the error
it.printStackTrace()
})

compositeDisposable.addAll(disposableSubscription)
}

private fun updateIPv4Address() {
val service = NetworkReachabilityService.getService(application)
textView.text = service.getIpv4HostAddress()
}
}
回顾
使用 ConnectivityManager实例,我们设置了一个侦听器,该侦听器会对网络的任何变化使用react。每次更改都会触发一个更新,该更新会将值发布到拥有最新网络状态的RX主题。通过订阅该主题,我们可以跟踪网络状态更改并假定设备的地址已更改,因此我们刷新显示在 TextView中的IPv4值。
我认为这段代码适合在GitHub上使用,所以这里是 the link to the project

关于android - Android Kotlin刷新textview,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63201737/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com