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

Google Chrome slow on Linux?

I’m running Google Chrome on Debian Wheezy (testing) 64 bit.

For the last couple of months it often had issues rendering the home page after the initial launch, getting stuck for a few seconds, then snapping back.

The last few days, it also started running slow as molasses.

Solution? Simple:

Went into chrome://plugins/

Disabled “Remoting Viewer”

( don’t need this anyway, and didn’t enjoy finding out it was enabled by default )

Was I hacked? My Linux system is behind a home router with a firewall, so it seems unlikely. Probably just a Chrome plugin bug.

Categories: linux

SQLite, IFNULL, weird…

I have some SQLite queries in my project where I use things like:

... "... IFNULL(table1.col1, table1.col2) = table2.col3 ... "

Did this in some new code:

db.update(TABLE_NAME, contentValues, "... IFNULL(table1.col1, table1.col2) = ?...", new String[] { val1, val2, ...} );

… and the update never actually updated any messages.

Expanding IFNULL “by hand” started producing expected results:

db.update(TABLE_NAME, contentValues, "... table1.col1 IS NULL AND table1.col2 = ? OR table1.col1 = ? ...", new String[] { val1, val1, val2, ...} );

Probably has something to do with how Android’s SQLiteDatabase methods always bind query arguments as strings.

( an hour or so lost… sigh )

Categories: android

WiFi Manager 2.5.1, Bluetooth Widget 1.8.1

I know it’s taken me a long time, but the new version is finally here:

Full changelog:

  • Two new widget themes, styled after Android 4.0 (part of premium package).
  • Support for IP address and proxy server configuration for Android 3.0 and 4.0 (free functions).
  • Added widget to toggle WiFi Tethering
  • Adjusted widget sizes for a wider range of screens.
  • Support for EAP (802.11x) networks, Android 2.2 and higher.
  • A new way of connecting to networks, see app settings. Keeps all networks active, if you move out/in range (home/work etc.) your device should connect.
  • Easier IP address configuration for Andorid 2.* (when connecting for the first time).
  • Connection speed info in the main window (tap on the currently connected network; actual value is reported by the firmware).
  • Fixed Android 1.6 compatibility broken in 2.1.8 (sorry!)

Note: IP address and proxy configuration for Android 3.*/4.*, as well as EAP network support, use undocumented functions. May not work on some devices, depending on how extensive the manufacturer’s firmware changes are.

Version 2.5.0 had wrong widget widths on Android 1.6-2.1. Fixed in 2.5.1.

And now the same thing again, but this time in Russian:

  • Две новые визуальные темы для виджетов в стиле Андроида 4.0 (входят в платный пакет).
  • Поддержка конфигурации IP адреса и прокси сервера для Андроида 3.0 и 4.0 (бесплатные функции).
  • Добавил виджет для управления точкой доступа WiFi.
  • Коррекция размеров виджетов для более широкого набора экранов.
  • Поддержка сетей EAP (802.11x), на Андроиде 2.2 и выше.
  • Новый алгоритм подключения к сетям, включается в настройках. Все сети остаются активными, при выходе/входе в зону действия (дом/работа, etc.) должно быть подключение.
  • Более простая конфигурация IP адреса в Андроиде 2.* (сразу при подключении).
  • Отображение скорости соединения в основной программе (нажмите на сеть; зависит от прошивки).
  • Исправил совместимость с Андроидом 1.6, сломанную в 2.1.8 (извините!)

Учтите: для настроек IP адреса и прокси сервера на Андроиде 3.*/4.*, равно как и для работы с сетями EAP, используются недокументированные функции. Может не работать на некоторых устройствах, в зависимости от степени изменений прошивки, внесенных производителем.

Версия 2.5.0 неверно отображала виджеты, по ширине. Исправлено в 2.5.1.

Categories: releases, wifi

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/2512076

Categories: android, tools

The sorry state of SQLite full text search on Android

Just spent a few hours prototyping full text search using SQLite’s FTS functionality.

As far as I’m concerned, it’s a dead end for my app, for three reasons:

1. The lack of international-character tokenizer.

The first step when building a full text search index is to break down the textual content into words, aka tokens. Those tokens are then entered into a special index which lets SQLite perform very fast searches based on a token (or a set of tokens).

SQLite has two built-in tokenizers, and they both only consider tokens consisting of US ASCII characters. All other, non-US ASCII characters are considered whitespace.

There is an “icu” (Unicode) tokenizer, but it has to be enabled at compile time. A standard Android build does not have the “icu” tokenizer enabled.

I actually ran some tests, just to make sure, and the results are:

- Samsung Galaxy Ace, S5830, Android 2.3.6
- Sony Ericsson Arc, Android 2.3.4
- Samsung Galaxy Nexus, Android 4.0.2

The above devices do not have the “icu” tokenizer.

- HTC Incredible S, Android 2.3.5

The Incredible S has the “icu” tokenizer.

I hardly think HTC wanted to do a favor to third-party app developers – the “icu” tokenizer is probably used by their Sense UI system.

2. Crashes in the “icu” tokenizer.

This is moot, but I’ve stumbled upon this post on stack overflow. A crash in native code when using the “icu” tokenizer is not something I’m willing to risk.

3. The large size of FTS indexes.

In my tests, ab FTS index table takes about as much space as the original, structured, non-FTS table it was built for.

This is probably to be expected, because it’s possible to query an FTS table for the original text that was used to build the index.

This may be a useful feature (although one could always do a join between FTS and structured data tables), but I’d rather do without it.

Android users are very sensitive to the amount of internal storage used by applications, and putting a SQLite database in external storage on a memory card is something I’m very hesitant to do.

Bottom line – it’s going to be the good old “LIKE ‘%blah%’” queries for me, which have more or less acceptable performance even considering the full table scan they perform, and do not use any extra storage space.

Categories: android

Setting up WiFi EAP authorization with Freeradius

March 6, 2012 4 comments

I’m working on adding support for EAP networks to WiFi Manager.

My test environment uses dd-wrt running on an old Linksys WRT54GL and freeradius running on my main development system. It actually turned out to be fairly easy to configure.

Some useful links:

http://www.smallnetbuilder.com/wireless/wireless-howto/30213-how-to-setting-up-freeradius-for-wpa-a-wpa2-enterprise-part-2

http://www.dslreports.com/forum/remark,9286052~mode=flat

http://habrahabr.ru/blogs/wireless/128405/

http://www.ixbt.com/comm/prac-wpa-eap_3.shtml

Categories: wifi
Follow

Get every new post delivered to your Inbox.