1

In swift there is a wonderful thing

if UIApplication.shared.canOpenURL(myUrl) {
    // url can be opened
    UIApplication.shared.open(myUrl) { success in
        if !success {
            //...
        }
    }
} else {
   // and cannot
}

Is there an analogue in Kotlin?

MaxB
  • 635
  • 1
  • 9
  • 22

3 Answers3

1

Going off the documentation for canOpenURL(), it doesn't check if the URL is available, only if there's an app available that can handle its scheme.

On Android, the URL has to be wrapped in an Intent to be able to open it. You can then check if an app is available for the Intent by using the PackageManager.

val intent = Intent(Intent.ACTION_VIEW).apply {
    data = Uri.parse(url)
}

if (intent.resolveActivity(packageManager) != null) {
    // url can be opened with startActivity(intent) or requireContext().startActivity(intent)
} else {
    // ...
}

If this function is in a Fragment rather than Activity, prefix packageManager with requireContext()..


Edit:

You can check if it's possible to connect to the URL using a function like this (adapted from here):

suspend fun canConnect(url: String): Boolean = withContext(Dispatchers.IO) {
    // We want to check the current URL
    HttpURLConnection.setFollowRedirects(false)
    val httpURLConnection = (URL(url).openConnection() as HttpURLConnection)

    // We don't need to get data
    httpURLConnection.requestMethod = "HEAD"

    // Some websites don't like programmatic access so pretend to be a browser
    httpURLConnection.setRequestProperty(
        "User-Agent",
        "Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 (.NET CLR 3.5.30729)"
    )

    // We only accept response code 200
    return@withContext try {
        httpURLConnection.responseCode == HttpURLConnection.HTTP_OK
    } catch (e: IOException) {
        false
    } catch (e: UnknownHostException){
        false
    }
}

It has to be done asynchronously since you're making a connection, or else you risk an Application Not Responding error. So I made it a suspend function that you can call from a coroutine.

Tenfour04
  • 83,111
  • 11
  • 94
  • 154
  • Thanks for our answer. As I understand it starts a new activity by url, but in my case I don't need it. I just need to establish a connection by this url and get a boolean value it was successful or not. That is, firstly I should only check that connection can be successful and after that I have to connect to receive a boolean state response. Is it possible with this method? – MaxB Jun 11 '20 at 19:52
  • No, not with an Intent. But that's not what the iOS method would do either. If you need to ping the URL, you'll need to do it asynchronously to avoid an Activity Not Responding error. See edit. – Tenfour04 Jun 11 '20 at 20:09
  • I have a trouble with `httpURLConnection.responseCode`. It freezes execution. I run your example in the AsyncTask – MaxB Jun 13 '20 at 13:35
-1

You can check if a URL is valid or not using patterns. See the sample function:

fun isValidUrl(url: String): Boolean {
        val p = Patterns.WEB_URL
        val m = p.matcher(url)
        return m.matches()
    }

Once the URL is validated, you can verify whether the device is able to connect to the URL or not using below method:

 fun isAPIAvailable(c: Context, url:String): Boolean {
            return try {
                val ipAddr: InetAddress = InetAddress.getByName(url)
                ipAddr.hostAddress != ""
            } catch (e: Exception) {
                false
            }
        }
Alpha 1
  • 4,118
  • 2
  • 17
  • 23
  • The OP is not asking if a URL is valid. – Brill Pappin Apr 24 '22 at 14:01
  • @brill-pappin You should have checked the edit history of the question before commenting here. The answer was a valid response to the question `How to check whether it is possible to open url in Kotlin`. – Alpha 1 Apr 25 '22 at 03:25
  • 1
    Right. And the question is clear, based on the Swift code the OP posted. Although i think the question could have been worded better. – Brill Pappin Apr 26 '22 at 14:34
-1

Add isValidUrl():

 fun String.isValidUrl(): Boolean = Patterns.WEB_URL.matcher(this).matches()
            && URLUtil.isValidUrl(url)

Then check:

val url = "www.myWebpage.com"
if (!url.isValidUrl()) {
    // url can be opened
}else{
   // and cannot
}
Krishna Sony
  • 1,286
  • 13
  • 27