Category Archives: PhoneGap

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

Advertisements
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 , ,

HTML5 Offline Solution

Although PhoneGap is an offline solution where the HTML, CSS and JS files etc are held in the assets/www folder within the app, there are some cases where you might want the app to point to a remote server where the HTML5 file and its CSS/JS are located. They can be downloaded onto your device and ran as offline files when the device has no Internet connection.

The requirements to trigger the HTML5 offline cache are detailed below and each requirement must be implemented with care, otherwise it will not work:

1) The MIME Type for a Manifest file.
This is very important. Previously I have followed a solution to add a mime type by using a .htaccess file and place it together with index.html of my HTML5 app, but it didn’t work.

In my case, I was using the Tomcat server and the surefire way that the .manifest file will be correctly used by the server, is to modify “/conf/web.xml” and add in the mime mapping as below:
<mime-mapping>
<extension>manifest</extension>
<mime-type>text/cache-manifest</mime-type>
</mime-mapping>

2) Specify the Manifest File
This is a standard configuration. For every HTML file that wants to use the cache manifest, they have to update their tag to

3) Configure the Manifest File
The manifest file is a text file that you have configure to tell the HTML5 app what is to be cached for offline use. A sample file is below:
CACHE MANIFEST

# Version 0.1

# Explicitly cached entries
index.html
jqtouch/jqtouch.css
jqtouch/jqtouch.js
jqtouch/jquery-1.4.2.min.js
js/common.js
images/1.png
images/2.png

# All other resources (e.g. sites) require the user to be online.
NETWORK:
*

* note that the manifest file only caches static resources such as .html, .js and images, so files like JSP pages will not be applicable here.

***VERY IMPT: Each entry to be cached must be correctly named and if the entry is there, the physical file must be there, otherwise the whole caching will fail!

4) For iOS, steps 1-3 are sufficient for HTML5 offline caching to work. However, in the case of Android, we need to fix the Android Shell Native App to enable HTML5 caching:

In your App.java class, there are these lines of codes to be added as part of the solution to enable HTML5 caching:
public class App extends DroidGap {
...
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

...

super.appView.getSettings().setDomStorageEnabled(true);
super.appView.getSettings().setAppCacheMaxSize(1024*1024*8);
super.appView.getSettings().setAppCachePath("/data/data/com.yourdomain/cache");
super.appView.getSettings().setAllowFileAccess(true);
super.appView.getSettings().setAppCacheEnabled(true);
super.appView.getSettings().setCacheMode(WebSettings.LOAD_DEFAULT);

...
}
...
}

Reference: http://alex.tapmania.org/2010/11/html5-cache-android-webview.html

Tagged , ,

HTML5 App Within a Native Shell App

The 2 previous postings were about getting the native apps up and running for their respective Android and iOS environments. The official guide takes you to a Hello World index.html which merely displays a static message. In reality, the app that your user will interact with is the UI of the index.html or the HTML5 app. The underlying native app that runs the index.html is what I call a Shell Native App.

So, the actual primary app is a HTML5 file with various supporting web libraries to fulfill the functions of a full-fledged mobile app. Generally, it should have the following supporting technologies to give it the native look and feel and experience:

1) jQuery (www.jquery.com)
2) AJAX (With AJAX, our mobile application can send data to and retrieve data from a server asynchronously (in the background) without interfering with the UI experience of the existing page.)
3a) jQTouch (www.jqtouch.com)
3b) jQuerymobile (www.jquerymobile.com)

As for the Shell Native Apps, they host the app icon, the splash screen, PhoneGap libraries and other native information. If you require certain native functions, it is inevitable that you will need to modify the natives codes for your Shell Native Apps. A good example would be the implementation of Push Notifications for both iOS and Android, you are unable to do this in the HTML5 app, which means you have to put in codes in your Shell Native App.

In summary, PhoneGap is a bridge that allows the HTML5 app to call PhoneGap Javascript (JS) methods which will call PhoneGap native methods in your Shell Native Apps, of course there are native events that can call JS events which you can use in your HTML5 apps. Not all native methods can be called from JS, so some native programming would be expected depending on your app requirements.

Tagged , ,

Getting Started with PhoneGap (iOS)

