WiFi Manager 2.1.7

January 23, 2012 Leave a comment
  • Added Slovak translation.
  • Added a workaround for an Android Market / Checkout issue.

More on the Market / Checkout issue:

Starting with about three weeks ago, I’m seeing those dreaded “Order canceled / took too long to deliver” errors again. Maybe it’s the latest Market app version, maybe it’s the Wallet / Checkout merge, there is no way for me to know.

These errors are not new, but what is new is that now when this happens, there is no “order canceled” notification from Google’s servers to the application.

Google Groups discussion

Bug tracker discussion

As a result, the app would get stuck waiting for the order to complete or fail, and the user could not retry his purchase.

Version 2.1.7 adds code to automatically reset from “order in progress” state after four hours.

Now if one of these Market errors happens again, there is a way to retry the purchase.

Categories: android, releases, wifi

WiFi Manager 2.1.6

December 5, 2011 1 comment

Subtitled: why I never buy any Andorid devices made by Samsung.

This update has a workaround for a firmware bug on the Samsung Galaxy Tab 10.1.

About a month or so ago, someone left a Market comment saying that the app crashes on his Galaxy Tab 10.1. With no way to contact the user via Market (thank you, Google, one way “communication” is so effective!), I had no way to verify and resolve the issue. In fact, I have two Honeycomb based tablets, and the app works just fine on both of them.

Now, two days ago, a very nice user contacted me via email, reporting that WiFi Manager crashed when trying to disable the device’s WiFi. He provided screenshots, one of them had an error message displayed by the firmware: “the application does not have the android.permission.CHANGE_NETWORK_STATE permission“.

I added the permission, emailed the apk to the user, the issue went away.

And here is why I “looove” Samsung.

Working with WiFi does not require android.permission.CHANGE_NETWORK_STATE. It requires android.permission.CHANGE_WIFI_STATE, which is a different permission.

The firmware on the Galaxy Tab 10.1 thinks that CHANGE_NETWORK_STATE is required for disabling WiFi – probably because the device also has a 3G modem, and disabling WiFi kind of, sort of, like, maybe implies enabling 3G (which might be done a bit later by the firmware and not by the application that disabled WiFi).

This is wrong and is clearly a bug in the firmware.

All my users will now need to update the app manually due to the added permission, which is an inconvenience.

I wonder how this one slipped past Google’s certification testing. Perhaps this is not tested by the CCD, or perhaps firmware updates are not required to be submitted for testing, only the initial releases are.

The latter seems likely – seeing how the 3.2.1 firmware for the Motorola Xoom also has a serious issue with WiFi APIs (a thread deadlock, it seems).

Categories: releases, wifi

WiFi Manager 2.1.5

November 27, 2011 Leave a comment

A user recently reported an issue with IP switching on his office network: the automatic switching wouldn’t work.

To fix this, I added a “compatibility” setting to “Switch early”. If the application doesn’t notice a WiFi network connection change and doesn’t switch to its IP, try enabling this setting and see if it makes a difference.

More info:

WiFi Manager watches WiFi related events which are broadcast by the networking code inside Andorid. There is a number of events during a single connection, so there is a choice as to which one is used to check and update the device’s IP settings.

The new setting instructs the program to make the check / switch on an earlier event than before.

This is disabled by default, to make sure the application keeps working as before on those devices that don’t need this change.

Categories: android, releases, wifi

Another fast scroller helper for ListView

November 22, 2011 1 comment

Android’s ListView has a built-in way to implement fast (indexed) scrolling.

As useful as it is, it has two limitations that sometimes can be critical:

- A section name is assumed to be a single letter.
- If the list content changes over time, it’s difficult to update the section list on the go.

The fast scroller helper class in the framework is closely integrated with AbsListView, and so it does not seem possible to just replace it with another implementation, or change the way it behaves.

I needed one of these for my current project, and found a fast scroller that was posted on Google Code by Android’s Dianne Hackborn.

This code is from 2008, before there was a fast scroller implementation in the framework, and so its way of interacting with the list is different. This class is derived from FrameLayout and should be used in the layout XML file as the list view’s parent.

I combined this code with the fast scroller from the Ice Cream Sandwich sources. The result looks like this:

This class is used the same way as the FastScrollView linked to above – it should be inserted into the layout XML as the list view’s parent.

It has a method for updating the section index, which can also optionally reset the current drag tracking state (or not, specified as a parameter).

The section overlay’s size and its font size are specified as dimension resources. Long (over 1 character) section names are displayed correctly.

Finally, I also fixed some rendering issues on Android 3.0 when running with hardware acceleration enabled.

The code is too large to post here, so I uploaded it to Google Code. A sample / test project is included.

You can get it here: a wiki page is here and the code is here.

Categories: android, ui

