Why Android scrolling feels “wrong”


Video link

Android, or at least the UI framework, ignores the first few touch events it gets if it’s doing a bunch of other things, like rendering a webpage. This leads to things like trying to scroll a certain distance, and having the page, or list scroll only a small fraction of that distance, or trying to fling a page or list, and having it move with very little inertia.

Android’s new developer options allow you to see where the hardware thinks your touch is, from the last touch down event to the last touch up event. This is useful for demonstrating this bug.

If you’re at the top of a web page, and you scroll down the web page, and then back up to the top in an upside down V pattern, the tips of the V should be at the same height, since, in order to move the page up and down, your finger should have to begin and end at the same height. It’s a little bit hard to see, but in the video, this is not so. Android has been widely criticized for being laggy, and feeling wrong, (whatever that means) this explains in more concrete terms, one origin of that “wrong” feeling.

Demonstrated on an ASUS TF101 Transformer, running Android 4.0.3, although this has been a problem since the G1, and Android 1.5.

I’ve submitted the bug here, so feel free to star it if you’ve experienced the same issues.

Comments off

Volume down bug in Galaxy Nexus

Dangit, I was really looking forward to this phone too. Apparently, Galaxy Nexus owners in the UK are experiencing an odd, intermittent bug where the phone mutes itself.

In the original post, a commenter linked to a video demonstrating that another phone using the 900mHz 2G network held next to the Galaxy Nexus could trigger the volume down button while it was in Bootloader mode, meaning a software patch wasn’t going to do much.

I’m excited about this phone, but this bug’s going to make me hold off on buying the Galaxy Nexus until I hear that it’s been fixed.

Comments off

Random crashes with the x120e on Ubuntu

So the last hangup I’ve had is random crashes on resume, and sometimes on suspend. Through a whole bunch of googling, I found that people more knowledgable than me pinned it down to the wireless drivers. If you’re experiencing crashes on 11.04, you use lsmod, and see that you’re using the r8192ce driver instead of the r8192ce_pci driver, then you have the same problem I was.

You can probably just go to Administration -> Additional Drivers, and it’ll find the appropriate drivers for you and install them.

Additionally, I blacklisted these drivers:

blacklist rt2800pci
blacklist rt2800lib
blacklist rt2x00usb
blacklist rt2x00pci
blacklist rt2x00lib
blacklist rtl8192ce

and used the aspm=force kernel option.

My laptop’s been running really stably for a few days now, so all this seems to have solved my problems.

Comments off

Twitchy touchpad in Ubuntu on the x120e

So two-finger scrolling on the x120e has been acting unusably twitchy. Fixing this requires some command-line craziness.

1) xinput list
2) Find Synaptics Touchpad in the list of devices, and find the ID. (In this case, 12)
3) xinput set-prop –type=int 12 “Synaptics Finger” 44 49 255

This sets the Finger property. The first number, 44, is the pressure needed to register a touch up event. The second is a touch down event. The last is the pressure needed to count as a press. The defaults, 24 29 255 are way too light, and result in a lot of twitchyness when lifting a finger, so this takes the sensitivity down a notch.

NOTE: These changes won’t persist after you log out, so in order to make them stick, create or modify an .xsessionrc file in your home directory, and add the line from step 3.

Comments off

Ubuntu and Windows 7 dual-boot on the Lenovo x120e

So, I decided to get a Lenovo ThinkPad x120e for development purposes. The Chromebook I got from Google I/O made me appreciate the value of a light laptop with massive battery life, and the experience of installing Ubuntu on it made me think that I could actually start using something like that for development purposes. Of course, the disadvantages of the Chromebook are that it’s not necessarily easy to install different OSes on it, and the stupid, stupid touchpad. The SSD can be upgraded, so that’s not a big deal.

–RANT–
One of the reasons I got into Android way back in the G1 days was that I wanted a decent smartphone, but having played around with iPhones, I really liked physical keyboards as well, so along comes the G1, and I was instantly sold. The trend towards buttonless trackpads is terrible for the same reasons soft keyboards aren’t the end all, be all. A soft keyboard will NEVER be as comfortable as a real one for extended typing sessions, and buttonless trackpads will ALWAYS misinterpret your touches a certain percent of the time.
–END RANT–