The main steps are already detailed on the official PhoneGap site – http://phonegap.com/start.

Below are my tried and tested steps for your reference to get the iOS environment up and a test App running on a Mac OSX (Lion) machine. It is not intended to be comprehensive and there are more details available on the web. Once you got the environment up and deploy the test app to your device successfully, you can add in the steps to create a PhoneGap app from the official guide above.

Getting Started with Running an iOS App in XCode4

1) Ensure that your Mac machine is running on Lion OSX 10.7 Mac OS X 10.7 because XCode 4.2.1 with SDK 5 only runs on Lion.

2) Go to the App Store app on your Mac machine and search for XCode4 and install it.

3) Download and extract SimpleDrillDown.zip (a sample iOS app) by double-clicking it and it can be downloaded from: http://developer.apple.com/library/ios/#samplecode/SimpleDrillDown/Introduction/Intro.html#//apple_ref/doc/uid/DTS40007416

4) Open the SimpleDrillDown folder and double-click on SimpleDrillDown.xcodeproj to load this project in XCode4.

5) From the dropdown box above, select the iPhone Simulator (any version 4.3 or 5.0). Click on Run to build and run the project.

6) iPhone Simulator will load and run the SimpleDrillDown app.

Configure to Deploy on An Actual Device (Done Once Only)

1) Login to iOS Dev Center (https://developer.apple.com/devcenter/ios/index.action) using your Apple ID. You must have a paid subscription (at USD$99 per year) to the iOS Developer Program in order to log into this portal.

2) Go to the iOS Provisioning Portal

The license is tied to ONE main Mac machine only. So if you are changing to a different Mac machine, be sure to revoke the Current Development Certificate in the Provisioning Portal first. Then follow the steps to generate the CSR to disk and submit and download and use the new Development Certificate.
However, a better way is to export the Development certificate with the private key and import into the 2nd Mac machine.

3) Scroll to the bottom to “Get your application on an iOS with the Development Provisioning Assistant” and click on “Launch Assistant” and click “Continue” and follow the steps.

4) Assuming all the necessary are set up, connect your iOS device to your Mac machine, e.g. an iPhone.

5) Open the SimpleDrillDown folder and double-click on SimpleDrillDown.xcodeproj to load this project in XCode4.

6) From the dropdown box above, select the first option which should be the name of your iOS device. Click on Run to build and run the project.

Adding Another Device

1) Connect the new device to the Mac machine.

2) Open XCode4 and go to Window -> Organizer.

3) Select the new device from the list and click on the “Add to Portal” button.

4) Enter your Apple ID and password when prompted.

5) If there are no errors, you should be able to run the iOS app on the new device.

Tagged , , ,

Getting Started with PhoneGap (Android)

The main steps are already detailed on the official PhoneGap site – http://phonegap.com/start.

Below are my tried and tested steps for your reference to get the Android environment up and a test App running on a Windows 7 machine, then you can add in the steps to create a PhoneGap app from the official guide above.

Getting Started with Running an Android App in Eclipse

1) Download and extract Eclipse Classic 3.7.1, 174 MB from http://www.eclipse.org/downloads.

2) Download the Android SDK installer (installer_r16-windows.exe) at http://developer.android.com/sdk/index.html. Make sure that you change the installation directory to “c:\android-sdk” for example, it must be a PATH with NO spaces! When the installation is done, run SDK Manager and it will download and install some files which will take some time, make sure that Android SDK Tools/Platforms are installed.

3) In SDK Manager window, go to Virtual Devices and add a new device called Android2.3.3 and select Target to be “Android 2.3.3 – API Level 10”, click on “Create AVD”. (You can add more devices with different versions as you please)

4) Run Eclipse and start to install the Android Development Tools (ADT) plugin for use with Eclipse, the repository url is “https://dl-ssl.google.com/android/eclipse/&#8221;. Follow the steps here to configure the ADT: http://developer.android.com/sdk/eclipse-adt.html#installing.

5) Start a new Android Project by clicking File > New > Android Project.

  • In the New Android Project dialog, select Create project from existing source.
  • Click Browse and navigate to where the SDK is installed and select Spinner, e.g. C:\android-sdk\samples\android-13\Spinner
  • Android 1.5 will be selected as the Build Target and click on Finish.
  • Go to Project -> Clean to build the project.

