Archive

Archive for the ‘tools’ Category

Eclipse lockups, adb, Linux, ModemManager

September 24, 2014 Leave a comment

I’ve been seeing Eclipse freeze spontaneously lately, both in Fedora 20 (my daily environment) and Ubuntu 14.04 / 14.10 (separate boot for playing with Android L).

https://code.google.com/p/android/issues/detail?id=75562

I tracked down the issue (using jstack) to an adb related thread inside Eclipse Android Tools. Doing adb kill-server would end the freeze, until the next time.

Then I had an idea to check the system log the next time it would happen. Interesting. Turns out, ModemManager, a part of NetworkManager (used by both Ubuntu and Fedora for automated network configuration) was:

– recognizing my Android phones as modems
– trying to determine their capabilities
– timing out when doing that (but taking a few seconds to do so)
– and this was causing the adb thread inside Eclipse to wait, freezing the Eclipse UI

Two possible workarounds, I’m using the second one:

– switching USB connect mode in each phone’s settings from MTP (default) to Camera
– adding stuff to udev configuration to blacklist the Android phones from ModemManager‘s automatic detection


/etc/udev/rules.d/51-android.rules

# Samsung
SUBSYSTEM=="usb", ATTR{idVendor}=="04e8", MODE="0666", GROUP="wheel", ENV{ID_MM_DEVICE_IGNORE}="1"
# ASUS
SUBSYSTEM=="usb", ATTR{idVendor}=="0b05", MODE="0666", GROUP="wheel", ENV{ID_MM_DEVICE_IGNORE}="1"
#LG
SUBSYSTEM=="usb", ATTR{idVendor}=="1004", MODE="0666", GROUP="wheel", ENV{ID_MM_DEVICE_IGNORE}="1"

The ENV{ID_MM_DEVICE_IGNORE}="1" stuff at the end tells ModemManager that the device is not a modem.

PS – to be fair, Android phones can act like modems, when enabled in the phone’s system settings. Why they also look like modems, but don’t respond to commands, even when this setting is off.. Who knows?

PPS – there appears to be no way to uninstall ModemManager from Fedora and keep NetworkManager, too bad.

Categories: android, linux, tools

A user.css for the redesigned Android Developers site

June 22, 2012 1 comment

Makes the API reference and articles readable… again.

I’m using Google Chrome on Linux with the Stylebot Extension.

body {
    font: 12px/16px Verdana;
    background: white;
}

html {
    background: white;
}

h1, h2 {
    line-height: 1;
}

#jd-header h1 {
    font-size: 14px;
}

#jd-content h2 {
    font-size: 12px;
}

#jd-content h3 {
    font-size: 12px;
}

#jd-content .prettyprint {
    margin: 0.5em 0;
    padding: 0.5em;
    font-family: 'Droid Mono', 'Courier New', Courier;
    font-size: 12px;
    line-height: 1.25;
}

.jd-details-title {
    font-size: 12px;
}

#packages-nav h2, #classes-nav h2 {
    font-size: 12px;
}
Categories: tools

Scale Android drawables with a script

Here is a simple script to create lower-resolution Android drawables from higher-resolution ones.

For example, given a batch of -xhdpi images, it can generate -hdpi and -mdpi images.

With this script, it’s possible to export only highest-resolution artwork from authoring tools and then create the lower-resolution versions with a few batch commands.

Before, I would have to export all artwork versions one by one, adjusting the size, navigating to the right directory, double-checking to make sure I haven’t accidentally exported an -mdpi sized image into -hdpi, etc.

Script usage:

drawable_convert.py -d res/drawable-mdpi -d res/drawable-hdpi res/drawable-xhdpi-v14/select*.png

This will take select*.png from xhdpi and place lower-resolution versions into mdpi and hdpi folders.

Resize ratios are computed based on resource directory names.

The actual scaling is done by ImageMagick’s convert command.

https://gist.github.com/2771791

Categories: android, tools

Finding missing translations in an Android application

An app that is developed primarily in one or two languages, and supports more, needs to be updated from time to time.

To do this, missing string translations need to be identified.

The Lint tool from the Android SDK can do this, but I’ve found its output format to be difficult to work with.

Lint groups missing translations by string identifier, like this:

