Make url with custom scheme clickable in textview - android

I have urls with custom schemes that are displayed in a TextView. The problem is that when I try using something like Linkify not the whole text section is clickable. I am following this link to try to get it working but the link is only on google.com
Code copied from link but I am using Kotlin:
val fullString = "This sentence contains a custom://www.google.com custom scheme url"
mTextView.text = fullString
val urlDetect = Pattern.compile("([a-zA-Z0-9]+):\\/\\/([a-zA-Z0-9.]+)") // this is a terrible regex, don't use it. There are better url regexs.
val matcher = urlDetect.matcher(fullString)
var scheme: String? = null
while (matcher.find()) {
val customSchemedUrl = matcher.group(0)
val uri = Uri.parse(customSchemedUrl)
// Now you could create an intent yourself...
// ...or if you want to rely on Linkify keep going
scheme = uri.getScheme()
break
}
if (!TextUtils.isEmpty(scheme)) {
Linkify.addLinks(mTextView, urlDetect, scheme)
}
the output is: (custom://www.google.com) where only google.com is a link.

maybe a clickable span would be of help here?
https://developer.android.com/reference/android/text/style/ClickableSpan.html

Related

How to insert path between absoluteURL and parameter?

My url looks like this: https://test.com/test#someParameter
And i want to insert "/site" between the url and the parameter without string operations, because using string operations on urls are not best practise.
The final url should look like this: https://test.com/test/site#someParameter
I tried using .apply but it didn't work:
URI(url).apply { path += "/site" }.toString()
I believe that a safe way to do it is using urllib
import urllib
args = {"site": "site", "param": "some_parameter"}
url = "https://test.com/test/{}#{}".format(urllib.urlencode(args))

Android Uri building ignore parameters except if at least one parameter is present

I have a strange behaviour when I click on a link in a webview that is a PDF file link.
For example: https://my.server.com/foobar.pdf
So I have made some research and this link will start a dowload in my webview.
I have a DownloadListener and a onDownloadStart method.
In it I send the URL to Android so that PDF apps on phone can open it.
My strange behaviour is here. If the link in the webview does not have parameters I am not able to add parameters in the URL but if the URL have one parameter -> my parameters are added.
Example will be more meaningful.
Here url in link is "https://my.server.com/foobar.pdf"
val uriTest = Uri.parse(url).buildUpon()
.appendQueryParameter("key1", val1)
.appendQueryParameter("key2", val2)
.build()
val intent = Intent(Intent.ACTION_VIEW, uriTest)
startActivity(intent)
So when the PDF app called by startActivity(intent) call the URL on my server I have no parameters in URL and on my server I see a call to "https://my.server.com/foobar.pdf" not to "https://my.server.com/foobar.pdf?key1=val1&key2=val2".
BUT
If the url in link is "https://my.server.com/foobar.pdf?t=t" when my Android code is executed on my server side I can see a call to ""https://my.server.com/foobar.pdf?t=t&key1=val1&key2=val2". My parameters are added in this case.
Is it normal? Am I missing something?
Thanks for your help!
---EDIT---
I also tried to add my parameters in the string directly and it is the same -> my parameters are ignored until the URL I get has one parameter.
Example: I get "https://my.server.com/foobar.pdf" and I do:
val url1 = url + "?key1=" + val1
or
val url1 = "$url?key1=$val1"
val yourUrl = StringBuilder("https://my.server.com/foobar.pdf")
val parameters = hashMapOf<String, String>()
parameters["key1"] = "val1"
parameters["key2"] = "val2"
var count = 0
for (i in parameters.entries) {
if (count == 0)
yourUrl.append("?${i.key}=${i.value}&")
else
yourUrl.append("${i.key}=${i.value}&")
count++
}
val yourNewUrl = yourUrl.substring(0, yourUrl.length - 1)
Timber.e("URL: $yourNewUrl")
val intent = Intent(Intent.ACTION_VIEW, Uri.parse(yourNewUrl))
startActivity(intent)
Happy coding :)

How to check whether the youtube url has username or channel?