Getting a Sony Tablet S to work with Android tools under Ubuntu

November 18, 2011 Leave a comment

I’ve had a Sony Tablet S for a while now. Getting it to work with Android development tools under Windows required some special sauce, as there is no official development driver from Sony (or, to be more exact, there was not one back when I bought the device).

Instructions for Windows are still available here, by way.

Under Ubuntu, I did the usual thing with editing /etc/udev/rules.d/51-android, which worked for all my other Android devices, and still, “adb devices” did not list the Tablet S. I entered the line in the udev rules file like this:

SUBSYSTEM=="usb", ATTR{idVendor}=="054c", MODE="0666", GROUP="plugdev"

… and here is my output from lsusb:

Bus 002 Device 005: ID 054c:05b4 Sony Corp.

After Googling for a bit, I got it to work. The missing step was to add 0x054C (Sony’s UPnP identifier) to my ~/.android/adb_usb.ini. I repeat, this was not necessary for any other of my Android devices, so the Sony must be special in some way.

kman@kman-P55-UD3R:~$ echo 0x054c > ~/.android/adb_usb.ini
kman@kman-P55-UD3R:~$ cat ~/.android/adb_usb.ini
0x054c
kman@kman-P55-UD3R:~$ adb kill-server
kman@kman-P55-UD3R:~$ adb devices
* daemon not running. starting it now on port 5037 *
* daemon started successfully *
List of devices attached
42801024420f617 device

kman@kman-P55-UD3R:~$

Categories: android, hardware

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

AlertDialog, custom ListView items, and Honeycomb

October 15, 2011 Leave a comment

Here is another compatibility tip for Honeycomb and previous versions. This one has to with custom ListView item layouts inside alert dialogs.

Ok, so I have a few places in my app that display an AlertDialog with a ListView inside, backed up by a adapter that provides custom item layouts. Getting the text color inside those layouts is a little tricky.

Prior to Honeycomb, dialogs always use a dark background and light text, regardless of which theme (light or dark) is used by their parent activity. This is true for AlertDialogs and plain Dialogs. However, lists inside AlertDialogs use an inverted (light) background. This is usually enabled automatically, or you can enable it yourself by calling AlertDialog.setInverseBackgroundForced. Now TextViews inside item views returned by your adapter can use black text, or, preferably, just in case the color is customized by the device manufacturer, a theme attribute reference (one of textAppearanceMediumInverse, or textColorPrimaryInverse, etc.).

Here is an alert dialog with a list view, running on the Sony Ericsson Xperia Arc. The background is not quite white, it’s a bit greyish (purplish?), and the text is pure black.

The item layout looks like this (only text views are shown):

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/pick_attachment_root"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">

	<TextView
		android:textAppearance="?android:attr/textAppearanceMediumInverse"
		android:id="@+id/pick_attachment_main_title"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/pick_attachment_icon"
		android:layout_toLeftOf="@id/pick_attachment_toggle"
		android:singleLine="true"
		android:ellipsize="middle"
		android:textStyle="bold" />

	<TextView
		android:textAppearance="?android:attr/textAppearanceInverse"
		android:id="@+id/pick_attachment_sub_title"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/pick_attachment_icon"
		android:layout_toLeftOf="@id/pick_attachment_toggle"
		android:layout_below="@id/pick_attachment_main_title" />

</RelativeLayout>

On Honeycomb and later, if you use the native, Holographic, themes, dialogs can be light or dark, matching the parent activity’s theme. AlertDialogs with lists look the same as regular dialogs with text, so this is what the above layout looks like on an Sony Tablet S running Android 3.2:

The text views turned invisible, white on white. How did this happen? The dialog’s background is no longer inverted, as the dialog’s theme matches the parent activity’s, but our text appearance references still assume inverted background: for a light parent theme, it’s “whatever text color is appropriate over the inverse of a light background”, in other words, “whatever is appropriate for a black background”, which is white. Switching the parent activity to a dark theme produces black text on black background by the same logic.

Ok, so for Honecomb, we’re supposed to use non-inverted theme attribute references. How to do this without duplicating our layouts inside res/layout-v11? My solution is this:

First, define these styles inside res/values-v4/list_styles.xml:

<?xml version="1.0" encoding="utf-8"?>
<resources>

	<!-- Text for listboxes, inverted for Andorid prior to 3.0 -->

	<style name="MyListTextAppearanceSmall">
		<item name="android:textAppearance">?android:attr/textAppearanceSmallInverse</item>
	</style>

	<style name="MyListTextAppearanceDefault">
		<item name="android:textAppearance">?android:attr/textAppearanceInverse</item>
	</style>

	<style name="MyListTextAppearanceMedium">
		<item name="android:textAppearance">?android:attr/textAppearanceMediumInverse</item>
	</style>

