Get the link redirected from webview android - android

I am trying to implement a payment gateway in android, and the payment processor requires sending some parameters when the "Pay" button is clicked. The sample link is:
https://vpay.com/?p=linkToken&v_merchant_id=qa331322179752&merchant_ref=234-567-890&memo=Bulk+order+from+McAckney+Web+Shop&total=13000&
notify_url=http%3A%2F%2Fwww.example.com%2Fnotification.php&
success_url=http%3A%2F%2Fwww.example.com%2Fthank_you.html&fail_url=http%3A%2F%2Fwww.example.com%2Ffailed.html
Now if the parameters are inputted correctly, the link returns another link in the format: https://vpay.com/pay/bnlink/xxxxxxxx-x0 which when visited brings up VPay payment page that can be used for payment based on the parameters supplied.
The payment processor should have employed an automatic redirection when the new link is generated, instead, it just displays the new link and stays there. Is there a way to get this new "RETURNED" link and then visit it so users can input the payment info.
Thank you!

Following method of Webview will work if you are using your own webview in activity or fragment for the payment stuff. below is the piece of code which will help:
webview.setWebViewClient(new WebViewClient() {
public boolean shouldOverrideUrlLoading(WebView view, String url) {
Log.i(TAG, "Processing webview url click...");
view.loadUrl(url);
Log.v(TAG,"html content of url:"+ getHtml(String url) );
return true;
}
public void onPageFinished(WebView view, String url) {
Log.i(TAG, "Finished loading URL: " +url);
}
});
in shouldOverrideUrlLoading method you will add your condition according to the url whether to load this url in webview or not.
And to get html content of the url use below Method:
public String getHtml(String url) {
HttpClient vClient = new DefaultHttpClient();
HttpGet vGet = new HttpGet(url);
String response = "";
try {
ResponseHandler<String> vHandler = new BasicResponseHandler();
response = vClient.execute(vGet, vHandler);
} catch (Exception e) {
e.printStackTrace();
}
return response;
}

Related

How to play a video in webview from a link which needs authentication?

We have some videos hosted in our platform. Let's say mydomain.com/no_auth_video_1 and mydomain.com/no_auth_video_2, for instance. Now we added a third video mydomain.com/auth_video_3, but this one can only be seen if you add some authentication headers to the request.
In our android app, we use a WebView to play these videos. We have this html template:
<!-- html stuf -->
<video>
<source src="%videoUrl%"/>
</video>
<!-- html stuf -->
and once replaced the url, we load the html on the webview with:
webView.loadData(html, "text/html", "utf-8")
This works great for the no_auth videos, but not for the video which needs the authentication. Looking for some answers, I found that we should override the shouldInterceptRequest method on the WebViewClient:
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
String url = request.getUrl().toString();
if (urlShouldBeHandledByWebView(url)) {
return super.shouldInterceptRequest(view, url);
}
return getNewResponse(view, url);
}
private WebResourceResponse getNewResponse(WebView view, String url) {
try {
OkHttpClient okHttpClient = getMyAuthenticatedHTTPClient()
Request request = new Request.Builder()
.url(url)
.build();
final Response response = okHttpClient.newCall(request).execute();
return new WebResourceResponse(
response.header("content-type", null),
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
} catch (Exception e) {
return null;
}
}
This works intended since the query for mydomain.com/auth_video_3 is executed, and I can see that the info is retrieved properly with the debugger. Problem is that in the WebView the video isn't loading anyway.

Android WebView sometimes doesn't send request headers on initial page load

I have a webview activity that loads a URL with a few custom request headers in its onCreate() method. The requirement is to pass the custom headers with the initial URL request. On a few devices, the webview stops sending the headers after the webview activity has been launched a few times.
For example, I have a HomeActivity which launches a WebViewActivity. After launching the WebViewActivity and navigating back to HomeActivity a few times, the WebViewActivity stops sending the custom request headers and this behaviour doesn't change unless I clear the application's data.
I have confirmed this behaviour using a MITM tool. The implementation is as follows:
#Override
protected void onCreate(Bundle savedInstanceState) {
Map<String, String> map = new HashMap<>();
map.put("header1", "header1_value");
map.put("header2", "header2_value");
map.put("header3", "header3_value");
map.put("header4", "header4_value");
webView.loadUrl("https://www.example.com/mypath", map);
}
The above snippet executes unconditionally on every activity launch. However, the headers are not present in the actual request made by the webview. Also, the page being requested is a 303 redirect.
If your minimum API target is level 21, you can use the shouldInterceptRequest else you can use this
With each interception, you will need to take the url, make this request yourself, and return the content stream:
Then:
WebViewClient wvc = new WebViewClient() {
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
try {
DefaultHttpClient client = new DefaultHttpClient();
HttpGet httpGet = new HttpGet(url);
httpGet.setHeader("header1", "header1_value");
httpGet.setHeader("header2", "header2_value");
httpGet.setHeader("header3", "header3_value");
httpGet.setHeader("header4", "header4_value");
HttpResponse httpReponse = client.execute(httpGet);
Header contentType = httpReponse.getEntity().getContentType();
Header encoding = httpReponse.getEntity().getContentEncoding();
InputStream responseInputStream = httpReponse.getEntity().getContent();
String contentTypeValue = null;
String encodingValue = null;
if (contentType != null) {
contentTypeValue = contentType.getValue();
}
if (encoding != null) {
encodingValue = encoding.getValue();
}
return new WebResourceResponse(contentTypeValue, encodingValue, responseInputStream);
} catch (ClientProtocolException e) {
//return null to tell WebView we failed to fetch it WebView should try again.
return null;
} catch (IOException e) {
//return null to tell WebView we failed to fetch it WebView should try again.
return null;
}
}
}
//Where wv is your webview
wv.setWebViewClient(wvc);
Based on this question

