Friday, June 3, 2011

Hypnoblobs

Hypnoblobs has just been released on the Android Market. The app shows two luminous blobs of endlessly mixing, swirling fluids. It's mesmerising to watch!

Two apps have been released - Hypnoblobs Demo, which is a stand-alone application and Hypnoblobs Live Wallpaper. Both the demo and live wallpaper are interactive, touching the screen creates a blob. The demo is fun to play with, but the live wallpaper is much better!

This is basically a successor to Plasmeriser using JNI code, so it's much faster. The graphics have also been greatly improved. The underlying code has been optimised but it still uses an underlying buoyant gas computational model.

It is heavy on the CPU usage, so there's an option in the Live Wallpaper to run at a slower rate. However, I've found that if I look at the list of apps which use the most battery, it doesn't even show up! I've noticed no extra drain with it running at full speed as a live wallpaper on my HTC Desire. Usage will probably vary, though depending on device.

There are a bunch of different palettes, to hopefully suit everyone's taste. Please feel free to email if you have any suggestions.

Friday, February 4, 2011

Cash Counter

Stuck in a boring job? See how much they're paying you as you earn it with this widget!

It's basically just a clock which counts your cash up. With fancy spinny graphics. Install it as a widget, then click to configure your hours and wage. It'll count up during your work hours and show you how much you've made over the day.

This widget is only really for people with regular working hours. Perfect for that boring office job where you're stuck in a pointless meeting for hours. See exactly how much money you're company's spending having you sit around doing nothing!

Version 2 has just been released, bringing an updated UI to the working hours display, 4 different job types, job time multipliers and flexible reset points. Night shifts should also now be working.

How to set your hours

Here's a basic guide to set your hours. The widget divides your week into blocks of time that you're at work and not at work. These blocks need to be set by you, to tell the widget when to count, but it's not too painful.

Tap on the widget and select 'Set your working hours'. If this is the first time you've set your hours, the 'Add work times' dialog will appear automatically, otherwise select 'Add new work times'.

The 'Add work times' dialog lets you add these blocks to your week. The start and end times of the block can be changed using the buttons showing the time to the right of 'Start' and 'End'. The day is also set here. If you work nights, an end time set before the start time will give you a work block through the night.


There are 4 job types supported, and each can be set to a different wage. The type of job you're working for the hours you're setting can be changed in the drop-down list below the times.

If you work regular hours, you can copy the hours you've just entered over a number of days using the drop-down list below the job type. For example, if you've entered 9:00 Monday to 17:00 Monday and choose 'Repeat for 3 days', this will set your 9:00 to 17:00 work times for the next 3 days: Monday, Tuesday and Wednesday.

The last option is whether to reset the counter at the start of the work block. You can use this to choose whether you show the total for the week on the counter, or just for the day.

Click 'Save' to set the block(s). New blocks will appear as coloured bars in the week display. Each block can be clicked on to set, edit or delete the block. The block will have a white border when selected and new buttons will appear.


Breaks can be added within the block by clicking on a block and selected 'Add a break in work block'. Set the break times, and click 'Save'. A gap will then appear in the block.

'Edit or delete selected work block' allows you to change the block times, or delete the block entirely. The options here are the same as adding a new block, with the exception of the shift multiplier. This allows you to set a multiplier to the current rate for overtime blocks. Blocks with a shift multiplier are shown with a lighter colour shade on the week list.


To delete a block, click on 'Delete work block'. All work blocks in a day can also be also deleted by clicking on the name of the day and selecting 'Delete all entries in day'.

Please feel free to send me any comments/bugs/flames on the widget or UI!

Sunday, November 7, 2010

Tokaplot +

The enhanced version of Tokaplot, Tokaplot +, has (finally) been released! This adds three extra widget sizes to Tokaplot, 2x2, 4x1 and 4x2 for your viewing pleasure. It also allows a range of background shading styles and line rendering to better customise the widget to your device's theme. I'm charging an Aussie $ for this. While I don't expect to leave my day job, it would be nice to get some extra beer $.

