Zephyr HxM BT

A new toy arrived in the post this morning. Eric Morse from TitanXT very kindly arranged this for me as a thank you for building the Tracks2TitanXT Android application.

image

I’ve been after one of these for a little while after getting a look at one when a couple of colleges bought them to help with their training.

As well as heart rate information the unit contains an accelerometer which is used to generate cadence information, this means that it can be used to approximate distances where there is no GPS reception. The data to is passed to a mobile phone via Bluetooth and there are a number of applications that understand the data including My Tacks. There is also an opensource project called zephyropen on goolge code that has documented the protocol and created a desktop app to display the data.

Zephyr also do a smarter version of the HxM called the BioHarness, this version gathers skin temperature and respiration rates as well as all the data from the HxM.

My Tracks only collects data from the sensor while it’s recording a route and it’s not easy to see the data once the workout has finished so I’m tempted to write a little app to grab the data at any time and possible a tool to view the data stored in the My Tracks database. I’ll also look at adding average heart rate info to the workout summary Tracks2Miles can upload to dailymile.

image

The soft belt and pickups is a lot comfier than some of the previous HRMs I’ve used before.

image

image

UPDATE:
From the logs it appears people are interested in where to buy these in the UK. Mine came from these guys, http://www.heartratemonitor-app.com/zephyr_hxm_bluetooth_heartrate_belt.html

Android Notification, Uploading Progressbar

While working on Tracks2Miles and Tracks2TitanXT I have been looking for a better way to show the status of the GPS track upload. In Tracks2Miles I have an entry in the Notification Area that changes as it moves through the steps of creating the route, uploading the track and finally adding a workout that uses the route. The first and the last steps are pretty quick HTTP post actions which return almost instantly, the uploading of the GPS track can take a long time for a big file on a slow network link and there was no way to know how much of the file had been uploaded. For Tracks2TitanXT I’m just using a AsyncTask for now which shows a dialog with a spinning progress bar.

I decided I wanted to add a progress bar to notification entry so went looking to see if anybody had outlined how to do it already. While I found this on United Coders which explained how to put a progress bar into the notification it did not show how to get the current bytes transferred data from the HTTPClient code included in Android.

I started to have a bit of a look at the HTTPClient API to see how I could get some status information out. A basic file upload looks a bit like this

final HttpResponse resp;
final HttpClient httpClient = new DefaultHttpClient();
final HttpPost post = new HttpPost(UPLOAD_URL);
ParcelFileDescriptor fileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r");
InputStream in = context.getContentResolver().openInputStream(uri);
InputStreamEntity entity = new InputStreamEntity(in, fileDescriptor.getStatSize());
post.setEntity(entity);
resp = httpClient.execute(post);
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
...
}

Looking at the InputStreamEntity documentation showed a method called writeTo(OutputStream outputStream). Overriding this method should allow the wrapping of the OutputStream to count the amount of data written to it.

package uk.me.hardill.upload;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import org.apache.http.entity.InputStreamEntity;

public class CountingInputStreamEntity extends InputStreamEntity {
	
	private UploadListener listener;
	private long length;

	public CountingInputStreamEntity(InputStream instream, long length) {
		super(instream, length);
		this.length = length;
	}
	
	public void setUploadListener(UploadListener listener) {
		this.listener = listener;
	}
	
	@Override
	public void writeTo(OutputStream outstream) throws IOException {
		super.writeTo(new CountingOutputStream(outstream));
	}
	
	class CountingOutputStream extends OutputStream {
		private long counter = 0l;
		private OutputStream outputStream;
		
		public CountingOutputStream(OutputStream outputStream) {
			this.outputStream = outputStream;
		}

		@Override
		public void write(int oneByte) throws IOException {
			this.outputStream.write(oneByte);
			counter++;
			if (listener != null) {
				int percent = (int) ((counter * 100)/ length);
				listener.onChange(percent);
			}
		}		
	}
	
	public interface UploadListener {
		public void onChange(int percent);
	}

}

Using a Listener model allows an external class to be notified when the % uploaded changes. With a minor update to the original code we get this

final HttpResponse resp;
final HttpClient httpClient = new DefaultHttpClient();
final HttpPost post = new HttpPost(UPLOAD_URL);
ParcelFileDescriptor fileDescriptor = context.getContentResolver().openFileDescriptor(uri, "r");
InputStream in = context.getContentResolver().openInputStream(uri);
CountingInputStreamEntity entity = new CountingInputStreamEntity(in, fileDescriptor.getStatSize());
entity.setListener(this);
post.setEntity(entity);
resp = httpClient.execute(post);
if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {
...
}

where the containing class has a onChange(int percent) method like this

@Override
public void onChange(int percent) {
	if(percent > lastPercent) {
		notification.contentView.setProgressBar(R.id.progressBar1, 100, percent, false);
		notificationManager.notify(1, notification);
		lastPercent = percent;
	}
}

Using a background thread started by a service to control the upload we end up with something the looks a but like this. A full example project is available here NotificationProgressTest.

Updated versions of both Tracks2Miles and Tracks2TitanXT should be available at the weekend with this new status notifications.