res/values/strings_widget.xml:7: Error: "widget_loading" is not translated in cs, es, fr, it, ja, ko, nb, nl, pt-rBR, sv, vi [MissingTranslation]
    <string name="widget_loading">Loading…</string>
    ^
res/values/strings_widget.xml:8: Error: "label_account_and_folder" is not translated in cs, es, fr, it, ja, ko, nb, nl, pt-rBR, sv, vi [MissingTranslation]
    <string name="label_account_and_folder">Account and folder:</string>
    ^

I believe it’s more useful to group missing translations by language code, so that they can be collected and sent to the translator for a particular language all at once.

With this in mind, I’ve written a simple script that does this. Its output look like this:

	Checking language 2, de
	***** Found 44 missing translations for language de

	<!-- res/values/strings_account_list.xml -->

	<string name=account_list_menu_uilock_now>Lock now</string>

	<!-- res/values/strings_account_options.xml -->

	<string name=account_options_folder_sync_type_spam>Sync as spam</string>
	<string name=account_options_prefs_preload_inlines_mobile>Embedded images, mobile</string>
	<string name=account_options_prefs_preload_inlines_wifi>Embedded images, WiFi</string>
	<string name=account_options_prefs_signature_auto>Add signature automatically</string>
	... more strings here

	Checking language 1, uk

	***** Found 47 missing translations for language uk
	... all missing translations for Ukrainian are printed here

The script is written in Python, and is available here: https://gist.github.com/3038713

Categories: android, tools

Moving Android projects from Windows to Linux

November 18, 2011 4 comments

This one had me really puzzled today.

I recently installed Ubuntu, just to see what developing for Android under Linux is like. Besides, it’s been about 10 years since I last used Linux, so I also wanted to see what it looks like these days.

I keep my source code in a remote Mercurual reporsitory, so copying my workspace from Windows to Linux was a snap (even if those are just different parttions on the same computer’s disk drives).

After doing “hg clone”, I opened up Eclipse, pointed it at my new workspace… and froze in a mixture of horror and confusion.

All my projects were marked with a red exclamation point, and the error window had a multitude of messages about Android requiring Java compiler compatibility level of 1.5 or better (… please use Fix project properties, etc.).

The confusing part was, all my projects are set up to use the workspace default for Java compiler platform level, and my just-created workspace’s setting was 1.6. Weird isn’t it?

The cause turned out to be my Java file encoding settings. Eclipse on Windows by default uses a single byte encoding for newly created Java files, which is my case is windows-1251 (Russian). Eclipse on Linux expects UTF-8. As soon as I changed my Linux workspace to use to windows-1251, and without touching those compiler compliance level settings, everything turned normal and my projects started building.

There is a bug filed in the Eclipse tracker going back to 2005 about this – whether or not Eclipse should default to UTF-8 for new files on Windows (and possibly MacOS). I’d like the default on Windows to be UTF-8, at least for Java files.

So… if you moved your Android code from Windows (and I presume, from MacOS) to Linux, and are getting the compiler compliance level error, check the encoding setting. Better yet, set up any new workspaces you create on Windows and intend to move to Linux later as UTF-8 right from the start.

Categories: android, tools

Signing Andorid packages for production builds

September 28, 2011 Leave a comment

I keep thinking about switching my production build system to be Ant-based, but keep exporting from Eclipse instead. Maybe one day… Meanwhile, here is how I get an exported (unsigned, unaligned) .apk ready for Market.

In my source tree, I have a special directory, release, which is the release (duh!) staging area. The production key files are located here, which, besides being convenient, makes sure they get backed up.

Making a production build for me takes three steps:

  1. Cleaning the project in Eclipse (I won’t want my production build to get a weird crash because of an outdated R.java).
  2. Generating an obfuscated, unsigned, unaligned .apk by selecting Android Tools – Export Unsigned Application Package in Eclipse.
  3. Running a script to sign and align the .apk, which gets it ready for a Market or a web site upload, or for installation to a test device.

The filename I use for the second step always follows a special pattern: it’s some base name, with the version number and the suffix “-raw” appended. So for Bluetooth Widget version 1.8.1, I export to “kmanBluetoothWidget-1.8.1-raw.apk“, and for WiFi Manager version 2.1.1pre3 I export to “kmanWifiManager-2.1.1pre3-raw.apk“.

( a side note: the “kman” thing goes back quite a few years… my co-workers used to call me that, because “Kostya” was too complicated for some people )

