I've been using IMAP to access my work emails because it's much easier (for me) to read and write, but for over a year I've had to log into Gmail's web interface to copy email addresses for new employees or people I've never had to email before.

This references the default proguard configuration, and then your own local one defined in "local.properties". You should not commit "local.properties" to source control as it's generated for the local development machine.

Installing Thunderbird 24 was a pretty good experience, but some little quirks have been getting on my nerves.

One of them is automatically clipping the response email with whatever you had selected. It doesn't really work for me because I like to highlight as I read, and it becomes very annoying after replying to a handful of emails.

Chef selecting a handful of umm... emails.

From the main menu:

Click "Tools" > "Options"

In the Options dialog, go to "Advanced" > "General" and click on the "Config editor"

If you get a little warning, agree to be careful

Start filtering with "mailnews.reply_quoting"

Change "mailnews.reply_quoting_selection" to false by double clicking it

The changes should take effect immediately, so no need to restart Thunderbird.

Gingerbread still holds up to 30% of all device market share on the Play Store at time of writing.

The solution

I'm not gonna lie, this is only a half-baked solution butAWESOME and it's the best I can find so far. It's a method first discovered (or published) by Jason Shah of PhoneGap, then tweaked by Mr S (StackOverflow) to detect multiple versions of Gingerbread.

Unfortunately, there are a few flaws with his implementation which I've taken upon to fix (red ones are still unresolved)

Not synchronous, so we can't return values between JS/Java (without callbacks)Fixed 17/9/13

Unable to access interface from iframes

Required each methods in JSInterface to tokenize a single String argument to accommodate for lack of bridging support

Required you to manually map out all methods in the interface

Issues with commas/double quotes in strings breaking JS

String separator is cumbersome in case data had break string in it

It wasn't clear on how to change the interface name

I then took this code and modified it so most of the issues have been ironed out (to a degree).

I wasn't too keen on subclassing the WebView, so here's the helper function. (Don't worry, all the code will be made available for easy copy-pasting in GitHub along with more detailed comments).

GingerbreadWebViewClient and GingerbreadWebViewChrome contains pretty much all the workaround logic, so prepare yourself for a lengthy snippet!

How it works

Normally, JavaScript in the WebView is able to call Android functions via the interface name "Android" or whatever name we gave it. For example:

Android.showToast("Hello! Is it me you're looking for?");

At the fixWebViewJSInterface() level, the fix is relatively simple. Anything other than Gingerbread 2.3 will use the normal JavaScript interface implementation addJavascriptInterface().

However anyone on Android 2.3 we'll have to treat a little differently, but be glad to know that the JS code itself is (mostly) the same. We DON'T actually set the interface, but instead mark the interface as broken and let GingerbreadWebViewClient/GingerbreadWebViewChrome handle the rest as it'll:

Wait until the page has finished loading

Generate JS code based off your JSInterface class methods

Inject our own "Android" interface object into the page

Call android_init() at the end of it all (even on non-Gingerbread Android)

GingerbreadWebViewClient is responsible for the JS code injection and re-injection into the broken WebView.

Regarding the JS code generated:

Declares an "Android" object so we don't have to change the JS code we write in the WebView

Replicate the method names into the "Android" interface object

All the methods will wrap Android._gbFix()

_gbFix() is a function which seals the function arguments (and some meta data) into JSON

The JS signature is appended to the generated JSON and passed to GingerbreadWebViewChrome via prompt()

prompt() will wait for a response, thus making it a synchronous call

Calls by prompt() from the WebView's JS to the Android interface will trigger these events within GingerbreadWebViewChrome:

onJsPrompt() picks up the prompt() call and checks the message for the JS signature

Decode the meta data from the JSON bubble-wrap

Attempt to map the method back to the JSInterface class we've defined and invoke it

/** * What this JS wrapper function does is convert all the arguments to strings, * in JSON format before sending it to Android in the form of a prompt() alert. * * JSON data is returned by Android and unwrapped as the result. */ public String generateJS() { StringBuilder gbjs = new StringBuilder();

If you're using a custom WebViewClient and/or WebChromeClient, simply change the subclasses for your one or merge the code somehow. I'll assume you're capable enough as no support will be given here.

Maybe this guy's a little TOO capable...

Things you should be aware of

android_init()

Due to the delay between page load and JS injection, you have to assume that the JS interface is NOT available to you until android_init() has been called. Because of this, you must always declare android_init(), even if it's not used.

If you have any code in $(document).ready() or onload() which uses the Android interface, you may want to move it into android_init().

I think this is a fairly small trade-off for the convenience this method provides.

JSInterface method parameters

The JavaScript calls can be a mixture of numbers and strings, but all parameters in JSInterface Android class must be of type String.

This could probably be fixed later, but I was short on time and chose to convert all the arguments into strings when invoking the method.

Limitations

Not synchronous, so we can't return values between JS/Java (without callbacks)Fixed 17/9/13

Unable to access interface from iframes

Required each methods in JSInterface to tokenize a single String argument to accommodate for lack of bridging supportSee android_init() limitation and JSInterface method parameters

Required you to manually map out all methods in the interfaceNow automatic

What you'll need

Download and install Twython from the site or via "pip install twython".

Setting up twitter

What you'll need for this to work is a twitter "app" associated with your account. For the purpose of this tutorial, I'll show you how to set up your own account with your own app for testing purposes.

This setup can also be used for stuff like fetching/searching tweets using the twitter API, but just read the docs to find examples of that. Just be aware of the limitations which the twitter API impose before conjuring anything on a grand scale.