how can i open the html string that has a href on webview only instead of going on your browser?
i am using the LinkMovementMethod, this is okay on opening it on other app like video from youtube but i have some links that needs to be open only on webview.
here is a sample html string
String html_text = "<h1>sample text</h1><p><small>February 1 1970</small></p><p class=\"text-center\"><img src=\"https://www.google.com\" /></p><p>sample (here).</p>"
i need the a href to be open only on webview.
here is my code
DetailActivity
public class DetailActivity extends AppCompatActivity implements Html.ImageGetter {
private TextView newsContentTv;
private WebView newsWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_detail_news);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
newsWebView = (WebView) findViewById(R.id.newsWebView);
setSupportActionBar(toolbar);
// add back arrow to toolbar
if (getSupportActionBar() != null){
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
getSupportActionBar().setDisplayShowHomeEnabled(true);
}
newsContentTv = (TextView) findViewById(R.id.textNewsContext);
Intent i = getIntent();
String news_content = i.getStringExtra("detail_content");
Spanned spanned = Html.fromHtml(news_content, this, null);
Spannable spannable = new SpannableString( Html.fromHtml(news_content) );
newsContentTv.setText(spanned);
newsContentTv.setMovementMethod(LinkMovementMethod.getInstance());
}
any help would be really appreciated.
// Create an unencoded HTML string
// then convert the unencoded HTML string into bytes, encode
// it with Base64, and load the data.
String html_text =
"<h1>sample text</h1><p><small>February 1 1970</small></p><p class=\"text-center\"><img src=\"https://www.google.com\" /></p><p>sample (here).</p>";
String encodedHtml = Base64.encodeToString(html_text.getBytes(),
Base64.NO_PADDING);
newsWebView.loadData(encodedHtml, "text/html", "base64");
I hope this will help you.
WebView webview = (WebView)this.findViewById(R.id.webview);
webview.getSettings().setJavaScriptEnabled(true);
webview.loadDataWithBaseURL("", data, "text/html", "UTF-8", "");
Your question states you need to open the clicked url in your webview instead of navigating to browser. I can think of two ways to do this.
First case, if its not necessary to have a Textview to display the clickable link then you can load your string into the WebView itself (as others mentioned) and set a WebViewClient (this part is important)
newsWebView.loadDataWithBaseURL(null, html_text, "text/html", "UTF-8", null);
newsWebView.setWebViewClient(new WebViewClient());
// add below line to support youtube videos etc.
newsWebView.getSettings().setJavaScriptEnabled(true);
newsWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
so that any click keeps the navigation in the same WebView. Without the client it will navigate to the browser. But you should note this will load and replace the content inside, so your original link will not be there on screen.
Second case, if you need the clicks to be from the TextView simply setting newsContentTv.setMovementMethod(LinkMovementMethod.getInstance()); won't work as by default it will make the normal intent causing it to navigate to browser or related apps, you need to remove that. Then, you have to create a custom class extending LinkMovementMethod and override the touch event to load the url clicked into your webview as shown below:
public class CustomLinkMovementMethod extends LinkMovementMethod {
private static CustomLinkMovementMethod instance;
public static CustomLinkMovementMethod getInstance() {
if (instance == null)
instance = new CustomLinkMovementMethod();
return instance;
}
#Override
public boolean onTouchEvent(TextView widget, Spannable buffer, MotionEvent event) {
int action = event.getAction();
if (action == MotionEvent.ACTION_UP) {
int x = (int) event.getX() - widget.getTotalPaddingLeft() + widget.getScrollX();
int y = (int) event.getY() - widget.getTotalPaddingTop() + widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
URLSpan[] urlSpans = buffer.getSpans(off, off, URLSpan.class);
if (urlSpans.length != 0) {
// You can check log to see if you are getting the url on click.
Log.d("TAG", String.valueOf(urlSpans[0].getURL()));
/* If you've made this an inner class in your activity
you can directly load the url into your webview.
Else you will have to create listeners to get url in activity
on event trigger */
newsWebView.loadData(urlSpans[0].getURL());
return true;
}
}
return super.onTouchEvent(widget, buffer, event);
}
}
use this on the TextView like
newsContentTv.setMovementMethod(CustomLinkMovementMethod.getInstance());
See if this works for you, hadn't expected the answer to become this long.
Related
so I have a working webview that is simple, but most of the work is done in the main activity. I am trying to break it out to its own little class so I can load other classes into the main activity on the fly. I am stuck on how to do this. I have tried this a few times and been debugging it but I just dont know if I am using the right findByValue(R.id.webView); thing here. it keeps giving me a
Caused by: java.lang.NullPointerException: Attempt to invoke virtual method 'android.view.View android.webkit.WebView.findViewById(int)' on a null object reference
issue. I have tried passing the reference in as a parameter and also hard coded it. I am missing something but dont know what. There is a WebView in my activity_main that is called wevView that is what I am trying to find out where i'm did mistake.
Thanks for any help with this.
So this is my webview class:
public class NewWebView {
//variables need for webview
private final String myPage = "http://www.google.com";
WebView myWebView = null;
//consturctor
public NewWebView(){}
//This method creates the WebView
public void createWebView(WebView webView)
{
//WebView code
//Find the Webview in the Activity.xml file
//myWebView = webView;
myWebView = (WebView)myWebView.findViewById(R.id.webview);
// myWebView = (android.webkit.WebView)findViewById(R.id.webview);
//Use the custom WebViewClient for internal app browsing
myWebView.setWebViewClient(new MyWebViewClient());
//now for enabling the settings
WebSettings webSettings = myWebView.getSettings();
//Enable JavaScript
webSettings.setJavaScriptEnabled(true);
//Enable andriod zoom features
webSettings.setBuiltInZoomControls(true);
//Loading the Url
myWebView.loadUrl(myPage);
}
//Methods Used for WebViewer
//custom WebViewClent needed for internal app navigatiion
private class MyWebViewClient extends WebViewClient
{
public boolean shouldOverRideUrlLoading(android.webkit.WebView view, String url)
{
if(Uri.parse(url).getHost().equals(myPage))
{
//this is Apivita remain in the APP
return false;
}
/*
//if it is not in my site redirect it to mobile browers
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
startActivity(intent);
return true;
*/
return true;
}
}
//Enable the use of the system back button for navigation
public boolean onKeyDown(int keyCode, KeyEvent event)
{
//if the back button was pushed
if((keyCode == KeyEvent.KEYCODE_BACK) && myWebView.canGoBack())
{
myWebView.goBack();
return true;
}
//if not
return false;
}
}
and here is the main activity
public class MainActivity extends AppCompatActivity {
WebView myWebView = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//create the webview
myWebView = (android.webkit.WebView)findViewById(R.id.webview);
NewWebView apWebView = new NewWebView();
apWebView.createWebView(myWebView);
}
}
It looks like you are finding your webview in the main activity and then passing it into your class. In your custom class, you're then trying to find another view, which you technically already have. So its trying to find a webview, inside of the webview. It obviously can't find this, so it's null.
In theory, you should be able to just use myWebView = webView;, however, you need to make sure that it is finding it in the first place.
I have a large String from the database. I showed it in the TextView with scrolling.
This is a totally boring method to show large text though; I want to show data in pages.
There are multiple questions similar to this one, but I am not able to find any solutions from them; they are incomplete and off track.
Challenges
How to count number of lines that fit to screen?
How to split string in sub parts so that each substring fits to a page?
I think this should solve the problem,
1. it will split the large string
2. display on view as you want
So if u dont want to use Scroll View then well i tried something and i hope it helps
Following i done
1. inflate required views into parent view
2. set large text into Textview
3. Check if other text views are within the (visible) screen or not
4. update appropriately
Main Activity class
public class MainActivity extends Activity {
private TextView text1, text2;
private Context context;
private LinearLayout layout;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
context = getLayoutInflater().getContext();
layout = (LinearLayout) findViewById(R.id.parentLayout);
setTextViews();
// checkViewAndUpdate();
layout.getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
#Override
public void onGlobalLayout() {
checkViewAndUpdate();
}
});
}
private void checkViewAndUpdate() {
Rect rect = new Rect();
layout.getHitRect(rect);
if (text1.getLocalVisibleRect(rect)) {
Toast.makeText(context, "visible", Toast.LENGTH_LONG).show();
} else {
// update if not visible decreasing the view text size
Toast.makeText(context, "Not visible", Toast.LENGTH_LONG).show();
}
if (text2.getLocalVisibleRect(rect)) {
Toast.makeText(context, "visible", Toast.LENGTH_LONG).show();
} else {
// update if not visible decreasing the view text size
Toast.makeText(context, "Not visible", Toast.LENGTH_LONG).show();
}
}
private void setTextViews() {
text1 = new TextView(context);
text2 = new TextView(context);
text1.setText("your link seems to work. where/when do u trying to call getXXXVisibleRect()? if u do it at onCreate your link seems to work. where/when do u trying to call getXXXVisibleRect()? if u do it at onCreate your link seems to work. where/when do u trying to call getXXXVisibleRect()? if u do it at onCreateyour link seems to work. where/when do u trying to call getXXXVisibleRect()? if u do it at onCreate ");
text2.setText("text2");
text1.setTextSize(30);
text2.setTextSize(30);
// layout.removeAllViews();
layout.addView(text1);
layout.addView(text2);
}
}
I'm creating a sample webpage with button..this webpage am calling in Android using webview.
now when I click the button on webpage(that is html button). I should be able to execute some codes in Android..
How to proceed?
public class web extends Activity {
WebView mWebView;
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.webdisplay);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.loadUrl("http://localhost/test.html");
valid = new Button(ctx);
valid.setOnClickListener(this);
refuse = new Button(ctx);
refuse.setOnClickListener(this);
}
}
We can detect following HTML elements as per Android API Document.
int ANCHOR_TYPE HitTestResult for hitting a HTML::a tag
int EDIT_TEXT_TYPE HitTestResult for hitting an edit text area
int EMAIL_TYPE HitTestResult for hitting an email address
int GEO_TYPE HitTestResult for hitting a map address
int IMAGE_ANCHOR_TYPE HitTestResult for hitting a HTML::a tag which contains HTML::img
int IMAGE_TYPE HitTestResult for hitting an HTML::img tag
int PHONE_TYPE HitTestResult for hitting a phone number
int SRC_ANCHOR_TYPE HitTestResult for hitting a HTML::a tag with src=http
int SRC_IMAGE_ANCHOR_TYPE HitTestResult for hitting a HTML::a tag with src=http + HTML::img
int UNKNOWN_TYPE Default HitTestResult, where the target is unknown
I think you will be able to get all events using WebView's setOnTouchListener function.
WebView has inner class named HitTestResult.
HitTestResult class will help us to find the HTML element which press when user click on WebView.
HitTestResult class has only two method.
getExtra() : It return String. String has HTML element which is clicked by user
getType() : It return integer. It is used to identify which HTML element is clicked by user.
You can do like :
wv.setOnTouchListener(new View.OnTouchListener() {
public boolean onTouch(View v, MotionEvent event) {
WebView.HitTestResult hr = ((WebView)v).getHitTestResult();
Log.i(TAG, "getExtra = "+ hr.getExtra() + "\t\t Type=" + hr.getType());
return false;
}
});
Edited :
Refer for perfect answer :
Detect click on HTML button through javascript in Android WebView
Right now when I push a specific button it starts an intent to open a web page into a webView, but instead it opens a Browser Application, revealing the address bar which is not what I want.
After doing some research I found out I can use the shouldOverrideUrlLoading() method to stop this from happening and just open the page in a webView, but I don't know how to implement this method in my code, help would be greatly appreciated!
This is what I have in the class where I'm opening the web page:
public class Codes extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.codes);
View titleView = getWindow().findViewById(android.R.id.title);
if (titleView != null) {
ViewParent parent = titleView.getParent();
if (parent != null && (parent instanceof View)) {
View parentView = (View)parent;
parentView.setBackgroundColor(Color.rgb(228, 108, 10));
}
}
WebView codes = (WebView)findViewById(R.id.codesWebView);
codes.getSettings().setJavaScriptEnabled(true);
codes.loadUrl("http://dev10.affirmaconsulting.com:24009/keyentry");
shouldOverrideUrlLoading(codes, "http://dev10.affirmaconsulting.com:24009/keyentry");
}
}
I had this same problem, that pages were not loading in my webview but instead via the browser application. I resolved the issue by implementing a WebViewClient class and overriding the shouldOverrideUrlLoading method.
WebViewClient webClient = new WebViewClient()
{
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
return false;
}
};
webView.setWebViewClient(webClient);
The following link proved to be helpful:
http://www.firstdroid.com/2010/08/05/override-url-loading-in-webview-android-tutorial/
We do this exact task in one of our activities and haven't ran into this issue. Here is what ours looks like:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.document_viewer_activity);
WebView wv = (WebView) findViewById(R.id.documentViewerWebview);
wv.getSettings().setJavaScriptEnabled(true);
String url = getString(R.string.document_viewer_url) +
getIntent().getExtras().getString("media");
wv.loadUrl(url);
}
With the webview defined in the layout file looking like this:
<WebView
android:id="#+id/documentViewerWebview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
Hope this helps.
In my game, I'd like to have a kind of "message of the day" feature. Basically, when the user taps the "message of the day" button in the main menu, it would open up a browser view in-game. When the user is done, he taps a "close" button and the view disappears, returning him to the game menu.
So, is it possible to create a browser view dynamically? If yes, how?
The following can be used in a Dialog as well
public void setWebView() {
//WebViewClient is used if you want to capture stuff from the webview, like if a link was pressed
WebViewClient yourWebClient = new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
open_web = true;
if (!url.startsWith("http://") && !url.startsWith("https://")) {
url = "http://" + url;
}
Intent browserIntent = new Intent("android.intent.action.VIEW",
Uri.parse(url));
startActivity(browserIntent);
return true;
}
};
WebView wv = (WebView) findViewById(R.id.webview);
wv.setWebViewClient(yourWebClient);
String str = getHtml();
wv.loadData(str, "text/html", "utf-8");
wv.setBackgroundColor(0);
}
boolean isAsset = false;
private String getHtml(){
InputStream source = null;
if (isAsset){
source = getAssets().open("motd.html");
} else {
source = new FileInputStream(Environment.getExternalStorageDirectory() + "motd.html");
}
}
You could probably just use a WebView. When you want it to show up you could just set its view state to View.VISIBLE. When you want it to go away, just set its view state to View.GONE.
You can add/remove a WebView to your game dynamically (or show/hide it, whatever you prefer).
Take a look at the WebView tutorial for more info:
http://developer.android.com/resources/tutorials/views/hello-webview.html
Make sure to leave room for your "Close" button in your layout, i.e. you don't want to set the layout height to "fill_parent".