Anyway, the x120e comes with a few disadvantages too:
1) It’s default Windows 7 installation comes with a ton of bloatware, and
2) For something that’s supposed to have a ton of battery life, an HDD seems silly.

So of course I ripped the HDD out, and replaced it with a Samsung 470 series 128gb SSD. Works great.

Of course, the next step was Ubuntu. There’s a number of pages detailing what you need to do to get Ubuntu running on the x120e, and I’ve already posted about one of the pitfalls I encountered, so ’nuff said for the mo.

Eventually, I decided I wanted to dual-boot Windows 7 though, since Ubuntu is great, but it’s not as well supported as it could be, software-wise (GIMP is just bad) and WINE isn’t perfect. Here’s where I ran into problems.

I’d reserved some space, knowing I was going to install Windows 7 eventually, but when the time came to do it, Windows refused to install, saying that it couldn’t be installed to a GPT type disk or something. Googling it didn’t help much, so I decided to backup the Ubuntu installation using dd, nuke everything, and try again. I repartitioned the disk using the Windows 7 installer, and installed.

Windows installed fine at that point, but then the Ubuntu installer couldn’t see the Windows install, and tole me the disk was blank. Googling around led me to some people saying that if you use GParted to create an NTFS partition, everything works, so I did that, and it did. I then re-installed Windows, and when it came time to install Ubuntu, it saw the Windows install, and everything was hunky-dory.

Until I rebooted, and I never got the GRUB menu. Well huh. I tried installing EasyBCD, but then when I tried going to Ubuntu, all I got was a GRUB prompt, and nothing else.

The solution to that eventually wound up being to take the hard drive out, put it in a USB enclosure, hook it up to another Ubuntu machine, and use sudo grub-install to reinstall GRUB.

The full process:
1) Hook the drive up to Ubuntu machine #2
2) Use GParted to figure out which device the drive was. (In this case, /dev/sdc. The Ubuntu partition was /dev/sdc5)
3) sudo mount /dev/sdc5 /mnt
4) sudo grub-install –root-directory=/mnt /dev/sdc

On reboot, I got a bunch of scary “Error, file not found:” messages that went away after awhile. Eventually, I got to an actual command prompt, typed sudo grub-update, and after that, everything was cool.

Side note:

Because I was restoring from a disk image, and because the drive configuration had changed in the meantime, I had to go into /etc/fstab, and change the UUIDs there to the appropriate ones for the new configuration. You can find the UUIDs for your partitions using GParted.

There were a ton more dead ends and missteps that I’ve left out, but those were the major pain points. At the moment,the only problem is that if you go from Windows 7 to Ubuntu with a warm boot, Ubuntu freezes, but cold booting works fine.

Comments off

Ubuntu on the Thinkpad x120e

To paraphrase JFK, we do not choose to install Ubuntu, or any other form of Linux because it is easy, we install it because it is hard.

That said, it’s not as hard as it could be, unless you install the wrong version. First, I installed the 32-bit version, which was what was recommended on the Ubuntu site. Everything went pretty well until I tried running Minecraft. I got as far as the create a new world screen, then it crashed. The solution: Install the 64-bit version. (The issue in this case is that fglrx, the proprietary video drivers for my video card, don’t play well with Java when you use 32 bit Ubuntu. 64 bit works.)

Of course, this lead down a Google rabbit-hole. I messed up the re-install because I didn’t specify an EFI bootloader partition, and the Ubuntu installer didn’t warn me that it wouldn’t work. (You get the No operating system found message.) Then some sort of graphics misconfiguration meant that when it tried to boot into Unity, (which I already hate) all I got was a blank screen. Three or four reboots later, this problem somehow sorted itself out, whereupon I disabled Unity, then apt-got fglrx, and after that, everything seemed to work fine. That still left replacing OpenJDK with Sun’s JRE. (apt-get remove openjdk-6-jre openjdk-6-jre-headless. That seemed to remove everything that needed to be removed.) Minecraft now runs, (I think. I did get a crash which corrupted my save file, but that was after messing with graphics options pretty intensely for five minutes or so.) It’s not perfect. Being Java, it seems like GCs cause stuttering, but being able to play it at all on what’s basically a slightly beefier netbook it kinda cool.

