opening link in external browser from page in WebView - javascript

I'm developing an angular website which is loading in an app from a WebView, and there is only one of the links in it that has to be opened outside of the app (external browser)
I need a way to handle this from JavaScript not putting extra work to the android side.
and i have already tried some ways including:
window.open("url","_system")
(navigator as any).app.loadUrl("http://google.com", {openExternal : true});

Well, there is no such thing
instead it must be handled from android application code. you can add a parameter to the url when u need it to open in external browser, ( here it is external=true ) and then check for that parameter in your webview url loading as below:
webView.setWebViewClient(new WebViewClient(){
#RequiresApi(api = Build.VERSION_CODES.N)
#Override
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
if((String.valueOf(request.getUrl())).contains("external=true")) {
Intent intent = new Intent(Intent.ACTION_VIEW, request.getUrl());
view.getContext().startActivity(intent);
return true;
} else {
view.loadUrl(String.valueOf(request.getUrl()));
}
return true;
}
});

Related

How to close webview in mobile android/iOs(Native app)

In our app have opening one url in webview there is way to close webview after some specific url detect.
how can possible to close webview ? I have try with window.close() in javascript.but could not work.have another way from android or ios app.
As per comments on question, I am putting a better term for closing the web view - going back to previous screen. You can do this as follows for Android and iOS :
Android :
finish()
iOS :
If you are using navigation controller :
self.navigationController?.popViewController(animated: true)
If you are presenting web view controller :
self.dismiss(animated: true, completion: nil)
The key is to check that url in the delegate function of web view.
Android :
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.equals("your_url")) {
finish()
return false;
} else {
return true;
}
}
iOS :
func webView(_ webView: UIWebView, shouldStartLoadWith request: URLRequest, navigationType: UIWebViewNavigationType) -> Bool {
if request.url?.absoluteString == "your_url" {
self.navigationController?.popViewController(animated: true)
// If controller is presented - self.dismiss(animated: true, completion: nil)
return false
}
return true
}
You can use shouldOverrideUrlLoading
Give the host application a chance to take over the control when a new url is about to be loaded in the current WebView. If WebViewClient is not provided, by default WebView will ask Activity Manager to choose the proper handler for the url. If WebViewClient is provided, return true means the host application handles the url, while return false means the current WebView handles the url.
Notes:
This method is not called for requests using the POST "method".
This method is also called for subframes with non-http schemes, thus it is strongly disadvised to unconditionally call loadUrl(String) with the request's url from inside the method and then return true, as this will make WebView to attempt loading a non-http url, and thus fail.
Here is the sample demo
public class MainActivity extends AppCompatActivity {
WebView myWebView;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myWebView = findViewById(R.id.myWebView);
myWebView.setWebViewClient(new MyWebViewClient());
myWebView.getSettings().setJavaScriptEnabled(true);
myWebView.loadUrl("https://stackoverflow.com/users/7666442/nilesh-rathod?tab=topactivity");
}
public class MyWebViewClient extends WebViewClient {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if (url.equals("https://stackoverflow.com/users/7666442/nilesh-rathod?tab=profile")) {
finish() ;
Toast.makeText(MainActivity.this, "URL DETECTED", Toast.LENGTH_SHORT).show();
// perform your action here
return true;
} else {
view.loadUrl(url);
return true;
}
}
}
}
In iOS you would now be using Safari sfview so directly picking up a URL is blocked for security hence the only universal solution you can apply in both Android and iOS apps is deep linking.
You can trigger to close the safari sf view when you reach that specific URL using deep link.
Google deep link and follow the examples.
Use this can help you
myWebView.destroy();
myWebView = null;

Facebook share button finished with blank page in Android webview

