Tag Archives: webview

Viewport Meta Tag

Default Meta Tag

This is the default meta tag required to display the HTML5 app as it is without scaling, i.e. a scale of 1.0.

<meta name="viewport" content=" user-scalable = no, target-densitydpi = device-dpi, initial-scale=1, maximum-scale=1, width=320"/>

Note that we have used ‘device-dpi’ for ‘target-densitydpi’ as the default. Other values are ‘low-dpi’ (120dpi), ‘medium-dpi’ (160dpi), ‘high-dpi’ (240dpi).

Reference: http://darkforge.blogspot.com/2010/05/customize-android-browser-scaling-with.html

window.devicePixelRatio

An app built for the iPhone usually follows the ‘medium-dpi’ setting and if the device-DPI of a phone/tablet is lower than the ‘medium-dpi’, the HTML5 UI will appear larger (scaled up) which is generally acceptable. However, if the device-DPI is higher than the ‘medium-dpi’ that the app is developed based on. The HTML5 app will shrink and look too small compared to the physical screen dimensions, and this is not acceptable. To correct this, we need to set the ‘target-densitydpi’ value from ‘device-dpi’ to ‘medium-dpi’ for devices with higher resolutions.

In Javascript, we can use window.devicePixelRatio for Webkit browsers. A value of 1 is a 1:1 ratio of a virtual pixel to a physical pixel, a value >1 represents a high-density display.

If we do not want our HTML5 app to appear smaller than the DPI that the HTML5 app was designed for, the meta for ‘viewport’ will need to be altered dynamically as below:

if (window.devicePixelRatio>1) { // DPI higher than medium-dpi
var metatags = document.getElementsByTagName('meta');
for(cnt = 0; cnt < metatags.length; cnt++) {
var element = metatags[cnt];
if (element.getAttribute('name') == 'viewport') {
element.setAttribute('content','user-scalable = no,target-densitydpi = medium-dpi,initial-scale=1,maximum-scale=1, width=320');
}
}
}

Reference: http://stackoverflow.com/questions/1230019/how-to-set-viewport-meta-for-iphone-that-handles-rotation-properly

Tagged ,

Android WebView Threads

Threads in the Android WebView continue running even though the app is switched out to another app. My test PhoneGap app will take 4% to 5% of the CPU when active and it will drain battery power if this 4%-5% CPU is running in the background all the time. Therefore it is vital to pause the threads if the app is put in the background which will result in the CPU % to be 0% in the Android Task Manager.

In your App.java class, add the following codes:
public class App extends DroidGap {

...

@Override
protected void onPause() {
super.onPause();
super.appView.pauseTimers();
}

@Override
protected void onResume() {
super.onResume();
super.appView.resumeTimers();
}

...

This will allow the webview (named as appView) to pause and resume its threads correctly.

References:
http://stackoverflow.com/questions/2040963/webview-threads-never-stop-webviewcorethread-cookiesyncmanager-http0-3
http://stackoverflow.com/questions/3431351/how-do-i-pause-flash-content-in-an-android-webview-when-my-activity-isnt-visibl

Tagged , ,

File Upload in WebView (Android)

The Android WebView by default doesn’t open file chooser for a HTML form input of type ‘file’. However, it is possible to make this work by overriding the hidden method openFileChooser, which needs to be overridden to pop up a file chooser and then return the result to WebView.

In com.phonegap.DroidGap class, add the openFileChooser method to GapClient:

Codes:
public class GapClient extends WebChromeClient {

...
// For Android < 3.0
public void openFileChooser(ValueCallback uploadMsg) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
DroidGap.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}

// For Android 3.0+
public void openFileChooser( ValueCallback uploadMsg, String acceptType ) {
mUploadMessage = uploadMsg;
Intent i = new Intent(Intent.ACTION_GET_CONTENT);
i.addCategory(Intent.CATEGORY_OPENABLE);
i.setType("*/*");
DroidGap.this.startActivityForResult(
Intent.createChooser(i, "File Browser"),
FILECHOOSER_RESULTCODE);
}

...

Add the following code to onActivityResult():
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
if (requestCode == FILECHOOSER_RESULTCODE) {
if (null == mUploadMessage)
return;
Uri result = intent == null || resultCode != RESULT_OK ? null
: intent.getData();
mUploadMessage.onReceiveValue(result);
mUploadMessage = null;
} else {
super.onActivityResult(requestCode, resultCode, intent);
IPlugin callback = this.activityResultCallback;
if (callback != null) {
callback.onActivityResult(requestCode, resultCode, intent);
}
}
}

The webview will be able to pop up a file chooser and then return the chosen file.

Reference: http://stackoverflow.com/questions/5907369/file-upload-in-webview

Tagged , , ,

URL Redirection within the same WebView (Android)

The default behaviour of a PhoneGap when a user taps on a web link is to open the default browser app and run the web link. However, it might make better sense for the web link to open in the same PhoneGap webview instance if the web link was intended to load a remote HTML5 app that should run in the PhoneGap enviroment on the device.

In com.phonegap.DroidGap class, add in the following lines of code to process URLs starting with “androidurl://”. The problem was that “http://&#8221; URLs somehow do not trigger the “shouldOverrideUrlLoading()” event, so the workaround was to use “androidurl://” within the HTML5 app to trigger the event on the native app and then revert the URL to “http://&#8221; and process it accordingly.

Codes:
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {

...

// All else
else {
// IMPT! Fix for shouldOverrideUrlLoading() to be triggered from window.location javascript
if (url.startsWith("androidurl://")) {
url = url.replaceAll("androidurl://", "http://");
}

...
}

Tagged , ,