Created
August 9, 2025 04:33
-
-
Save raspberrypisig/29bc00e856903ac5414c6bc01f79d817 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import android.net.nsd.NsdManager | |
import android.net.nsd.NsdServiceInfo | |
import android.os.Build | |
import androidx.annotation.RequiresApi | |
import kotlinx.coroutines.suspendCancellableCoroutine | |
import java.util.concurrent.Executor | |
import kotlin.coroutines.resume | |
import kotlin.coroutines.resumeWithException | |
// ... other code ... | |
/** | |
* The core suspendable coroutine for resolving a service. | |
*/ | |
private suspend fun resolveServiceInternal( | |
nsdManager: NsdManager, | |
serviceInfo: NsdServiceInfo | |
): DiscoveredService = suspendCancellableCoroutine { continuation -> | |
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) { | |
val executor = Executor { command -> command.run() } // You can use a more specific executor if needed | |
val callback = object : NsdManager.ServiceInfoCallback { | |
override fun onServiceInfoCallbackRegistrationFailed(errorCode: Int) { | |
val error = NsdException("Service info callback registration failed for ${serviceInfo.serviceName}", errorCode) | |
continuation.resumeWithException(error) | |
} | |
override fun onServiceUpdated(resolvedInfo: NsdServiceInfo) { | |
continuation.resume(resolvedInfo.toCommon()) | |
} | |
override fun onServiceLost() { | |
// This callback indicates the service is no longer resolvable. | |
// You might want to handle this differently, e.g., by throwing a specific exception | |
// or returning null, depending on your desired behavior. | |
val error = NsdException("Service lost during resolution: ${serviceInfo.serviceName}", 0 /* Or a custom error code */) | |
continuation.resumeWithException(error) | |
} | |
override fun onServiceUnregistered() { | |
// This is typically for when a service *you* registered is unregistered. | |
// It might not be directly relevant in the context of resolving a *discovered* service, | |
// but you should be aware of its purpose. | |
} | |
} | |
nsdManager.registerServiceInfoCallback(serviceInfo, executor, callback) | |
continuation.invokeOnCancellation { | |
// Important: Unregister the callback when the coroutine is cancelled | |
// to avoid leaks and unnecessary work. | |
nsdManager.unregisterServiceInfoCallback(callback) | |
} | |
} else { | |
// Fallback to the deprecated version for older Android versions | |
@Suppress("DEPRECATION") | |
val listener = object : NsdManager.ResolveListener { | |
override fun onResolveFailed(failedServiceInfo: NsdServiceInfo, errorCode: Int) { | |
val error = NsdException("Failed to resolve service: ${failedServiceInfo.serviceName}", errorCode) | |
if (continuation.isActive) { // Check if coroutine is still active | |
continuation.resumeWithException(error) | |
} | |
} | |
override fun onServiceResolved(resolvedInfo: NsdServiceInfo) { | |
if (continuation.isActive) { // Check if coroutine is still active | |
continuation.resume(resolvedInfo.toCommon()) | |
} | |
} | |
} | |
@Suppress("DEPRECATION") | |
nsdManager.resolveService(serviceInfo, listener) | |
} | |
} | |
// ... other code ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment