I've created an android app using twitter4j.
None of the api calls can authenticate when on 3g, but work perfectly when on wi-fi. What could be the problem?
I've tested this extensively and can confirm this is only a problem on Android 4.0 (ICS) devices. Why, I'm unsure yet, though some parts of HttpURLConnection have changed in 4.0, so some of these changes have made twitter4j incompatible.
I thought it may have been this: Android 4.0 ICS turning HttpURLConnection GET requests into POST requests
but after analysing the requests with tcpdump it seems like it is in fact making a valid GET, but for some reason, the twitter api still says it's a bad request..
GET /1/users/show.json?include_entities=true&user_id=6842472 HTTP/1.1
Authorization: OAuth oauth_consumer_key="<redacted>",oauth_signature_method="HMAC-SHA1",oauth_timestamp="1331150787",oauth_nonce="2157367237",oauth_version="1.0",oauth_token="<redacted>",oauth_signature="<redacted>"
Accept-Encoding: gzip
X-Twitter-Client-URL: http://twitter4j.org/en/twitter4j-2.2.5.xml
User-Agent: twitter4j http://twitter4j.org/ /2.2.5
X-Twitter-Client-Version: 2.2.5
X-Twitter-Client: Twitter4J
Host: api.twitter.com
Connection: Keep-Alive
HTTP/1.1 400 Bad Request
Date: Wed, 07 Mar 2012 20:06:30 GMT
Status: 400 Bad Request
X-RateLimit-Class: api
X-RateLimit-Reset: 1331153824
X-Revision: DEV
Last-Modified: Wed, 07 Mar 2012 20:06:30 GMT
X-Frame-Options: SAMEORIGIN
X-Transaction: a0bf805e990a5c79
Content-Type: application/json; charset=utf-8
X-RateLimit-Remaining: 0
X-RateLimit-Limit: 150
Pragma: no-cache
Cache-Control: no-cache, no-store, must-revalidate, pre-check=0, post-check=0
X-Runtime: 0.00742
X-MID: 2295d07237fcb4763f7f54d2bf46e27dd40e022f
Expires: Tue, 31 Mar 1981 05:00:00 GMT
Vary: Accept-Encoding
Server: tfe
Transfer-Encoding: chunked
Connection: close
Content-Encoding: gzip
Set-Cookie:
...
Unless someone can find what it is in ICS/HttpURLConnection that is breaking this the only workaround I can see is to write an alternate backend for twitter4j that uses HttpClient instead of HttpURLConnection, which is exactly what I plan to do.
EDIT: So I wrote the a client backend for twitter4j that uses the apache httpclient and it suffers from the exact same problem!! Some more sleepless hours and wireshark has brought me to the following very handy solution, that actually works:
Initialise your twitter4j instance like this:
ConfigurationBuilder configurationBuilder = new ConfigurationBuilder();
configurationBuilder.setOAuthConsumerKey(Const.CONSUMER_KEY);
configurationBuilder.setOAuthConsumerSecret(Const.CONSUMER_SECRET);
configurationBuilder.setUseSSL(true);
Configuration configuration = configurationBuilder.build();
twitter = new TwitterFactory(configuration).getInstance();
The setUseSSL(true) is the magic line.