theshadow124
theshadow124

Reputation: 671

Not Returning to App After Following Link

Content is delivered to my app from a server, sometimes the content contains tel: or mailto: hyperlinks. Currently I use html.fromhtml() and setMovementMethod to make the textview links clickable:

        ((TextView) findViewById(R.id.c_data)).setText(Html.fromHtml(HTML_out));
        ((TextView) findViewById(R.id.c_data)).setMovementMethod(LinkMovementMethod.getInstance());

and this works, allows the user to open mailto links, phone links and anything else.

The problem is it closes my app when they click the link, so if they click back from the phone or email it takes them back to the home screen instead of my app.

From what I can see, when the link is clicked for some reason onStop is called. How can I avoid this so the app will be re-opened right after the call/email?

example data:

<b>Title1</b><a href="tel:44#######">(44#) ###-####</a>
<b>Title2</b><a href="mailto:[email protected]">[email protected]</a>
<b>Title3</b><a href="google.ca">google.ca</a>

edit: I tried to use an intent:

((TextView) findViewById(R.id.cust_data)).setText(Html.fromHtml(HTML_out));
//((TextView) findViewById(R.id.cust_data)).setMovementMethod(LinkMovementMethod.getInstance());
((TextView) findViewById(R.id.cust_data)).setMovementMethod(new MovementMethod() {
    @Override
    public void initialize(TextView widget, Spannable text) {
        //Log.i("Test click","Good");
    }

    @Override
    public boolean onKeyDown(TextView widget, Spannable text, int keyCode, KeyEvent event) {
        return false;
    }

    @Override
    public boolean onKeyUp(TextView widget, Spannable text, int keyCode, KeyEvent event) {
        //Log.i("Test click","Good");
        return false;
    }

    @Override
    public boolean onKeyOther(TextView view, Spannable text, KeyEvent event) {
        //Log.i("Test click","Good");
        return false;
    }

    @Override
    public void onTakeFocus(TextView widget, Spannable text, int direction) {

    }

    @Override
    public boolean onTrackballEvent(TextView widget, Spannable text, MotionEvent event) {
        return false;
    }

    @Override
    public boolean onTouchEvent(TextView widget, Spannable text, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_UP) {
            Log.i("Test click", text.toString());
            Intent intent = new Intent(Intent.ACTION_DIAL);
            intent.setData(Uri.parse("tel:0123456789"));
            startActivity(intent);
            return true;
        } else {
            return false;
        }
    }

    @Override
    public boolean onGenericMotionEvent(TextView widget, Spannable text, MotionEvent event) {
        return false;
    }

    @Override
    public boolean canSelectArbitrarily() {
        return false;
    }
});

Just to text I used a static phone number. This still doesn't take me back to my app after.

Upvotes: 0

Views: 92

Answers (1)

Cody Harness
Cody Harness

Reputation: 1147

From your last comment it sounds like you are going to possibly have several links inside of one textview. If that's the case then what you want is to set the text with a spannable, which allows you to determine what links are in there, what their text says, and other formatting like bold or italic text for only part of the text. Try something like this:

final SpannableStringBuilder content = getContent(); // This method is explained below.

final TextView textView = (TextView) findViewById(R.id.my_text_view);
textView.setLinksClickable(true);
textView.setText(content, TextView.BufferType.SPANNABLE);
textView.setMovementMethod(LinkMovementMethod.getInstance());

getContent() - This is where it will be more difficult to give you an answer, since we don't know how you're getting your links. When I wrote an application that did this it was pulling data from an xml file, so the links were marked in it. I will paste that code, so you can base yours off of it, but unless you are doing exactly the same as we were then you'll have to modify it to get your links.

if (contentNode instanceof Element && contentNode.getNodeName().equals("section")) {
    String sectionTitle = ((Element) contentNode).getAttribute("title");
    article.headers.add(sectionTitle);
    NodeList sectionList = contentNode.getChildNodes();

    String text = "";
    ArrayList<String> links = new ArrayList<>(), linkStrings = new ArrayList<>();

    for (int k = 0; k < sectionList.getLength(); k++) {
        Node sectionNode = sectionList.item(k);

        if (sectionNode instanceof Element && sectionNode.getNodeName().equals("text")) {
            NodeList textNodes = sectionNode.getChildNodes();

            for (int l = 0; l < textNodes.getLength(); l++) {
                Node attributeNode = textNodes.item(l);

                text += attributeNode.getTextContent();
            }
        }

        if (sectionNode instanceof Element && sectionNode.getNodeName().equals("embedded_link")) {
            String linkDestination = ((Element) sectionNode).getAttribute("destination");
            String linkString = ((Element) sectionNode).getAttribute("string");

            linkStrings.add(linkString);
            links.add(linkDestination);
        }
    } // end k forloop

    SpannableStringBuilder spannableStringBuilder = new SpannableStringBuilder(text);

    // Loop through all of the links.
    for (int m = 0; m < links.size(); m++) {
        final String linkString = linkStrings.get(m);
        final String link = links.get(m);

        final int start = text.indexOf(linkString);
        final int end = start + linkString.length();

        ClickableSpan clickableSpan = new ClickableSpan() {
            @Override
            public void onClick(View widget) {
                Intent i = new Intent(Intent.ACTION_VIEW);
                    i.setData(Uri.parse(link));

                    context.startActivity(i);                                   
            }
        };

        if (start > -1) {
            try {
                spannableStringBuilder.setSpan(clickableSpan, start, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
            } catch (Exception e) {
                Log.e("couldn't spannable text", linkString);
            }
        }
    } // end m forloop

    article.bodyContent.put(sectionTitle, spannableStringBuilder);
} // end if for section

Hopefully that all isn't too confusing. If you have more questions let me know.

Upvotes: 1

Related Questions