Similarly, there is a pattern to my production keystores: they are named the same as the application’s base file name (without the version, obviously), and the key alias inside the store also has a certain name.

Now, the script.

I’ve been using PowerShell as my command line window for about a month now, and just today rewrote my script from being a .cmd batch file into a PowerShell script.

The script takes two arguments, the first is the abbreviated application name, and the second is the version number.

So, after exporting, let’s say, kmanWifiManager-2.1.1-raw.apk, I run the script as “.\sign_and_pack.ps1 wfm 2.1.1” – where “wfm” is the application, “WiFi Manager” and “2.1.1” is the verison number. Or I could sign Bluetooth Widget version 1.8.1 by running “.\sign_and_pack.ps1 btw 1.8.1“.

The script determines the application’s exported .apk name based on the arguments, signs it with that particular application’s key, and aligns it for faster runtime resource access as recommended by Google.

Here is the source:

if ($Args.length -lt 2) {
	Write-Output "Usage: sign_and_pack.ps1 program version"
	exit
}

$argProgram = $Args[0]
$argVersion = $Args[1]

switch ($argProgram) {
	"wfm" {
		$procName = "WiFi Manager"
		$procBaseName = "kmanWifiManager"
		$procKeyName = "WifiManagerKey"
	}
	
	"btw" {
		$procName = "Bluetooth Widget"
		$procBaseName = "kmanBluetoothWidget"
		$procKeyName = "BluetoothWidgetKey"
	}

	default {
		Write-Output "Unknown application: $argProgram"
		exit
	}
}

Write-Output "***" "***" "*** Program: $procName, version: $argVersion" "***" "***" ""

$keypass = "*** my keystore password goes here ***"
$fileKeystore = "$procBaseName.keystore"

$fileRaw = "$procBaseName-$argVersion-raw.apk"
$fileTemp = "$procBaseName-$argVersion-temp.apk"
$fileDest = "$procBaseName-$argVersion.apk"

$fileRawExists = Test-Path "$fileRaw"

if (-not $fileRawExists) {
	Write-Output "Error: $fileRaw does not exist"
	exit
}

Write-Output "Copying $fileRaw to $fileTemp"
Copy-Item $fileRaw $fileTemp

Write-Output "Signing $fileTemp with $fileKeystore"
jarsigner -storepass $keypass -keystore $fileKeystore $fileTemp $procKeyName

Write-Output "Aligning $fileTemp to $fileDest"
zipalign -f 4 $fileTemp $fileDest

Remove-Item $fileTemp

Write-Output "" "***" "***" "*** Ready: $fileDest" "***" "***"

#$key = Read-Host "Install? (Y/N)"

#if ($key -eq "Y" -or $key -eq "y") {
#	Write-Output "Installing $fileDest"
#	adb install -r $fileDest
#}

Here is example output, assuming I just exported WiFi Manager 2.1.1 as “kmanWifiManager-2.1.1-raw.apk”:

PS D:\Android\proj-indigo\release> .\sign_and_pack.ps1 wfm 2.1.1
***
***
*** Program: WiFi Manager, version: 2.1.1
***
***

Copying kmanWifiManager-2.1.1-raw.apk to kmanWifiManager-2.1.1-temp.apk
Signing kmanWifiManager-2.1.1-temp.apk with kmanWifiManager.keystore
Aligning kmanWifiManager-2.1.1-temp.apk to kmanWifiManager-2.1.1.apk

***
***
*** Ready: kmanWifiManager-2.1.1.apk
***
***
PS D:\Android\proj-indigo\release> _

The commented-out stuff at the end of the script can install the just generated release .apk to a device (I’m not sure yet which is more convenient: doing it from the script, or typing “adb install -r” myself…)

So here it is….

Categories: android, tools

Workspace never loading in Eclipse

If you’ve been doing Android development for any length of time, you’ve no doubt experienced Eclipse getting stuck loading the workspace.

The symptoms are: you launch Eclipse, it starts to load, the progress bar in the launch window gets to about one third, and then it just sits there. Killing Eclipse.exe and starting over doesn’t help, it just happens again.

Here is a simple fix, found on stack overflow:

Open your workspace’s .metadata directory, then browse to .plugins\org.eclipse.core.resources and delete the file named .snap.

After this, the next time the workspace will load.

Categories: android, tools