Now, I just need to install Eclipse and the Android SDK, and I can strop using my lapburney Macbook!

Here’s some useful links if you want to try this:
The Ubuntu community page for the x120e
The ArchLinux wiki page
A good blog post about this

Comments off

Android and https

I recently had to deal with using https with Apache’s http libraries. Not a simple task. If you just create a Uri with https in front of it, and your SSL certificate isn’t from a trusted authority, or if you’re using a self-signed certificate, you’re in for a world of hurt.

There’s a lot of solutions out there, and most of them involve trusting everyone, which isn’t so secure. The best solution I found is here:

Crazy Bob: Trusting SSL Certificates

It’s reasonably secure, but in order to use it, you’ll need the 1.6 JDK. You don’t need the Android SDK to create the needed keystore.

[UPDATE]

That method works if you’re only going to one domain. All other domains stop working with that method. A better method can be found at this Stack Overflow question:

http://stackoverflow.com/questions/2642777/trusting-all-certificates-using-httpclient-over-https/6378872#6378872

The code here appends your KeyStores to Android’s list, which is a much better solution. You’ll still need the method for generating a keystore in the first link.

Comments off

Slow Android autocomplete in Eclipse Helios

Eclipse Helios has been slow for me for awhile, and it finally annoyed me enough to try to google a solution.

This guy found a good, relatively easy fix.

Basically, you’re just downloading the Android source, and adding it to your Android SDK directory. Hit the link for full details.

Comments off

Referencing drawables in HTML in Android’s WebView

Here’s another interesting Android quirk:

So let’s say you have a webview that you want to populate with HTML from an arbitrary source, and you want to use an image in the res/drawable directory. You could try webview.loadData(html, “text/html”, “UTF-8″), and within the HTML, use

<img src="file:///android_res/drawable/icon.png" />

or something, but that won’t work. Instead, this is what I had to do:

WebView webview = (WebView)this.findViewById(R.id.webview);
String html = "<html><head><title>TITLE!!!</title></head>";
html += "<body><h1>Image?</h1><img src="icon.png" /></body></html>";
webview.loadDataWithBaseURL("file:///android_res/drawable/", html, "text/html", "UTF-8", null);

So basically, for some reason, you absolutely have to use loadDataWithBaseURL.

UPDATE

This only seems to work with 2.2 (API level 8) and up.

Comments off

Basic authentication with HttpClient on Android using https and PUT

‘ve been beating my head against a wall for hours with this one. The examples I’d been using all returned HTTP 400 Bad Request, and Apache’s HttpClient is cryptic enough so that the reason for this wasn’t obvious. The reason for this response still isn’t obvious, but thanks to Kyle Lampe, I now have some code that actually works:

try {
    String data = "YOUR REQUEST BODY HERE";
    //
    CredentialsProvider credProvider = new BasicCredentialsProvider();
    credProvider.setCredentials(new AuthScope(AuthScope.ANY_HOST, AuthScope.ANY_PORT),
        new UsernamePasswordCredentials("YOUR USER NAME HERE", "YOUR PASSWORD HERE"));
    //
    DefaultHttpClient http = new DefaultHttpClient();
    http.setCredentialsProvider(credProvider);
    //
    HttpPut put = new HttpPut("YOUR HTTPS URL HERE");
    try {
        put.setEntity(new StringEntity(data, "UTF8"));
    } catch (UnsupportedEncodingException e) {
        Log.e(TAG, "UnsupportedEncoding: ", e);
    }
    put.addHeader("Content-type","SET CONTENT TYPE HERE IF YOU NEED TO");
    HttpResponse response = http.execute(put);
    Log.d(TAG, "This is what we get back:"+response.getStatusLine().toString()+", "+response.getEntity().toString());
} catch (ClientProtocolException e) {
    //
    Log.d(TAG, "Client protocol exception", e);
} catch (IOException e) {
    //
    Log.d(TAG, "IOException", e);
}

Comments off