I have made two attempts in trying to access a website with authentication, and I am not sure what is wrong with my attempts. I will list each one. Has anyone tried this and gotten it to work?
This should not be difficult for Java Android programmers to understand, nor should it matter that I am using monodroid EDIT (It DOES matter, because I have a Java implementation below that works just fine)END EDIT.
I am trying to gain access to an SSRS RDL through the WebView and I need to plug in some generic credentials.
ACTIVITY:
public static string username = "...";
public static string password = "...";
public static string website = "http://10.0.0.5/Reports";
private WebView webView;
private void setupWebView(int attempt)
{
webView.Settings.JavaScriptEnabled = true;
webView.Settings.BlockNetworkLoads = false;
switch (attempt)
{
case 1:
{
webView.SetHttpAuthUsernamePassword(website, "", username, password);
}break;
case 2:
{
webView.SetWebViewClient(new AuthenticationClient(this));
}break;
}
webView.LoadUrl(website);
}
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
webView = new WebView(this);
setupWebView(1);//1 or 2 depending on what I am testing
// Set our view from the "main" layout resource
SetContentView(webView);
}
}
AuthenticationClient:
//DECLARED IN ANOTHER FILE
[Android.Runtime.Register("android/webkit/WebViewClient", DoNotGenerateAcw = true)]
public class AuthenticationClient:WebViewClient
{
private Context _context;
public AuthenticationClient(Context context)
{
_context = context;
}
public override void OnReceivedError(WebView view, ClientError errorCode, string description, string failingUrl)
{
Toast.MakeText(_context, "OnReceivedError: " + errorCode, ToastLength.Long);
//base.OnReceivedError(view, errorCode, description, failingUrl);
}
public override void OnPageStarted(WebView view, string url, Android.Graphics.Bitmap favicon)
{
Toast.MakeText(_context, "OnPageStarted: " + url, ToastLength.Long);
//base.OnPageStarted(view, url, favicon);
}
public override bool ShouldOverrideUrlLoading(WebView view, string url)
{
Toast.MakeText(_context, "ShouldOverrideUrlLoading: " + url, ToastLength.Long);
view.LoadUrl(url);
return true;
}
public override void OnReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, string host, string realm)
{
Toast.MakeText(_context, "OnReceivedHttpAuthRequest: " + host, ToastLength.Long);
handler.Proceed(Activity1.username, Activity1.password);
}
}
//END DECLARATION
ATTEMPT 1: It does not even try to load the page. I keep getting an error:
chromium(18710): external/chromium/net/http/http_auth_gssapi_posix.cc:463: [0821/095922:WARNING:http_auth_gssapi_posix.cc(463)] Unable to find a compatible GSSAPI library
ATTEMPT 2: Does not show a single toast message.
I have already looked at:
http://developer.android.com/reference/android/webkit/WebView.html
Using WebView setHttpAuthUsernamePassword?
WebView.setHttpAuthUsernamePassword() not working?
Passing username and password to SSRS 2005 reports from web application
OTHER STUFF
I have now done it in Java and it works fine. I still need a Mono for Android solution:
public class Android_reporttestActivity extends Activity {
public static String username = "...";
public static String password = "...";
public static String website = "http://10.0.0.5/Reports";
private WebView setupWebView()
{
WebView webView = new WebView(this);
webView.setWebViewClient(
new WebViewClient(){
public void onReceivedHttpAuthRequest(WebView view, HttpAuthHandler handler, String host, String realm)
{
handler.proceed(username,password);
}
}
);
return webView;
}
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
WebView webview = setupWebView();
// Set our view from the "main" layout resource
setContentView(webview);
webview.loadUrl(website);
}
Running the following for me allows everything to work as expected for me:
[Activity (Label = "WebViewExample", MainLauncher = true)]
public class Activity1 : Activity
{
string url;
WebView mWebView;
protected override void OnCreate (Bundle bundle)
{
base.OnCreate (bundle);
// Set our view from the "main" layout resource
SetContentView (Resource.Layout.Main);
url = "http://awebsite.com";
mWebView = (WebView)FindViewById<WebView> (Resource.Id.webview);
mWebView.SetWebViewClient (new ViewClient (this));
mWebView.Settings.JavaScriptEnabled = (true);
mWebView.Settings.PluginsEnabled = (true);
mWebView.LoadUrl (url);
}
class ViewClient : WebViewClient
{
Activity1 _activity;
public ViewClient(Activity1 activity)
{
_activity = activity;
}
public override void OnPageStarted (WebView view, string url, Android.Graphics.Bitmap favicon)
{
Console.WriteLine ("On Page Started");
}
public override void OnReceivedHttpAuthRequest (WebView view, HttpAuthHandler handler, string host, string realm)
{
Console.WriteLine ("On received Http auth request");
handler.Proceed("username", "password");
}
public override bool ShouldOverrideUrlLoading (WebView view, string url)
{
Console.WriteLine ("Should Override Url Loading...");
return base.ShouldOverrideUrlLoading (view, url);
}
}
}
The reason why your toasts aren't showing is probably because you're not calling ".Show()" on them so they are never displayed.
If you still can't get it up and running, then providing a URL we can use to hit against would be really useful.
I hope this helps,
ChrisNTR
Related
I have internet permission in my manifest, I am trying to search for "facebook" on the searchbar of my webview, but the problem is, for the 50% searches, It does not load the search request! this is so weird and frustrating. I implemented everything correctly and checked everything 3 times, but no luck. every time I search for the same on other browsers, It always works. but when I search on my webview, It sometimes loads the page, and most of the times, progress bar shows loading, and disappears as if the page has actually loaded, but it is still white. Why is this happening???
public class MainActivity extends AppCompatActivity {
private EditText searchEditText;
private ProgressBar progressBar;
private WebView webView;
private String SearchString = "https://www.google.co.in/search?q=";
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
progressBar = (ProgressBar) findViewById(R.id.progressBar);
progressBar.setMax(100);
webView = (WebView) findViewById(R.id.webView);
webView.setWebViewClient(new WebViewClientDemo());
webView.setWebChromeClient(new WebChromeClientDemo());
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("about:blank");
// use keyboard go button to search
searchEditText = (EditText) findViewById(R.id.searchfield);
searchEditText.setOnEditorActionListener(new TextView.OnEditorActionListener() {
public boolean onEditorAction(TextView arg0, int arg1, KeyEvent arg2) {
CustomSearch();
return false;
}
});
}
private class WebViewClientDemo extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
progressBar.setVisibility(View.GONE);
progressBar.setProgress(100);
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
progressBar.setVisibility(View.VISIBLE);
progressBar.setProgress(0);
}
#Override
public void onReceivedError(WebView view, int errorCode, String description, String failingUrl) {
Toast.makeText(getBaseContext(), "page error. please try again!", Toast.LENGTH_SHORT).show();
super.onReceivedError(view, errorCode, description, failingUrl);
}
}
private class WebChromeClientDemo extends WebChromeClient {
public void onProgressChanged(WebView view, int progress) {
progressBar.setProgress(progress);
}
public void CustomSearch() {
searchEditText = (EditText) findViewById(R.id.searchfield);
String url = searchEditText.getText().toString();
url = SearchString + url.replace(" ", "+");// replace_spaces_with_a_"+"_sign(prefix)
webView.loadUrl(url);
}
Did you try encoding your search text, as per my understanding you need to encode the search string.
I have a WebView in which I display my site, in that site I have 3 pages in sequence, of those 3 pages I need to identify when the user is on the last page, and from that to get the html content that display that page.
I manage to do a WebViewClient in which i can now identify when the user is on the last page, the problem is that I don t know how to move pass that, I don 't know how to get the html content from that page.
This is what I have so far:
namespace WebViewExample
{
[Activity(Label = "WebView", MainLauncher = true)]
public class WebView : Activity
{
Android.Webkit.WebView web_view;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.WebView);
web_view = FindViewById<Android.Webkit.WebView>(Resource.Id.webview);
web_view.Settings.JavaScriptEnabled = true;
web_view.SetWebViewClient(new MyWebViewClient());
web_view.LoadUrl(url);
}
public class MyWebViewClient : WebViewClient
{
public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, string url)
{
view.LoadUrl(url);
return true;
}
public override void OnPageStarted(Android.Webkit.WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
}
public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
base.OnPageFinished(view, url);
int i = 0;
}
}
}
}
Thanks.
Create a c# class that contains methods to be called from javaScript
If your Android API level 17 or later, This class need annotate each JavaScript-callable method with [JavascriptInterface] and [Export]
Your WebView should call AddJavascriptInterface() method
The method of onPageFinished() will be called when page loading finished
This is code :
namespace WebViewTest{
[Activity(Label = "WebViewTest", MainLauncher = true, Icon = "#drawable/icon")]
public class MainActivity : Activity
{
Android.Webkit.WebView web_view;
protected override void OnCreate(Bundle bundle)
{
base.OnCreate(bundle);
SetContentView(Resource.Layout.Main);
web_view = FindViewById<Android.Webkit.WebView>(Resource.Id.webview);
web_view.Settings.JavaScriptEnabled = true;
web_view.SetWebViewClient(new MyWebViewClient());
web_view.LoadUrl("http://stackoverflow.com/questions/40943265/xamarin-android-get-html-content");
// 3. your WebView must call AddJavascriptInterface() method
web_view.AddJavascriptInterface(new InJavaScriptLocalObj(), "local_obj");
}
}
public class MyWebViewClient : WebViewClient
{
private int count;
public override bool ShouldOverrideUrlLoading(Android.Webkit.WebView view, string url)
{
view.LoadUrl(url);
return true;
}
public override void OnPageStarted(Android.Webkit.WebView view, string url, Android.Graphics.Bitmap favicon)
{
base.OnPageStarted(view, url, favicon);
}
public override void OnPageFinished(Android.Webkit.WebView view, string url)
{
base.OnPageFinished(view, url);
count++;
//page count
// 4.The method of onPageFinished() will be called when page loading finished
if (count == 2)
{
view.LoadUrl("javascript:window.local_obj.showSource('<head>'+"
+ "document.getElementsByTagName('html')[0].innerHTML+'</head>');");
count = 0;
}
}
}
//1. Create a c# class that contains methods to be called from javaScript.
//The Method is that called in javaScript.
public sealed class InJavaScriptLocalObj : Java.Lang.Object
{
//2.if your Android API level 17 or later,
//This class must annotate each JavaScript-callable method with [JavascriptInterface] and [Export]
[Export]
[JavascriptInterface]
public void showSource(string html)
{
// System.out.println("====>html=" + html);
}
}
}
I am loading some urls in my app using android WebView and all successful. But when i am trying to load this url:
http://dev.infibond.com/cloud/instagram?user_profile=https%3A%2F%2Fscontent.cdninstagram.com%2Ft51.2885-19%2Fs150x150%2F13534190_829691380497090_1099495058_a.jpg&user_name=infibondtest
But for some reason i am failing - "view.loadUrl(url);" in "shouldOverrideUrlLoading" doesn't show the page and doesn't load another url. just shows a white page.
The response code from the server is 304.
Before i am getting to this url, i am doing authentication with Instagram and sending the access token as a cookie.
public class CloudWebViewActivity extends ActivityBase {
public static final String TAG = "WebViewActivity";
private static final String WEB_VIEW_TOKEN = "token";
private static final String WEB_VIEW_TITLE = "title";
private static final String WEB_VIEW_URL = "url";
private ProgressBar mPbProgress;
private Toolbar mToolbar;
private String mTitle, mUrl;
public static void setInstance(Context context, String title, String url) {
Intent starter = new Intent(context, CloudWebViewActivity.class);
starter.putExtra(WEB_VIEW_TITLE, title);
starter.putExtra(WEB_VIEW_URL, url);
context.startActivity(starter);
}
// MARK: Lifecycle
protected void onCreate(Bundle savedInstanceState) {
mTitle = getIntent().getStringExtra(WEB_VIEW_TITLE);
mUrl = getIntent().getStringExtra(WEB_VIEW_URL);
super.onCreate(savedInstanceState);
AppInstance.sharedInstance().getBus().register(this);
}
#Override
protected void onResume() {
super.onResume();
AppInstance.sharedInstance().setSelf();
mToolbar.setTitle(mTitle);
mPbProgress.setVisibility(View.VISIBLE);
}
#Override
protected void onDestroy() {
super.onDestroy();
AppInstance.sharedInstance().getBus().unregister(this);
}
#SuppressLint("SetJavaScriptEnabled")
public void findViews() {
setContentView(R.layout.webview_activity);
mPbProgress = (ProgressBar) findViewById(R.id.pBProgress);
final WebView mWebView = (WebView) findViewById(R.id.webView);
if (mWebView != null) {
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setLoadWithOverviewMode(true);
mWebView.getSettings().setUseWideViewPort(true);
mWebView.setWebViewClient(webViewClient);
// Register a new JavaScript interface called HTMLOUT
mWebView.addJavascriptInterface(new MyJavaScriptInterface(), "HTMLOUT");
}
if (JavaUtils.isNotNullNotEmptyNotWhiteSpaceOnly(mUrl) && mWebView != null) {
String cookieString = WEB_VIEW_TOKEN + "=" + NetworkManager.instance().getToken();
CookieManager.getInstance().setCookie(mUrl, cookieString);
mWebView.loadUrl(mUrl);
} else {
InfiLogger.getInstance().logRemoteException(new RuntimeException("Cloud service: " + mTitle + " came with an empty/null url address"));
AndroidUtils.showToast(R.string.error_cant_load_url);
}
}
#Override
public Toolbar setToolbar() {
mToolbar = (Toolbar) findViewById(R.id.mToolbar);
if (mToolbar != null) {
mToolbar.setVisibility(View.VISIBLE);
}
return mToolbar;
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
return super.onCreateOptionsMenu(menu);
}
#Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case android.R.id.home:
finish();
break;
}
return super.onOptionsItemSelected(item);
}
private void handleProgressBarVisibility(String url) {
if (url.contains("login") ||
url.contains("https://api.twitter.com/oauth/authorize?oauth_token=") ||
url.contains("https://vimeo.com/log_in") ||
url.contains(".jpg")) {
mPbProgress.setVisibility(View.GONE);
} else {
mPbProgress.setVisibility(View.VISIBLE);
}
}
private final WebViewClient webViewClient = new WebViewClient() {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
handleProgressBarVisibility(url);
String cookieString = WEB_VIEW_TOKEN + "=" + NetworkManager.instance().getToken();
CookieManager.getInstance().setCookie(mUrl, cookieString);
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView view, final String url) {
if (url.startsWith("http://dev.infibond.com/api/cloud/")) {
mPbProgress.setVisibility(View.GONE);
// This call inject JavaScript into the page which just finished loading.
view.loadUrl("javascript:window.HTMLOUT.processHTML('<head>'+document.getElementsByTagName('html')[0].innerHTML+'</head>');");
}
}
#Override
public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) {
super.onReceivedError(view, request, error);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
AndroidUtils.showToast(error.getDescription());
} else {
AndroidUtils.showToast(R.string.gen_Something_went_wrong);
}
mPbProgress.setVisibility(View.INVISIBLE);
}
};
// An instance of this class will be registered as a JavaScript interface
class MyJavaScriptInterface {
#JavascriptInterface
#SuppressWarnings("unused")
public void processHTML(String html) {
// process the html as needed by the app
InfiLogger.d("infi", "html: " + html);
if (html.contains("code")) {
final boolean success;
if (html.contains("\"code\":200")) {
AndroidUtils.showToast(AndroidUtils.getString(R.string.cloud_sync_start) + mTitle);
success = true;
} else {
AndroidUtils.showToast(AndroidUtils.getString(R.string.gen_Something_went_wrong));
success = false;
}
AppInstance.sharedInstance().getBus().post(new CloudConnectionStateChangedBusEvent(mTitle, success));
finish();
}
}
}
}
I am not 100% sure, but it seems like you have a lot of small errors. I think the one in question is here:
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
handleProgressBarVisibility(url);
String cookieString = WEB_VIEW_TOKEN + "=" +
NetworkManager.instance().getToken();
CookieManager.getInstance().setCookie(mUrl, cookieString);
view.loadUrl(url);
return true;
}
The view.loadUrl(url) seems very wrong to me. I think you may need to change this to something like:
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (Uri.parse(url).getHost().equals("dev.infibond.com")) {
return false;
}
// otherwise, they are leaving the site, so open a new
// browser instead
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(url));
view.getContext().startActivity(intent);
return true;
}
And remove the guts of what you did here. Most of it is findViews() and should not be repeated anyway. I'm guessing this is what you meant to do with
handleProgressBarVisibility(url) in the WebViewClient but I'm not really sure:
#Override
public void onLoadResource(WebView view, String url) {
handleProgressBarVisibility(url);
}
I am writing a test webview app, in which I intend to open my yahoo mail the moment I launch the app view. It will be a webview, where I want to hardcode my username and password. I know yahoo uses get method instead of post. Is there a way I can achieve this?
Here's my code so far:
Webview webview = (WebView) getView().findViewById(R.id.mywebview);
webview.setBackgroundColor(0);
webview.getSettings().setJavaScriptEnabled(true);
webview.setWebViewClient(new webClient());
String url = "https://www.yahoomail.com";
webview.loadUrl(url);
private class webClient extends WebViewClient {
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
view.setVisibility(View.VISIBLE);
}
#Override
public void onPageFinished(WebView view, String url) {
final Animation fade = new AlphaAnimation(0.0f, 1.0f);
fade.setDuration(200);
view.startAnimation(fade);
view.setVisibility(View.VISIBLE);
}
public void animate(final WebView view) {
final Animation anim = AnimationUtils.loadAnimation(getActivity(),
R.anim.slide_in_from_left);
view.startAnimation(anim);
}
#Override
public void onReceivedError( WebView view, int errorCode, String description, String failingUrl ) {
Toast.makeText(view.getContext(), "Authentication Error", Toast.LENGTH_LONG).show();
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setCookie("yahooemail#yahoo.com", "yahoopass");
super.onReceivedError(view, errorCode, description, failingUrl);
}
#Override
public void onLoadResource( WebView view, String url ){
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
return super.shouldOverrideUrlLoading(view, url);
}
#Override
public void onReceivedHttpAuthRequest( WebView view, final HttpAuthHandler handler, final String host, final String realm ){
handler.proceed("yahooemail#yahoo.com", "yahoopass");
}
}
http://developer.android.com/reference/android/webkit/WebView.html
loadUrl(String url)
Loads the given URL.
postUrl(String url, byte[] postData)
Loads the URL with postData using "POST" method into this WebView.
So instead of using:
String url = "https://www.yahoomail.com";
webview.loadUrl(url);
use:
String url = "http://example.com/somepage.php";
String postData = "postvar=value&postvar2=value2";
webView.postUrl(url, EncodingUtils.getBytes(postData, "base64"));
You can extract the vars you need for Yahoo from the login page.
Im making a Web app.
I want block it's selecting texts.
When I use Facebook application, I can't select text likes the picture's.
Because facebook app, it's a hybrid app.
How can I control...
Is there a any method for blocking text selection??...
When I touch some text which hyper linked,
Webview showing up orange color border, where around the texts,
Can I change it color??? or not showing up...??
This is my very simple webviewClient source..
public WebView webViewDefault;
private Context context = null;
private String strListsURL = URLOperation.strListsURL;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
this.context = this;
webViewDefault = (WebView) findViewById(R.id.mainWeb);
webViewDefault.setVerticalScrollBarEnabled(false);
webViewDefault.setWebViewClient(new MyClient());
webViewDefault.loadUrl(strListsURL);
private class MyClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageFinished(WebView mWebView, String url) {
}
#Override
public void onPageStarted(WebView view, String url, Bitmap favicon) {
super.onPageStarted(view, url, favicon);
}
#Override
public void onReceivedError(WebView mWebView, int errorCode, String description, String fallingUrl) {
mWebView.loadData("<html>Load Error</html>", "text/html", "utf-8");
}
}
In android webview, it enters the text selecting mode by long press the text. you can override the onPerformLongClick() to take over the control and return true to prevent from entering the webtextview mode.