How can I get clickable hyperlinks in AlertDialog from a string resource?

AndroidUser InterfaceHyperlinkCustom Controls

Android Problem Overview


What I am trying to accomplish is to have clickable hyperlinks in the message text displayed by an AlertDialog. While the AlertDialog implementation happily underlines and colors any hyperlinks (defined using <a href="..."> in the string resource passed to Builder.setMessage) supplied the links do not become clickable.

The code I am currently using looks like this:

new AlertDialog.Builder(MainActivity.this).setTitle(
		R.string.Title_About).setMessage(
		getResources().getText(R.string.about))
		.setPositiveButton(android.R.string.ok, null)
		.setIcon(R.drawable.icon).show();

I'd like to avoid using a WebView to just display a text snippet.

Android Solutions


Solution 1 - Android

I didn't really like the currently most popular answer because it significantly changes the formatting of the message in the dialog.

Here's a solution that will linkify your dialog text without otherwise changing the text styling:

    // Linkify the message
    final SpannableString s = new SpannableString(msg); // msg should have url to enable clicking
    Linkify.addLinks(s, Linkify.ALL);

    final AlertDialog d = new AlertDialog.Builder(activity)
        .setPositiveButton(android.R.string.ok, null)
        .setIcon(R.drawable.icon)
        .setMessage( s )
        .create();

    d.show();

    // Make the textview clickable. Must be called after show()
    ((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

Solution 2 - Android

If you are only showing some text and URL[s] in your dialog perhaps the solution is simpler

public static class MyOtherAlertDialog {
 
 public static AlertDialog create(Context context) {
  final TextView message = new TextView(context);
  // i.e.: R.string.dialog_message =>
            // "Test this dialog following the link to dtmilano.blogspot.com"
  final SpannableString s = 
               new SpannableString(context.getText(R.string.dialog_message));
  Linkify.addLinks(s, Linkify.WEB_URLS);
  message.setText(s);
  message.setMovementMethod(LinkMovementMethod.getInstance());
    
  return new AlertDialog.Builder(context)
   .setTitle(R.string.dialog_title)
   .setCancelable(true)
   .setIcon(android.R.drawable.ic_dialog_info)
   .setPositiveButton(R.string.dialog_action_dismiss, null)
   .setView(message)
   .create();
 }
}

As shown here http://picasaweb.google.com/lh/photo/up29wTQeK_zuz-LLvre9wQ?feat=directlink

Alert dialog with clickable links

Solution 3 - Android

This should make <a href> tags to get highlighted as well. Please note that i have just added a few lines to emmby's code. so credit to him

final AlertDialog d = new AlertDialog.Builder(this)
 .setPositiveButton(android.R.string.ok, null)
 .setIcon(R.drawable.icon)
 .setMessage(Html.fromHtml("<a href=\"http://www.google.com\">Check this link out</a>"))
 .create();
d.show();
// Make the textview clickable. Must be called after show()   
    ((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

Solution 4 - Android

Actually, if you want to simply use a string without dealing with all the views, the fastest way is to find message textview and linkify it:

d.setMessage("Insert your cool string with links and stuff here");
Linkify.addLinks((TextView) d.findViewById(android.R.id.message), Linkify.ALL);

Solution 5 - Android

JFTR, here comes the solution which I figured out after some time:

View view = View.inflate(MainActivity.this, R.layout.about, null);
TextView textView = (TextView) view.findViewById(R.id.message);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(R.string.Text_About);
new AlertDialog.Builder(MainActivity.this).setTitle(
		R.string.Title_About).setView(view)
		.setPositiveButton(android.R.string.ok, null)
		.setIcon(R.drawable.icon).show();

The corresponding about.xml borrowed as a fragment from the Android sources looks like this:

<?xml version="1.0" encoding="utf-8"?>
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/scrollView" android:layout_width="fill_parent"
	android:layout_height="wrap_content" android:paddingTop="2dip"
	android:paddingBottom="12dip" android:paddingLeft="14dip"
	android:paddingRight="10dip">
	<TextView android:id="@+id/message" style="?android:attr/textAppearanceMedium"
		android:layout_width="fill_parent" android:layout_height="wrap_content"
		android:padding="5dip" android:linksClickable="true" />
</ScrollView>

The important parts are setting linksClickable to true and setMovementMethod(LinkMovementMethod.getInstance()).

Solution 6 - Android

Instead of ...

AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle(R.string.my_title);
dialogBuilder.setMessage(R.string.my_text);

... I now use:

AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
dialogBuilder.setTitle(R.string.my_title);
TextView textView = new TextView(this);
textView.setMovementMethod(LinkMovementMethod.getInstance());
textView.setText(R.string.my_text);
dialogBuilder.setView(textView);

Solution 7 - Android

Simplest way:

final AlertDialog dlg = new AlertDialog.Builder(this)
				.setTitle(R.string.title)
				.setMessage(R.string.message)
				.setNeutralButton(R.string.close_button, null)
				.create();
		dlg.show();
        // Important! android.R.id.message will be available ONLY AFTER show()
		((TextView)dlg.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

Solution 8 - Android

Solution 9 - Android

I was not really satisfied with the current answers. There are two things that are important when you want clickable hyperlinks in href style withing an AlertDialog:

  1. Set the content as View and not with setMessage(…), as only Views allow clickable HTML content
  2. Set the correct movement method (setMovementMethod(…))

Here is a working minimal example:

strings.xml

<string name="dialogContent">
    Cool Links:\n
    <a href="http://stackoverflow.com">Stackoverflow</a>\n
    <a href="http://android.stackexchange.com">Android Enthusiasts</a>\n
</string>

MyActivity.java

public void showCoolLinks(View view) {
   final TextView textView = new TextView(this);
   textView.setText(R.string.dialogContent);
   textView.setMovementMethod(LinkMovementMethod.getInstance()); // this is important to make the links clickable
   final AlertDialog alertDialog = new AlertDialog.Builder(this)
       .setPositiveButton("OK", null)
       .setView(textView)
       .create();
   alertDialog.show()
}
…

Solution 10 - Android

I've checked many questions and answers, but it doesn't work. I did it myself. This is the code snippet on MainActivity.java.

private void skipToSplashActivity()
{
  
    final TextView textView = new TextView(this);
    final SpannableString str = new SpannableString(this.getText(R.string.dialog_message));

    textView.setText(str);
    textView.setMovementMethod(LinkMovementMethod.getInstance());

    ....
}

Put this tag on res\values\String.xml

<string name="dialog_message"><a href="http://www.nhk.or.jp/privacy/english/">NHK Policy on Protection of Personal Information</a></string>

Solution 11 - Android

If you are using a DialogFragment, this solution should help.

public class MyDialogFragment extends DialogFragment {
    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {

        // dialog_text contains "This is a http://test.org/"
        String msg = getResources().getString(R.string.dialog_text);
        SpannableString spanMsg = new SpannableString(msg);
        Linkify.addLinks(spanMsg, Linkify.ALL);

        AlertDialog.Builder builder = new AlertDialog.Builder(getActivity());
        builder.setTitle(R.string.dialog_title)
            .setMessage(spanMsg)
            .setPositiveButton(R.string.ok, null);
        return builder.create();
    }

    @Override
    public void onStart() {
        super.onStart();

        // Make the dialog's TextView clickable
        ((TextView)this.getDialog().findViewById(android.R.id.message))
                .setMovementMethod(LinkMovementMethod.getInstance());
    }
}

Solution 12 - Android

For me the best solution to create privacy policy dialog is :

    private void showPrivacyDialog() {
    if (!PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).getBoolean(PRIVACY_DIALOG_SHOWN, false)) {

        String privacy_pol = "<a href='https://sites.google.com/view/aiqprivacypolicy/home'> Privacy Policy </a>";
        String toc = "<a href='https://sites.google.com/view/aiqprivacypolicy/home'> T&C </a>";
        AlertDialog dialog = new AlertDialog.Builder(this)
                .setMessage(Html.fromHtml("By using this application, you agree to " + privacy_pol + " and " + toc + " of this application."))
                .setPositiveButton("ACCEPT", new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        PreferenceManager.getDefaultSharedPreferences(getApplicationContext()).edit().putBoolean(PRIVACY_DIALOG_SHOWN, true).apply();
                    }
                })
                .setNegativeButton("DECLINE", null)
                .setCancelable(false)
                .create();

        dialog.show();
        TextView textView = dialog.findViewById(android.R.id.message);
        textView.setLinksClickable(true);
        textView.setClickable(true);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
    }
}

check the working example : app link

Solution 13 - Android

I combined some of the options discussed above to come up with this function that works for me. pass the result to dialog builder's SetView() method.

public ScrollView LinkifyText(String message) 
{
	ScrollView svMessage = new ScrollView(this); 
	TextView tvMessage = new TextView(this);
	
	SpannableString spanText = new SpannableString(message);
	  	
	Linkify.addLinks(spanText, Linkify.ALL);
	tvMessage.setText(spanText);
	tvMessage.setMovementMethod(LinkMovementMethod.getInstance());
	
	svMessage.setPadding(14, 2, 10, 12);
	svMessage.addView(tvMessage);
	
	return svMessage;
}

Solution 14 - Android

Easy Kotlin implementation

String resource:

<string name="foo"><a href="https://www.google.com/">some link</a></string>

Code:

AlertDialog.Builder(context)
        .setMessage(R.string.foo)
        .show()
        .apply {
            findViewById<TextView>(android.R.id.message)
            ?.movementMethod = LinkMovementMethod.getInstance()
        }

Solution 15 - Android

I do this by specifying the alert box in an XML resource and loading that. See for example the about.xml (see the ABOUT_URL id) that gets instantiated near the end of ChandlerQE.java. The relevant parts from the java code:

LayoutInflater inflater = 
    (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View view = (View) inflater.inflate(R.layout.about, null);

new AlertDialog.Builder(ChandlerQE.this)
.setTitle(R.string.about)
.setView(view)

Solution 16 - Android

This is my solution. It creates a normal link without html tags involved and without any URL visible. It also keeps the design intact.

SpannableString s = new SpannableString("This is my link.");
s.setSpan(new URLSpan("http://www.google.com"), 11, 15, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);

AlertDialog.Builder builder;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
    builder = new AlertDialog.Builder(this, android.R.style.Theme_Material_Dialog_Alert);
} else {
    builder = new AlertDialog.Builder(this);
}

final AlertDialog d = builder
        .setPositiveButton("CLOSE", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Do nothing, just close
            }
        })
        .setNegativeButton("SHARE", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                // Share the app
                share("Subject", "Text");
            }
        })
        .setIcon(R.drawable.photo_profile)
        .setMessage(s)
        .setTitle(R.string.about_title)
        .create();

