I'm trying to build a simple localStorage example using android webview. I'm having some trouble when i close the app. Everytime i start the app, values stored in localStorage disappear. I googled it and couldn't find a proper solution. Here I put my HTML, Java, Manifest code samples. Any help will be appreciated.
HTML :
<!DOCTYPE html>
<html>
<head>
<script>
function clickCounter()
{
if(typeof(Storage)!=="undefined")
{
if (localStorage.clickcount)
{
localStorage.clickcount=Number(localStorage.clickcount)+1;
}
else
{
localStorage.clickcount=1;
}
document.getElementById("result").innerHTML="You have clicked the button " + localStorage.clickcount + " time(s).";
}
else
{
document.getElementById("result").innerHTML="Sorry, your browser does not support web storage...";
}
}
</script>
</head>
<body>
<p><button onclick="clickCounter()" type="button">Click me!</button></p>
<div id="result"></div>
<p>Click the button to see the counter increase.</p>
<p>Close the browser tab (or window), and try again, and the counter will continue to count (is not reset).</p>
</body>
</html>
JAVA:
webView.getSettings().setJavaScriptEnabled(true);
webView.getSettings().setDomStorageEnabled(true);
webView.getSettings().setDatabaseEnabled(true);
webView.getSettings().setDatabasePath(this.getApplicationContext().getDir("database", Context.MODE_PRIVATE).getPath());
webView.loadUrl("http://www.example.com/sample.html");
setContentView(webView);
MANIFEST:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
Permission lines are placed under tag but outside the tag
and here is the scenario:
-turn off the internet connection of the mobile device
-start the app
-open the page inside the webview
-tap the button several times
-close the app (close it inside the task manager)
-turn on the internet connection of the mobile device
-start the app
-open the page
-tap button several times and it counts from beginning
you can create different scenarios while trying. The main problem is how to set the webView to use localStorage properly?There is something that i'm missing about webview.(this error does not occur when you try it on the chrome browser or any other browser)
This seems like a bug of webview. I was actually trying to open 3 different pages inside a webview and I was loosing localStorage data. I splitted this activity into 3 activities that each of them opens only one page. And the problem disappeared.
Related
I have one cordova app that loads content directly from client website.I have used it like <content src="https://example.com/ios/index.html"> in config.xml file.I have used the splashscreen delay of 6 seconds.and the issue is when the splash screen hides shows the black screen for 5-10 seconds and after that client website content is shown.and also sometimes i am getting the error CONNECTION TO SERVER WAS UNSUCCESSFULL.I have also specified <preference name="loadUrlTimeoutValue" value="700000" /> but still having same issue.Anyone having the same issue for cordova ios and android app?can anyone help me with this issue.
You shouldn't do it like that. Now I don't want to play this script where you ask A and I tell you to do B, don't worry, but it's really not the way you should do it.
You should make cordova load an index.html which loads a javascript file cordova.js. You don't need to actually have it, the js file will be included when you compile the app.
Then you should add the whitelist plugin in case you don't already it, in order for your website to load correctly. https://www.npmjs.com/package/cordova-plugin-whitelist
You should disable auto-hide for the splashscreen in config.xml like so:
<preference name="AutoHideSplashScreen" value="false" />
You should then make the javascript load a fullscreen iframe with your website like so, then detect when loading has finished: (This should go into your index.html, in the cordova app)
<html>
<head>
<title></title>
</head>
<body>
<iframe id='frameid' onload='iframeLoaded();' src='https://mywebsite.com/mypage.html' style='border: 0; width: 100%; height: 100%'>Your browser doesn't support iFrames.</iframe>
<script src='cordova.js'></script>
<script>
iframe = document.getElementById("frameid");
iframe = document.getElementById("frameid");
function ready(callback){
// in case the document is already rendered
if (iframe.readyState!='loading') callback();
// modern browsers
else if (iframe.addEventListener) iframe.addEventListener('DOMContentLoaded', callback);
// IE <= 8
else document.attachEvent('onreadystatechange', function(){
if (iframe.readyState=='complete') callback();
});
}
ready(function(){
setTimeout(function(){
navigator.splashscreen.hide();
},555)
});
</script>
</body>
</html>
I haven't used cordova for a few months but that's how I did it if I didn't forget anything - Hoping I didn't... I didn't have time to test this, but you get the gist:
App start
Show Splashscreen
Load Index.html with Iframe in fullscreen pointing to https website.
Wait for iframe to finish loading.
Close splashscreen
Tell me if you run into any issue and I can help you further.
Scenario:
I'm using Android Robotium Solo (v5.6.3) to automate web page interactions within my app. I need to automate data entry into INPUT fields that are contained within an IFRAME but I do not have much luck!
The Problem:
When I attempt to use, for example, solo.waitForWebElement(By.id("room-number", 5000, true) and solo.typeTextInWebElement(By.id("room-number", "101"), solo is unable to locate the element.
The discussion on this related issue "Accessing an iFrame inside a WebView #794" (https://github.com/RobotiumTech/robotium/issues/794), suggests that it's possible to use "solo.getConfig().webFrame = XXX" to focus solo on the content of a specific IFRAME and then access the WebElements. Unfortunately, I've not been able to get it to work and haven't been able to find any full examples. I assume XXX might need to be the "id" of the IFRAME but in my scenario (where I don't have control of the source code for the web pages being automated) the IFRAME tag has no id assigned.
I've created a simple example test scenario:
index.html - the main page that hosts the IFRAME
<html>
<body bgcolor="#AA3333">
<div id="wrapper">
<iframe src="embed.html" width="100%" height="100%" frameborder="0"></iframe>
</div>
</body>
</html>
embed.html - the source for the IFRAME that contains the INPUT element.
<html>
<body bgcolor="#3333AA">
<div id="page-container" style="height:100vh; width:100%;">
<label>Room Number</label>
<input type="text" name="ROOM_NUMBER" id="room-number">
</div>
</body>
</html>
After reviewing the source code for Robotium in more detail I confirmed that using
solo.getConfig().webFrame = ['id' of IFRAME as a String]
allows subsequent calls to solo.typeTextInWebElement etc. to work OK as expected.
The trick in my scenario is that the parent page assigned no id to the IFRAME so I programatically assign one at runtime using the following javascript
document.getElementsByTagName("iframe")[0].id = "test";
and then use
solo.getConfig().webFrame = "test"
I've been wrestling with making calls to window open, using inappbrowser from within my app. Basically, I'm using phonegap as a wrapper to load up a mobile skinned CMS site with special app features.
Here is the index.html. I'm using inappbrowser (with location set to no).
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head>
<title>Emerald Test App</title>
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="viewport" content="width=device-width" />
<script src="phonegap.js"></script>
<script type='text/javascript'>
var ref = null;
function onLoad() {
document.addEventListener("deviceready", onDeviceReady, false);
}
function onDeviceReady() {
var url = 'https://my-cms-site.com/content.aspx?page_id=31&org_id=1&app=1';
var target = '_blank';
var options = "location=no"
ref = cordova.InAppBrowser.open(url, target, options);
}
</script>
</head>
<body onload="onLoad()">
</body>
</html>
What I'm looking to do, is open links in a system browser - from my external site loaded through inappbrowser
I've tried downloading files using similar documentation and suggestions from posts like
<script type="text/javascript">
window.open(url, '_system');
</script>
And _blank, and adding 'location=no' etc, but no dice. These are external pages, loaded from my remote site.
When these links are clicked, they open in the same browser (inappbrowser or webview) and take over the browser. What I'm looking to do is open these up in another system browser (chrome, safari, whatever). This would take care of my download issue (as the files will hopefully open up in the system browser and the user can figure out what to do with them).
I've tried to add an event listener, and executescript to return a value of the href. Then use that value to window.open(href,'_system'); from the index.html (instead of the remote page). Because on the index, I will still have the reference to inappbrowser.
ref.addEventListener( "loadstop", function() {
ref.executeScript(
{ code: "var gbal = null; $('a').on('click', function() { gbal = $(this).attr('href'); }); (function runIt() { return gbal })();" },
function( values ) {
if (values != null) {
//alert( values[ 0 ] );
window.open(values[0],'_system');
}
}
);
});
}
The values[0] is always null. Which seems to indicate I'm not doing something correctly in the code: portion of executescript - or $(this) is not really this
So, big question - how can I open links in my external site in a system browser. window.open('whatever.htm', '_XXXXX') makes no difference when called on my remote site. Am I on the right track by using an event listener?
Answering my own question here so anyone facing a similar situation can get a solid answer. I've pieced this together from other posts, references and documentation.
So you want to open up a link to an external browser, in a remote loaded site in InAppBrowser?
On your remote site, you will need to include a script src to your cordova.js file, your cordova_plugins.js file, and include your plugins folder. These files must be hosted on your remote site.
I am choosing to load mine conditionally if I know it's the "app". The cordova files when loaded will throw a series of alerts, so you won't want to load these unless you know it's the app.
Where do you get these files? I installed Phonegap Desktop and used the files from the build, but had some reference errors. I instead used Phonegap Build, and extracted the files from the APK. Renamed the appname.apk to appname.apk.zip and extracted/copied the needed js files to my server. *There are some issues with platform differences, and the cordova.js file will need to be altered and conditionally loaded for iOS/Android.
These are necessary so you have handles to the inappbrowser (and in the case of my "close the app" requirement - navigator).
On my remote (external) site (after I have loaded the cordova/plugins) I can now close the app with a simple call to
navigator.app.exitApp();
In the pages of my remote (external) site loaded in inappbrowser, I can now open links in external pages by doing something like this:
<a onclick="loadUrl('http://google.com'); return false;" href="#">Test link, don't click</a>
<script type="text/javascript">
$('.closeapp').click(function() {
navigator.app.exitApp(); //this only works on Android. iOS doesn't allow for programmatic exit
});
function loadUrl(url){
navigator.app.loadUrl(url, { openExternal:true });
return false;
}
</script>
I plan on modifying the loadURL function somewhat using jquery, to be handled on click and look for a class. Something like:
$('.downloadable').click(function() {
var url = $(this).attr('href');
navigator.app.loadUrl(url, { openExternal:true });
});
The above only works for Android.
Trying a vanilla window.open('http://www.whatever.com', '_system') doesn't open an external browser in iOS from my external site. I thought about using another ref = cordova.inappbrowser.open() from inside my external site? That doesn't work. Anyone have any ideas?
I have a WebView inside my android app, and this WebView is running a website with a fair bit of Javascript on it. Users have reported high power consumption when my app is running in the background, and I expect it is due to this javascript. However, I don't want to completely unload or remove the WebView, as this would hurt the time-to-resume.
Is there any way to selectively turn off Javascript and/or disable the WebView completely when the app is in the background (onPause())?
Accoring to http://www.mcseven.me/2011/12/how-to-kill-an-android-webview/ the only working way is to redirect to empty page with no javascript (and return back after resume).
In case of PhoneGap, the page should contain a code to return itself:
<!DOCTYPE html><html><head>
<script type="text/javascript" src="js/phonegap/cordova-2.9.0.js"></script>
<script type="text/javascript" src="js/jquery/jquery-1.9.1.min.js"></script>
</head><body>
<script type="application/javascript">
$(document).on('deviceready', function() {
$(document).on('resume', function() {
return history.back ? history.back() : history.go(-1);
});
});
</script>
</body></html>
Update: The above is for Cordova 2.x.x. In Cordova 3.x.x (not sure if since 3.0.0, but for sure in currect 3.7.x) you can simply add KeepRunning preference in your configuration XML:
<preference name="keepRunning" value="false" />
This will pause all JS timers until the APP is resumed again; see https://stackoverflow.com/a/21629586/2011448.
I have a WebView which may contain data that appears to be getting "auto linked". Something that looks like an email address is becoming clickable, even though it's now within an <a> tag or has an onclick attribute. How do I disable this auto-linking?
I've looked thorugh the WebView docs, as well as the WebSettings docs, but didn't seem to see anything that mentions this behavior.
alt text http://beautifulpixel.com/assets/5554_Fast-20100706-110228.png
I know this is a bit late, but for future reference, this might be a solution that will work regardless if the links are auto created or defined in the <a>-tag.
myWebView.setWebViewClient(new WebViewClient(){
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
// return true; // will disable all links
// disable phone and email links
if(url.startsWith("mailto") || url.startsWith("tel")) {
return true;
}
// leave the decision to the webview
return false;
}
});
To do all the email addresses, add a meta tag:
<meta name="format-detection" content="email=no" />
You can also disable physical address and telephone detection:
<meta name="format-detection" content="telephone=no" />
<meta name="format-detection" content="address=no" />
In my own application, though, I needed PhD's solution to prevent only one email from being linked.
I had the same problem, tried this:
<a onClick=\"return false;\">jorgesys#elnorte.com</a>
it did not worked.
Then tried this:
<a href='javascript:void(0);'>800-644-9737</a>
and it did the trick
Hi Squeaggy why you do want to eliminate that funcionality from the webview, but well a tricky way would be including onClick="return false;" in the anchor tag that contains the email or URL.
<a onClick=\"return false;\">jorgesys#elnorte.com</a>
That appears to be unchangeable functionality of the WebView.
You could do the opposite of this Is there any way to have WebView auto-link URLs and phone numbers in Android? and create a javascript link stripper (instead of the proposed link injector there).
Not sure what else would work for this.