Android Webview pass from headers data to Google Analytics

I track my visitors' usernames and I want to pass the username data from webpage to my activity method. What is the proper way to pass this data ?
(Putting username data inside HTML page's hidden div and parsing webpage is my last option, I don't prefer it)
I use Webview in my Android application. I load URLs like this:
public boolean shouldOverrideUrlLoading(WebView view, String url) {
...
String url = "http://example.com";
webView.postUrl(url, EncodingUtils.getBytes(myPostData, "base64"));
...
}
There is some custom headers inside my page response. Response headers have this:
header('User name: michael');
If page is successfully loaded, I need to get that headers from the response and use it inside my Google Analytics as custom dimension.
EasyTracker easyTracker = EasyTracker.getInstance();
easyTracker.send(MapBuilder
.createAppView("Home screen")
.set(Fields.customDimension(1), "michael");
.build()
);
My problem is what is the proper way for this ? Is it possible to get it from onPageFinished and set this header inside Analytics code or is there a better way ? I'm open to any method/solution that is compatible with this structure.
Note that I override these methods for my activity works:
WebViewClient::onPageStarted(WebView view, String url, Bitmap favicon)
WebViewClient::onPageFinished(WebView view, String url)
WebViewClient::shouldOverrideUrlLoading(WebView view, String url)
WebViewClient::onLoadResource(WebView view, String url)
WebViewClient::onReceivedError(WebView view, int errorCode, String description, String failingUrl)
WebChromeClient::onProgressChanged(WebView view, int newProgress)
Edit:
There is a similar answer here which is 3 years old: https://stackoverflow.com/a/3134609/429938
But It offers to catch headers in shouldOverrideUrlLoading. Is it not possible to catch it in onPageFinished ? Or how can I use it with Webview.postUrl()
Edit2:
Another solution is to use addJavascriptInterface and set user name from the javascript code and set google analytics code inside activity. But this is a Android specific solution. I would prefer a common solution that can be used in IOS etc.
the most cross platform solution is a javascript bridge ( addJavascriptInterface ). This is what I would recommend you.
The native part can be implemented on iOS too. And the HTML part stay the same.
If not, you need to implement all the logic on the native side using one of the events, like onPageFinished. If the header are not accessible from here, do the request yourself with HTTPURLConnection then loadDataWithBaseURL.
I'm using following code to konw when page is loaded:
webview.setWebChromeClient(new WebChromeClient() {
public void onProgressChanged(WebView view, int progress)
{
MyActivity.setTitle("Loading...");
MyActivity.setProgress(progress * 100);
if (progress == 100) {
//page is successfully loaded and you can get our header.
}
}
});
Try this one: here I'm getting "User name" value from header
HttpURLConnection conn = null;
final HostnameVerifier DO_NOT_VERIFY = new HostnameVerifier() {
public boolean verify(String hostname, SSLSession session) {
return true;
}
};
try {
URL url = new URL(YOUR_URL);
if (url.getProtocol().toLowerCase().equals("https")) {
trustAllHosts();
HttpsURLConnection https = (HttpsURLConnection) url.openConnection();
https.setHostnameVerifier(DO_NOT_VERIFY);
conn = https;
} else {
conn = (HttpURLConnection) url.openConnection();
}
conn.setInstanceFollowRedirects(false);
conn.connect();
String location = conn.getHeaderField( "User name" );

Logging in via HttpPost to a website via an application

Hello Stackoverflowers!
I have written a relatively simple application that consists of a login text field, a password text field and a login button.
My goal is that when the user enters the login information and touches the login button, the application will log the user into the website I have specified and open it up in a different intent or WebView. My current implementation opens a new activity with a WebView and passes in the login information. My code is as follows for the new activity:
setContentView(R.layout.web);
try {
//add the users login information(username/pw) to a List
List<NameValuePair> nameValuePairs = new ArrayList<NameValuePair>();
nameValuePairs.add(new BasicNameValuePair("email", "random#gmail.com"));
nameValuePairs.add(new BasicNameValuePair("password", "password1"));
//declare a new HttpClient
HttpClient httpclient = new DefaultHttpClient();
//set the HttpPost to the desire URL
HttpPost httppost = new HttpPost(URL_STRING);
//set the entity to a new UrlEncodedForm with the login info and type
httppost.setEntity(new UrlEncodedFormEntity(nameValuePairs, HTTP.UTF_8));
//store the response
HttpResponse response = httpclient.execute(httppost);
//get the data from the response
String data = new BasicResponseHandler().handleResponse(response);
//get the webview from the xml
WebView webview = (WebView)findViewById(R.id.webView);
webview.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
view.loadUrl(url);
return true;
}
});
//load the return website from the server
webview.loadDataWithBaseURL(httppost.getURI().toString(), data, "text/html", HTTP.UTF_8, null);
This successfully logs me in to the URL (an https site) and opens the page, however if you try to click on any of the buttons on the website it takes you back to the login page in the WebView, and it does not display many of the attributes on the website (charts/graphs).
Could this be a cookie thing?
So is there a way to send the login info via a new intent? Or is there a solution to my WebView implementation?
(here is a relatively similar(ish) question that never got a definitive answer Android SSO (Single sign-on) for app)
Thank you for your time! I really appreciate you taking a look at my question.
EDIT: So giseks's solution worked for me to get the webpage to stay within the WebView, however the charts/graphs/etc on the page still did not display, the solution for that was as simple as enabling javascript for the WebSettings
webview.getSettings().setJavaScriptEnabled(true);
Here's Google's WebSettings Android API for reference: WebSettings
This helped me, I hope it helps you!
My guess is that your application doesn't handle cookies right. Take a look at this question, it may help.
WebView and Cookies on Android
EDIT
In your code you seem to pass only the html retrieved from request to the WebView. Cookies seem to get lost somewhere. I'd suggest you another approach.
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
WebView webv = (WebView)findViewById(R.id.MainActivity_webview);
webv.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
});
String postData = FIELD_NAME_LOGIN + "=" + LOGIN +
"&" + FIELD_NAME_PASSWD + "=" + PASSWD;
// this line logs you in and you stay logged in
// I suppose it works this way because in this case WebView handles cookies itself
webv.postUrl(URL, EncodingUtils.getBytes(postData, "utf-8"));
}