1.1: Added free memory %

1.2: Important update: Explicitly set to long-running service. This should fix any freezing problems.

1.21: Reduced the thread priority by 1, as the new long-running service sets the priority to the same as foreground threads. This seemed to cause competition for resources with other long-running services, such as music players. This can be turned off in the settings. Slightly tweaked the graphics to make the line render better.

1.22: Eye candy update. Plot and grid line style customisation (shadow/shine/glow styles, width and dash effects) have been added, as well as background translucency control and the ability to change the background text colour. Also fixed a minor bug where the data plots would occasionally show large negative values.

1.30: Added battery current. Note: This will not work on most devices as they don't have this information! Tested on the HTC desire.

1.32: (Yes, I accidentally skipped a version no) Added ability to lock widget. Also fixed a minor bug with free memory % calculation.

1.4: Significant internal optimisations aimed at making the widget faster and use less memory for those who like to run the widget with low refresh rates. Also put back CPU load, added a pause button and made the lock sticky across device restarts.

1.6 Added support for more types of data file.

1.7 Finally found a way to remove the stupid notification! In case anyone is trying to do this with a widget the solution I came up with is to have a normal (not long running) service which is periodically refreshed by the widget 'updatePeriodMillis'. The minimum time for this is half an hour, which seems more than enough to refresh the service in Android's priority list.

Sunday, September 26, 2010

Tokaplot

My latest app, Tokaplot, is now on the Android Market. This is a 2x1 widget which plots phone information over time. The information which can be plotted is (currently):

1. Battery level (in percent).
2. CPU % from /proc/stat
3. Free memory % (from /proc/meminfo)
4. Temperature (in Celsius, from the phone battery temperature sensor).
5. GSM signal (the phone cell signal strength in -dBm).
6. WiFi signal (also in in -dBm)
7. Network data received (in kB, from the difference between readings of /proc/net/dev)
8. Network data sent (in kB)
9. Gravity (in units of acceleration, this is the dot product of gravity and the vector orthogonal to the phone screen).
10. Magnetic field (in microTeslas, this is the magnitude of the total magnetic field).
11. Light (in Lux, from the phone light sensor).

The sampling rate, and hence plot length, as well as many graphics options can be changed allowing for a fully customisable plotting tool. Useful for showing your battery level usage or how much work your phone's doing!

Android really needs to make installing a widget clearer to stop people getting annoyed they can't 'run' a widget. The widget needs to be installed by long-pressing on an empty space on the home screen. It can then be chosen from the widget menu.

The widget works by asynchronously collecting samples. When the graph is updated, all samples are sorted into time bins, the bins being the size of the sample rate. These bins are then averaged, and the points are joined together. This can result in the graph looking too linear while the phone is asleep, so I plan to put in some smoothing in the future.

Hopefully the reading of the /proc/ information for the CPU and network stuff will work on all devices. This is done every minute at the moment. The load average is quite simple to read, but the network stuff needs a good deal of parsing. The network data counters work by splitting /proc/dev/net into lines, and summing the receive/sent byte columns of lines starting with 'rmnet' (which I think is GSM data) or 'eth' (which I think is WiFi data) .

For more widget sizes I've released Tokaplot +, which has 2x2, 4x1 and 4x2 sizes as well as extra customisation.

Update 1.0: First release version.

Update 1.1: Bugfixes and tidying.

Update 1.2: Added CPU load and tweaked UI.

Update 1.3: Added WiFi strength, also tweaked rendering and menu. Changed the sampling and added time smoothing. Re-wrote a lot of internals to make adding new plots much easier.

Update 1.4: Added network data counters, hope these work on all devices. Added a very fancy colour picker, which I've been meaning to write for ages. Also added longer ranges - now up to 3hrs (17 days total!). Also minor UI tweaking.