d.show();

((TextView)d.findViewById(android.R.id.message)).setMovementMethod(LinkMovementMethod.getInstance());

Solution 17 - Android

The easiest and shortest way is like this

https://stackoverflow.com/questions/10095335/android-link-in-dialog

((TextView) new AlertDialog.Builder(this)
.setTitle("Info")
.setIcon(android.R.drawable.ic_dialog_info)
.setMessage(Html.fromHtml("<p>Sample text, <a href=\"http://google.nl\">hyperlink</a>.</p>"))
.show()
// Need to be called after show(), in order to generate hyperlinks
.findViewById(android.R.id.message))
.setMovementMethod(LinkMovementMethod.getInstance());

Solution 18 - Android

This is the simple way I use

Strings In strings.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <string name="credits_title">Credits</string>
    <string name="confirm">OK</string>
    <string name="credits">All rights reserved.
         <a href="https://google.com">Source</a>
    </string>
</resources>

Dimensions In dimens.xml

<?xml version="1.0" encoding="utf-8"?>
<resources xmlns:tools="http://schemas.android.com/tools">
    <dimen name="margin_8dp">8dp</dimen>
    <dimen name="margin_32dp">32dp</dimen>
</resources>

Helper Dialog class

public class MessageHelper {

    public static void showCreditsDialog(Context context) {

        AlertDialog alertDialog = new AlertDialog.Builder(context).create();
        alertDialog.setTitle(R.string.credits_title);
        TextView textView = new TextView(context);
        int padding = (int) context.getResources().getDimension(R.dimen.margin_32dp);
        int topPadding = (int) context.getResources().getDimension(R.dimen.margin_8dp);
        textView.setPadding(padding, topPadding, padding, 0);
        textView.setMovementMethod(LinkMovementMethod.getInstance());
        textView.setText(R.string.credits);
        alertDialog.setView(textView);

        alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, context.getResources().getString(R.string.confirm),
                new DialogInterface.OnClickListener() {
                    public void onClick(DialogInterface dialog, int which) {
                        dialog.dismiss();
                    }
                });
        alertDialog.show();
    }
}