i want to check the youtube url is username or channelid ?
for example https://www.youtube.com/user/aaaaaaaa
https://www.youtube.com/channel/UC--------hdch . how to check?
You can check if the url contains the string user for User and channel for Channel.
String url = "https://www.youtube.com/user/aaaaaaaa"
if(url.contains("/channel/")){
//url is a channel url
}else if(url.contains("/user/")){
//url is a user url
}
Well the problem is that you have to verify that there is a link to user or a channel directly after the youtube address,
val url: String = "https://www.youtube.com/user/aaaaaaaa"
if(url.contains("/channel/")){
//url is a channel url
}else if(url.contains("/user/")){
//url is a user url
}
Here I didn't used to check if the string contains youtube.com/user/ because some urls may have youtu.be/user/ which is valid and offical address, so just checking that there is forward slash before and after the identifier it makes sure that it'll work as expected!
EDIT1:
OP wants a regex solution so:
val regex = Regex("""(?:youtube\.com|youtu\.be)\/(user|channel)""")
val result = regex.find("https://www.youtube.com/user/aaaaaaaa")
when(result!!.groupValues[1]){
"user" -> //code
"channel" -> //code
else -> {} //or replace {} with code
}
EDIT2:
You could use this expression to get the information about the url
val regex = Regex("""(?:https:\/\/)*(?:www\.)*(youtube\.com|youtu\.be)\/(user|channel)\/(\w+)""")
val result = regex.find("https://www.youtube.com/user/aaaaaaaa")!!
when(result.groupValues[2]){
"user" -> //code
"channel" -> //code
else -> {} //or replace {} with code
}
println(result.groupValues[0]) //https://www.youtube.com/user/aaaaaaaa
println(result.groupValues[1]) //youtube.com
println(result.groupValues[2]) //user
println(result.groupValues[3]) //aaaaaaaa
EDIT3:
As OP suggested this does not work for a symbol (non word literal) hence, instead of /w+ you could use .+
So the finalized regex would be
(?:https:\/\/)*(?:www\.)*(youtube\.com|youtu\.be)\/(user|channel)\/(.+)

Validate Specfic URL input in EditText for android

My application is about downloading an image from a specific website e.g. www.example.com/img-...
The user will input the url for the img to the EditText field. e.g. www.example.com/img-123
My problem is that when the user inputs a wrong URL, i.e. one with no no image, it is empty e.g. www.example.com/img-222
I want to detect this and tell the user their input does not link to an image and try again.
I'm using the isValidUrl() function to detect if the input is a WEB_URL only but what I want is that when the entered url has no image, the program should tell them it is an incorrect format for url.
I'm using Jsoup.connect(url).get(); to connect to the url and get the image and save it
private boolean isValidUrl(String url) {
Pattern p = Patterns.WEB_URL;
Matcher m = p.matcher(url);
if(m.matches())
return true;
else
return false;
}
We can use android native android.webkit.URLUtil class to validate any kind of url.
URLUtil.isValidUrl(downloadImaheEditText.getText().toString());
it will return true if valid else false.
String[] schemes = {"http","https"}; //DEFAULT schemes = "http", "https", "ftp"
UrlValidator urlValidator = new UrlValidator(schemes);
if (urlValidator.isValid("http://www.google.com")) {
//url is valid
}else{
//url is invalid
}
Use Apache commons-validator URLValidator class
I tried this and it worked for me. Please find the code snippet below:
public static boolean isURL(String url) {
Pattern p = Patterns.WEB_URL;
Matcher m = p.matcher(url.toLowerCase());
return m.matches();
}

use of iframe ajax in android browser

I have a html page which is used in a android application . From this page i need to post data to server and response is an attachment which needs to be downloaded. I used the hidden iframe hack for this purpose. But unfortunately its failing. Can anyone explain the root cause?
function download(){
var iframe = document.createElement("iframe");
//iframe.src = "http://localhost:9080/HttpOptions/MultiPartServlet";
iframe.style.display = "none";
iframe.id = "myframe";
document.body.appendChild(iframe);
var doc = document.getElementById("myframe").contentWindow.document;
var form = doc.createElement("form");
form.setAttribute("name", "theForm"); // give form a name
form.setAttribute("id", "theForm"); // give form a name
form.setAttribute("action", "http://localhost:9080/HttpOptions/MultiPartServlet"); // give form an action
form.setAttribute("method", "post"); // give form a method
var par1 = doc.createElement("input");
par1.setAttribute("name", "theSubmit"); // give input a name
par1.setAttribute("type", "submit"); // make it a submit button
par1.setAttribute("value", "Submit"); // give input a value
var par2 = doc.createElement("input");
par2.setAttribute("name", "name"); // give input a name
par2.setAttribute("type", "text"); // make it a submit button
par2.setAttribute("value", "deepak"); // give input a value
form.appendChild(par1);
form.appendChild(par2);
doc.body.appendChild(form);
var myframe = document.getElementById('myframe');
var innerDoc = iframe.contentDocument || iframe.contentWindow.document;
form.submit();
}
Set the document.domain to same value in both parent page and framed page.
Example:
<script type="text/javascript">
document.domain = 'example.com';
</script>
Put this in both parent page and framed page, and the problem will be gone.

Categories

Resources