When I open webview and click Facebook share, it works.
But when share is finished, it opens a blank page.
Sometimes, it doesn't open blank page and show origin page. but usually it opens blank page.
I want to show page that includes share button. always
Here is my code:
//in onCreate.
String Url = //my url//;
CookieManager cookieManager = CookieManager.getInstance();
cookieManager.setAcceptCookie(true);
view = (WebView) this.findViewById(R.id.webView);
view.getSettings().setDomStorageEnabled(true);
view.getSettings().setSupportZoom(true);
view.getSettings().setBuiltInZoomControls(true);
view.getSettings().setUseWideViewPort(true);
view.getSettings().setJavaScriptEnabled(true);
view.getSettings().setAppCacheEnabled(true);
view.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
view.getSettings().setAllowFileAccess(true);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
CookieManager.getInstance().setAcceptThirdPartyCookies(view, true);
}
view.loadUrl(Url);
view.setWebViewClient(new myWebViewClient());
view.setWebChromeClient(new ChromeClient());
//
private class ChromeClient extends WebChromeClient{
#Override
public void onProgressChanged(WebView view, int newProgress) {
MainActivity.this.setProgress(newProgress*1000);
}
public void onCloseWindow(WebView window){
super.onCloseWindow(window);
}
And here is javascript code:
function fn_facebook_share() {
var url = //my url//;
var title = "${VideoModelDetail.title}";
var user_nm= "${VideoModelDetail.user_nm}";
var univ="${VideoModelDetail.univ_cd_nm}";
FB.ui({
method: 'feed',
link: url,
name:title,
caption:univ+" | "+user_nm,
description:'text',
}, function(response){});
}
Try moving your webview to xml layout file. The blank page error was caused due to js script fail while redirecting oAuth login to authorization acceptance page. You can overcome this issue by moving your webview into xml layout.I had the same issue on my android application. The cause of the issue is FB login javascript opens a new page on a new window

Unable to execute Js code in WebView in Cordova Project

I have two activity, one main activity(A) is an CordovaActivity, then I use intent to start another activity(B), in B i have an WebView(not CordovaActivity), and after I use this webview to load a simple webpage (alert something), I found the js code is not executed at all, even if I enable javascript by calling setttings.setJsenabel(true);
I start activity B from A
Load Url from webview in Activity B
simple web page
in the device, it does not alert anything
However, if I change the webview to CordovaWebView instead of the original Android native one, it works.....
That's because plain WebView doesn't support showing alerts by itself. You need to provide a WebChromeClient to it that implements WebChromeClient.onJsAlert method. For example:
mywebView.setWebChromeClient(new WebChromeClient() {
#Override
public boolean onJsAlert(
WebView view, String url, String message, final JsResult result) {
new AlertDialog.Builder(view.getContext())
.setTitle("Alert")
.setMessage(message)
.setPositiveButton("Ok",
new AlertDialog.OnClickListener() {
#Override
public void onClick(DialogInterface dialog, int which) {
result.confirm();
}
}).setCancelable(false).create().show();
return true;
}
});

Downloading web pages and refreshing it when connection available

So I'm building an app with a lot of web content I plan to release it using Phone Gap build but will host all the content online and will link to it. I was wondering if there is a way that the web pages can be downloaded when there is an active internet connection for offline use and when there is a connection again for the data to be refreshed preferably when the user is using a wifi connection. The site will mostly be in html, js, and php. I will be hosting with bluehost
Is there any way of doing this? Thanks in advance! Littleswany!
PhoneGap apps ARE downloaded to the device, when they are downloaded from the store. They are basically a wrapper around an index.html file, but the app is actually programmed in JavaScript, which is responsible for creating and displaying views etc. The only time you need to check for an internet connection is when you are communicating with your back end (PHP)... If the ajax request fails, the best solution is to provide the user with a button/link to try again when they have regained their internet connection, or set a timer which fires intermittently to keep trying again... NEVER use a while(true) loop in your Phone Gap app - it will just hang.
I am not familiar with java, but i think i can provide the logic to get the job done.
You want to do an infinite loop that checks if the user is on wifi. Then if true, use wget, rsync, or scp to download the website. Something like this.:
while (true){
// do an if statement that checks if user is on wifi. Then do a then statement that uses rsync or wget.
}
Info on how to nest if statements in while loops in java: java loop, if else
I do not know if wget, rsync, or scp can be ran from java. You'll need to look more into it or write your own alternative function to do it. Something like:
function download_file() {
var url = "http://www.example.com/file.doc"
window.location = url;
}
You should be able to do it from your java like this:
String whatToRun = "/usr/local/bin/wget http://insitu.fruitfly.org/insitu_image_storage/img_dir_38/insitu38795.jpe";
Sources:
1. What is the equivalent of wget in javascript to download a file from a given url?
2. Call a command in terminal using Java (OSX)
First Create an Connection filter class
public class Connection_Status{
private static ConnectivityManager connectivityManager;
static boolean connected = false;
public static Boolean isOnline(Context ctx) {
try {
connectivityManager = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
connected = networkInfo != null && networkInfo.isAvailable()&& networkInfo.isConnected();
return connected;
} catch (Exception e) {
System.out.println("CheckConnectivity Exception: " + e.getMessage());
}
return connected;
}
}
And in your Main class
public class Main extends Activity{
private WebView mWebView;
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mWebView = (WebView) findViewById(R.id.webview);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setBuiltInZoomControls(true);
if(Connection_Status.isOnline(Main.this)){
HttpClient httpclient = new DefaultHttpClient(); // Create HTTP Client
HttpGet httpget = new HttpGet("http://yoururl.com"); // Set the action you want to do
HttpResponse response = httpclient.execute(httpget); // Executeit
HttpEntity entity = response.getEntity();
InputStream is = entity.getContent(); // Create an InputStream with the response
BufferedReader reader = new BufferedReader(new InputStreamReader(is, "iso-8859-1"), 8);
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = reader.readLine()) != null) // Read line by line
sb.append(line + "\n");
String resString = sb.toString(); //
is.close(); // Close the stream
}
}
}
Or you can use cache on it e.g
mWebView.getSettings().setAppCacheMaxSize(1024*1024*8);
mWebView.getSettings().setAppCachePath(""+this.getCacheDir());
mWebView.getSettings().setAppCacheEnabled(true);
mWebView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);
Don't forget to add the following permissions
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <!-- for the connection status-->
Sources:
https://stackoverflow.com/a/6503817/1309629