Android - Webview only applying headers to initial request

I'm writing an android app that uses webview to request content from a web server, but using mWebView.loadUrl(url1, headers); will only apply the headers to the initial request and not the resources in the request.
Any idea as so how to apply the headers to the resource requests as well?
Not absolutely sure but you can try to override shouldOverrideUrlLoading(WebView view, String url) method and handle all redirects by starting mWebView.loadUrl(url, yourHeaders);
Dont forget to return true in that overriden method.
First of all, let me say that i can't believe that webview sucks so much.
This is what i did to pass custom headers
public class CustomWebview extends WebView {
public void loadWithHeaders(String url) {
setWebViewClient(new WebViewClient() {
#Override
public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
//makes a custom http request, which allows you to add your own headers
return customRequest(url);
}
});
loadUrl(url);
}
/**
* Custom http request with headers
* #param url
* #return
*/
private WebResourceResponse customRequest(String url) {
try {
OkHttpClient httpClient = new OkHttpClient();
Request request = new Request.Builder()
.url(url.trim())
.addHeader("Header-Name", "Android Sucks")
.build();
Response response = httpClient.newCall(request).execute();
return new WebResourceResponse(
"text/html", // You can set something other as default content-type
"utf-8", // Again, you can set another encoding as default
response.body().byteStream()
);
} catch (IOException e) {
//return null to tell WebView we failed to fetch it WebView should try again.
return null;
}
}
}

Categories

Resources