How to use

MessageHelper.showCreditsDialog(this); // this is the context

Preview

enter image description here

Solution 19 - Android

> Clickable hyperlinks in AlertDialog

 /*Dialog Agreement*/
    private fun agreed() {
        if (agreed != "yes") {
            val inflater: LayoutInflater = this.layoutInflater
            val dialogView: View = inflater.inflate(R.layout.dialog_agreed, null)
            val btnAccept: TextView = dialogView.findViewById(R.id.btn_accept)
            val btnDecline: TextView = dialogView.findViewById(R.id.btn_decline)
            val txtMessage: TextView = dialogView.findViewById(R.id.txt_message)
            btnAccept.setOnClickListener {
                //Saving data to preference manager
                val sharedPref = getSharedPreferences("Janta24", Context.MODE_PRIVATE)
                val editor = sharedPref.edit()
                editor.putString("agreed", "yes")
                editor.apply()
                alertDialog.dismiss()
            }
            btnDecline.setOnClickListener {
                finish()
            }
            txtMessage.text = Html.fromHtml(
                "We have revised our<a href=\"http://app.janta24.in/term.html\">Terms of Use</a> & " +
                        "<a href=\"http://app.janta24.in/privacy.html\">Privacy Policy</a> " +
                        "By accepting, you agreed to our updated terms and policies. Please take few minutes to read and understand them."
            )
            txtMessage.movementMethod = LinkMovementMethod.getInstance()
            val dialogBuilder: AlertDialog.Builder = AlertDialog.Builder(this)
            dialogBuilder.setOnDismissListener { }
            dialogBuilder.setView(dialogView)
            dialogBuilder.setCancelable(false)
            alertDialog = dialogBuilder.create()
            alertDialog.show()
        }
    }

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThilo-Alexander GinkelView Question on Stackoverflow
Solution 1 - AndroidemmbyView Answer on Stackoverflow
Solution 2 - AndroidDiego Torres MilanoView Answer on Stackoverflow
Solution 3 - AndroidDeRaganView Answer on Stackoverflow
Solution 4 - Androidvinc3m1View Answer on Stackoverflow
Solution 5 - AndroidThilo-Alexander GinkelView Answer on Stackoverflow
Solution 6 - Androidneu242View Answer on Stackoverflow
Solution 7 - AndroidGabrieleView Answer on Stackoverflow
Solution 8 - AndroidLakshmananView Answer on Stackoverflow
Solution 9 - AndroidFlowView Answer on Stackoverflow
Solution 10 - AndroidHirotoView Answer on Stackoverflow
Solution 11 - AndroidtronmanView Answer on Stackoverflow
Solution 12 - AndroidMinionView Answer on Stackoverflow
Solution 13 - AndroidAlexView Answer on Stackoverflow
Solution 14 - AndroidHawklikeView Answer on Stackoverflow
Solution 15 - AndroidHeikki ToivonenView Answer on Stackoverflow
Solution 16 - AndroidJohn TView Answer on Stackoverflow
Solution 17 - AndroidJavier Castellanos CruzView Answer on Stackoverflow
Solution 18 - AndroidZainView Answer on Stackoverflow
Solution 19 - AndroidAftab AlamView Answer on Stackoverflow