Update 2.0: Major, major update. Just about threw out all the old internals and re-wrote them. The data collection now works asynchronously, with new data points being added to a wrappable buffer. Each data value collected is given a timestamp, which is used to sort the data into bins. The bins are averaged and then the renderer does a join-the-dots to show the graph.

I'd also been using threads to run each widget. It turns out this is a bad idea. People complained of freezing, which I think was caused by this. Everything now is carried out on a task queue using Runnables. Simpler code, less overhead and no synchronization issues to worry about as it's all the same thread! Multiple widgets are also now properly supported.

Other things are the widget now properly supports Android 1.5-2.0, the renderer was re-written to take a list of points rather than just plotting whatever was in the buffer. The widget now updates when the phone wakes up and user preferences are saved. Finally some UI elements were added.

2.01: Minor tidies/fixes. Changed the graphline so it now goes off the left hand side of the plot. Caught a rare error where Android would hand a null pointer to widget update (why? Who knows?). Tried to improve the re-appearance of the widget after device restart, but really have no idea how Android handles this.

2.1: Added free memory % and big button to link to Tokaplot +. Sorry, I know I said no spam!

2.2: Important update. I'd assumed that services were naturally long-running, especially if their thread is being used frequently. Turns out this is not the case, and you have to tell Android your service is a long running service and shouldn't be killed. This requires you (in 2.0+) to put an annoying icon in the status bar. A fudgy way round this is to set the icon to blank and set the notification time really, really high. VoilĂ , no icon. This should fix all the freezing problems with the widget. I really should have read the Android Service notes more carefully..

2.21: Reduced thread priority to 1 to stop clashes with other long-running services such as music players.

2.22: Fixed a minor bug where the data plots would occasionally show large negative values.

2.30: Added battery current. Note: This will not work on most devices as they don't have this information! Tested on the HTC desire.

2.32: Added ability to lock widget. Also fixed a minor bug with free memory % calculation.

2.6 Finally found a way to remove the stupid notification!

Thursday, June 10, 2010

Virtual Hourglass

My second app, a virtual hourglass, is now on the Android market. This uses a granular physics model to calculate the motion of each grain inside the hourglass. The particle size can be chosen from large (runs the fastest) to small (runs the slowest). The grains respond to gravity, if there's a sensor on the device, so the hourglass can be turned over when it's run out.

The hourglass runs out in about a minute or so on my phone (HTC Desire) but takes longer on the Android emulator. So it's not that useful for timing but fun to watch! There's a clock in the top left hand corner for timing.

It uses a soft-sphere discrete element model. I think there are a few applications that use this in the Market already, namely bubble ones. Each particle is modelled as a slightly squashy sphere. At each step the forces on the particle from all of its neighbours is worked out. Then the speed and position of all of the particles is updated. Not surprisingly, this takes a lot of processing! So, it might be quite slow on early Android phones, although I'm trying to improve the speed. After the nightmare of OpenGL ES, I decided to use the 2D Android graphics library, which should work on more (all?) phones.

Update 1.1: I'm getting a lot of NullPointerException errors reported in this. It seems to be caused by re-registering the sensors, which is weird. I've changed the way I do this, so hopefully it will behave a bit better.

Touching the screen now freezes the grains under the point touched.

Also, I added a bunch of options for changing the springiness and damping of each grain. Springiness doesn't really seem to make much of a difference. The damping, on the other hand, really affects the time it takes for particles to drain out where a small amount of damping makes the particles run out a lot faster.

Update 1.2: Added a lot more options, including the ability to change the skin and particle colour. People seem to like being able to customise the way things look..

Update 1.3: Re-wrote and optimised a lot of the internal code for speed, managed to get around a 50% improvement. Also fixed a very annoying bug in onResume. Previously this called a function which re-registered the acceleration sensors, but on some phones this seemed to occasionally use a null pointer. Why? Who knows? The sensor stuff has been re-written and it seems like this has got rid of the bug.