Android/WebView doesn't load javascript gallery images when navigated to

I have a website/web app built with jquery mobile that I am trying to package into a webview for android; I am able to load up the pages locally by putting the whole site into the assets folder and loading the url like so:
mWebView.loadUrl("file:///android_asset/www/btec/index.html");
One of the pages is a gallery/slideshow of images that flips through automatically using javascript. However, if I navigate to my gallery from index.html, the images dont load. If I load it directly (i.e. load it directly into the webview with:
mWebView.loadUrl("file:///android_asset/www/btec/gallery.html");
the images appear and scroll no problem! I'm not sure why this is happening. Is there a setting I need to enable/disable? I have the following settings enabled already:
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.getSettings().setAllowFileAccess(true);
mWebView.getSettings().setJavaScriptCanOpenWindowsAutomatically(true);
mWebView.getSettings().setLoadsImagesAutomatically(true);
mWebView.getSettings().setPluginsEnabled(true);
This a trick that probably solves your problem.
1) Create a WebViewClient class, overriding shouldOverrideUrlLoading method:
private class MyClient extends WebViewClient {
private WebView mwv;
public MyClient(WebView v) {
mwv = v;
}
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
if(url.equals("file:///android_asset/www/btec/gallery.html")) {
mwv.loadUrl(url);
return true;
}
return false;
}
}
2) Associate this client to your webview:
mWebView.setWebViewClient(new MyClient(mWebView));
Probably not the best way; but I think it works... ;)
EDIT: for other details, you can see this: http://developer.android.com/reference/android/webkit/WebViewClient.html

Categories