6) Right-click on SpinnerActivity project and Run As -> Android Application. It will run with the Android 2.3.3 AVD created before.
7) The Android emulator will run and note that it takes a while to load.

Deploy and Run on An Actual Device

1) Depending on the model of your phone, e.g. Samsung or HTC etc, you will need to download the driver for the phone here: http://developer.android.com/sdk/oem-usb.html. In my case, I use the Samsung Galaxy S and I have to install the Samsung Kies software.

2) Follow the instructions to configure your Android phone for Development at: http://developer.android.com/guide/developing/device.html.

3) Then connect your phone to test if it can be detected by the Android SDK using a command prompt and go to “C:\android-sdk\platform-tools” and run “adb devices” to see a list of devices connected.

The output from the command will be something like this:
List of devices attached
35311BC91FD700EC device

4) In Eclipse, right-click on SpinnerActivity project and Run As -> Run Configurations.

5) Click on the Target tab and change the Deployment Target Selection Mode from Auto to Manual and click on Run. This will allow you to choose the device instead of the AVD.

6) Select the device and click OK.

7) The app will be running on your Android phone.

Adding Another Device

1) Follow the same steps as above and depending on your model of your phone, download the correct USB drivers.

Tagged , , ,

PhoneGap – A Device Independent Platform

With Apple’s iOS and Google’s Android mobile OSes dominating the current mobile market right now, it would make perfect sense for a company to develop mobile apps for these 2 major mobile OSes.  However, to develop a native mobile app for iOS and another native mobile app for Android, this would incur two tracks of development. This is because the programming languages (in Objective C for iOS and Java for Android) and their IDEs/tools are different and require developers of different expertises.

Enter PhoneGap (www.phonegap.com), the HTML5 platform to create a single codebase to deploy to iOS, Android and various mobile platforms. It uses HTML5, Javascript (JS) and CSS familar to many web developers and its JS library can access the device’s native capabilities such as the phone contacts, camera/album and internal data storage. Essentially, a PhoneGap app is a native app that presents a ‘webview’ or an embedded browser that takes up the whole screen. It loads an index.html which is your HTML5 app. From this HTML5 app, you will be coding your UI and logic in JS/jQuery and use AJAX calls to retrieve data. This is the alternative to coding a mobile app using Web technologies. You can choose to embed jQuery UI frameworks such as http://jquerymobile.com/ or http://jqtouch.com/ to simulate finger-friendly UIs for touch and CSS3 features for Webkit animations.

To keep my post short, there is a good comparison on the pros and codes of native vs. web technologies here: http://interfacethis.com/2011/is-html5-ready-for-prime-time-vs-native/ and many other comparisons that you can find on the Internet. But you will appreciate the differences and trade-offs if you have done both native and PhoneGap development before.

In summary, with PhoneGap, there will be a consistent UI that looks the same on both iOS and Android platforms and there is one main HTML5 codebase to maintain. I will not touch on how to start off coding a PhoneGap app as these are covered on the official site and there are many articles on how to use jQuery UIs with PhoneGap as well.

Things are not that rosy with PhoneGap, as there are still differences and tweaks required on each platform to get PhoneGap working the way you want it to…

Tagged ,

A Journal and a Journey

Apps development – whether for mobile or desktop or enterprise apps – is a journey in itself. Codes and SDKs are constantly changing and evolving and to ‘marry’ them together to form an usable app is a meteorological challenge. Apps developers are the guys who experiment constantly to get real software to work, they get their hands dirty – grease, nuts and bolts – to bring their creations to life. Anyone could have all the documentation and theory in the world but once you start to integrate codes and frameworks, their tiny and often undocumented differences can cause the best framework to break and nothing works at all.

This little journal will show you the way to some hair-pulling experiences in the mobile development journey. It’s the stuff that works after some hours of scouring the universe of the Internet for specific solutions. For a start, my journey begins with PhoneGap (www.phonegap.com) – a HTML5 platform that can be deployed to many different mobile platforms and run native functions. Is it truly platform-independent and near-native in user experience? Well, not quite… be prepared to drop some expectations, so read on for some of the challenges I have faced in the development of a PhoneGap app for the iOS and Android platforms.

Tagged