</resources>

Then use these styles inside the layouts returned by the adapter backing up the listview inside the AlertDialog (… that Jack built…). The layouts themselves don’t need to be duplicated, mine are in the “basic” res/layout:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:id="@+id/pick_attachment_root"
	android:layout_width="fill_parent"
	android:layout_height="wrap_content">

	<TextView
		style="@style/MyListTextAppearanceMedium"
		android:id="@+id/pick_attachment_main_title"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/pick_attachment_icon"
		android:layout_toLeftOf="@id/pick_attachment_toggle"
		android:singleLine="true"
		android:ellipsize="middle"
		android:textStyle="bold" />

	<TextView
		style="@style/MyListTextAppearanceDefault"
		android:id="@+id/pick_attachment_sub_title"
		android:layout_width="fill_parent"
		android:layout_height="wrap_content"
		android:layout_toRightOf="@id/pick_attachment_icon"
		android:layout_toLeftOf="@id/pick_attachment_toggle"
		android:layout_below="@id/pick_attachment_main_title" />

</RelativeLayout>

Now all that’s left to do is to redefine these three styles inside res/values-v11/list_styles.xml and to use regular, not inverted, text appearance references:

<?xml version="1.0" encoding="utf-8"?>
<resources>

	<!-- Text for listboxes, non-inverted starting with Android 3.0 -->
	
	<style name="MyListTextAppearanceSmall">
		<item name="android:textAppearance">?android:attr/textAppearanceSmall</item>
	</style>
	
	<style name="MyListTextAppearanceDefault">
		<item name="android:textAppearance">?android:attr/textAppearance</item>
	</style>

	<style name="MyListTextAppearanceMedium">
		<item name="android:textAppearance">?android:attr/textAppearanceMedium</item>
	</style>

</resources>

The same dialog now looks like this:

And when the parent activity uses a theme dervied from @android:style/Theme.Holo, the dialog items will turn black, with light text.

Categories: android, ui

WiFi Manager 2.1.3

October 7, 2011 3 comments

A new release: WiFi Manager 2.1.3.

This is a small update, first of all, it now has an option to display network signal strength as dBm in the radar mode:

I also fixed a couple of crashes, one of which merits a small story.

There is a setting in the application to play a sound when it discovers a new open network. To let the user pick the sound, I used RingtonePreference, which is a class built into Android for picking a sound (does just what it says on the box… nice).

Some manufacturers make changes to Android’s UI components, the ringtone picker included, and as it turns out, one of them, Samsung, didn’t properly test their modificaitons for the Galaxy S.

The ringtone picker on the Galaxy S crashes if the applciation reqests that the “None” option not be included in the available sounds list. My application did exactly that, because it has a separate checkbox to enable or disable sound notifications. Now, this option is a standard part of Android. It’s documented, it’s supported on all Andorid versions, but Samsung didn’t properly test their modifications to this class.

Nice. But it doesn’t end here – I’ve been seeing crash reports in this code “from the field” in my Market Developer Console for a few months now, but the device was listed as “Other”. Does it make sense that one of the most commercially successfull Android devices is listed the same as a non-name device from an unknown manufacturer? Wait, it gets better – apparently, Google’s own Nexus S, which is also affected by this bug, is also listed as “Other”. So all this time I just assumed that the app crashed on some weird device with broken firmware and ignored it.

The end of this story is that the bug is a really trivial one, and it’s fixed in this release, but it could have been fixed a long time ago (or not be there at all) if only Samsung and Google had set their quality bar just a little bit higher.

Categories: android, releases, wifi

Custom themes for Honeycomb and backwards compatibility

October 7, 2011 4 comments

Here is a couple of things I learned while recenly updating my apps to have the native look on tablets running Android Honeycomb (3.*).

My app lets the user select a UI theme (there are two: light and dark), so I had something like this in my res/values/styles.xml:

<declare-styleable name="WifiTheme">
	<attr name="radar_text" format="color" />
	<attr name="radar_alpha" format="color" />
</declare-styleable>

<style name="WifiTheme.Light" parent="@android:style/Theme.Light">
	<item name="radar_text">#FF202020</item>
	<item name="radar_alpha">#80000000</item>
</style>

<style name="WifiTheme.Dark" parent="@android:style/Theme">
	<item name="radar_text">#FFFFFFFF</item>
	<item name="radar_alpha">#A0000000</item>
</style>

I would then apply one of these themes, from inside onCreate, to my activities.

Now, Honeycomb has new “Holographic” UI themes that look different from 2.* themes, and users expect an application running on a tablet to use those. The two new themes are @android:style/Theme.Holo.Light and @android:style/Theme.Holo.

It’s possible to duplicate the XML snippet above in res/values-11/styles.xml, replacing the parent themes, but that would mean duplicating all the values for those themes. The snippet above has just two extra attributes, but there could be many more of them.

Ok, so here is a trick I came up with. Just like with program code, what we need to get out of a tight spot is an extra level of abstraction.

First, I defined the following themes in res/values/theme_compat.xml:

<style name="ThemeCompat">
</style>

<style
	name="ThemeCompat.Dark"
	parent="@android:style/Theme">
</style>

<style
	name="ThemeCompat.Light"
	parent="@android:style/Theme.Light">
</style>

The first one is just to keep the Android style hierarchy system happy, the other two are where the real work is. You can think of them as defining a base class (in programming terms) for my custom themes. My custom theme declarations are now derived from the themes shown above, and look like this:

<style name="WifiTheme.Light" parent="@style/ThemeCompat.Light">
	<item name="radar_text">#FF202020</item>
	<item name="radar_alpha">#80000000</item>
</style>

<style name="WifiTheme.Dark" parent="@style/ThemeCompat.Dark">
	<item name="radar_text">#FFFFFFFF</item>
	<item name="radar_alpha">#A0000000</item>
</style>

And for when the application runs on Android 3.*, I have the following declarations in res/values-11/theme_compat.xml:

<style
	name="ThemeCompat.Dark"
	parent="@android:style/Theme.Holo">
</style>

<style
	name="ThemeCompat.Light"
	parent="@android:style/Theme.Holo.Light">
</style>

What this does is replaces the “base class” of my custom themes with those native to Honeycomb. Now my custom theme declarations don’t need to be duplicated, and are automatically derived at runtime from the most appropriate system themes.

Here is another thing. AlertDialogs with custom content views.

AlertDialogs can be sometimes tricky, because they have their own styling and can even impose it on their content. But I feel that using them in place of regular dialogs makes an application’s UI better. The light panel behind the buttons, the title bar with the icon, the separator line below that – those may seem insignificant little things, but I feel they really make an app look better. Some manufacturers (Samsung, Sony Ericsson, perhaps others) make changes to stock Andorid UI to add their own color and graphics accents, and so it becomes even more important to use AlertDialog to better blend in with the device’s UI.

And this is another thing where Honeycomb is different from previous Android versions. Prior to 3.0, AlertDialogs always use a dark background (unless overriden for lists), even if the parent activity’s theme is light. Starting with 3.0, alert dialogs have the same overall light/dark color scheme as the base activity.

If your alerts use custom content views, it becomes tricky, because those views need to be inflated using an appropriate Context, so they match the dialog’s color scheme.

It’s really easy to end up with white text on white background, unless you use the following method, new with API level 11: AlertDialogBuilder.getContext().

Since this method doesn’t exist prior to API level 11, it’s possible to use Java reflection to stay compatible with older Android versions. Turns out there is another way: by subclassing AlertDialog, and overriding onCreate(), it’s possible to call getContext() for the AlertDialog itself. That method exists since API level 1, and returns a correctly themed Context for both 3.* and prior versions of Android. A further shortcut is to call getLayoutInflater(), which also exists since API level 1.

With this in mind, here is a simple alert dialog:

public class DlgAbout extends AlertDialog {

	public DlgAbout(Context context) {
		super(context);
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {

		setTitle(R.string.about_title);
		setCancelable(true);

		LayoutInflater inflater = getLayoutInflater();

		View contentGroup = inflater.inflate(R.layout.about_content, null);
		setView(contentGroup);

		super.onCreate(savedInstanceState);
	}
}

The dialog’s layout can use views without any specific color customizations:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
	xmlns:android="http://schemas.android.com/apk/res/android"
	android:orientation="vertical"
	android:layout_width="wrap_content"
	android:layout_height="wrap_content"

.....

<!-- Note the absence of android:textColor, etc -->
		<TextView
			android:layout_width="wrap_content"
			android:layout_height="wrap_content"
			android:text="@string/about_1"
			android:gravity="center_horizontal" />
......

The code to use this dialog is below. Not really that much different from using AlertDialog.Builder, and is actually somewhat better because the code for the dialog is placed in its own class (above).

@Override
protected Dialog onCreateDialog(int id) {
	if (id == DIALOG_ID_ABOUT) {
		/*
		 * About the app
		 */
		return new DlgAbout(this);
	}
.........
}

Categories: android, ui

A minor .2 update for 10″ tablet users

Based on user feedback, here is a small update with adjusted widget sizes for 10″ tablets.

WiFi Manager 2.1.2, Bluetooth Widget 1.7.2.

The widgets now perfectly line up on the sides, in both land and port modes, and have the expected size based on how many cells they occupy.

Categories: Uncategorized
Follow

Get every new post delivered to your Inbox.