Feeds:
Posts
Comments

A friend of mine tested the sleep-cycle application on iPhone and I wanted to test it myself, a quick search for applications for Android yielded some results but I thought I could make my own a prototype in a couple of hours and learn something in the process.

I wanted my application to register movements of the phone using the accelerometer, the phone itself would lie on the bed and register when I turned in my sleep. A high number of turns would then register as uneasy sleep. This is a prime example of implementing a Service (like MyTracks and the music player) that can run in the background even if the phone has gone in stand-by.

Basic bits of reading from the accelerometer

// Pseudo code ... showing the interesting bits.

public class MyService extends Service implements SensorEventListener {

// Obtain a reference to system-wide sensor event manager.
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

// Register for events.
mSensorManager.registerListener(
  this,
  mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
  SensorManager.SENSOR_DELAY_NORMAL);

public void onSensorChanged(SensorEvent event) {
		mNewValue = (int) event.values[0]*10;

		if (mNewValue != mOldValue) {
			Log.d(TAG, Integer.toString(mNewValue));
			mOldValue = mNewValue;
			SystemClock.sleep(1000);
		}
	}

This above could worked together with an Activity that started the Service and that would handle the data, right now it just showed the result in the log. I also did a convert from the float because even if the phone would lie still I’d get very small changes all the time that would trigger the reading. This would of course be calibrated later on.

Everything worked fine, but the instance the phone went into standby readings would stop. This seemed strange since the GPS can be read even when in sleep mode, some googling later I found out that this was a well known issue and can be read about here: LINK

There was a some hacks that might get it working by listening for the broadcast that the phone went into standby, and re-register the SensorEventListener, I made the changes but it doesn’t work on my HTC Legend (2.1). From what I’ve gathered this work around only functions on the Motorola Droid/Milestone. I guess they have implemented this to save battery but it could easily be fixed by having a permission “Application can read sensors, when the phone is in standby (will lower battery time)”. But if you want to read the accelerometer in stand-by the only way of handling this is having a wake-lock, but that would mean having the phone’s screen on the whole night and I don’t think most phones can handle that without depleting their battery.

A couple of days ago I got my HTC Legend and I’m now working with Bluetooth file-transfer. The emulator works fine for most things, but it has no BlueTooth support, so I wanted to develop directly on hardware with debugging through ADB and LogCat in Eclipse.

First I tried installing the USB-ADB-drivers that you can download through the SDK Manager. This didn’t work, I used the tricks that people suggested uninstalling HTC standard drivers and then trying to reinstall. No success. I then tried with the HTC-Sync dreading that it would a lot of bloatware, I didn’t need. But this worked like a charm.

Steps to get your HTC Legend/Hero to work as a development phone, Windows

1. Enable USD-Debugging on Phone, SETTINGS –> APPLICATIONS –> DEVELOPMENT –> USB-Debugging.

2. Uninstall any old USB-drivers using USBDeview

3. Install HTC-Sync.exe on your PC, you can find the file on the phones SD-Card.

4. Connect your phone using the HTC-Sync option (maybe optional)

5. Open a console window and navigate to the sdk/tools/adb.exe, test that your device is connected using “adb devices”. Your devices serial number should be listed.

6. Using Eclipse, install your project using Ctrl+F11 as you would on the emulator, but choose your real device as target.

7. Success, LogCat works just like normal.

There’s a lot of questions about how to correctly manage databases in your Activity but very few answers. If you get leak error “SQLiteDatabase created and never closed” you have this problem. Even the Google Notepad tutorial many people use as a starting point is leaving open databases. This is what I’ve found out, but I’m no expert:

I use a global variable as the database adapter I’ve created and I want to use this in numerous methods inside the activity to read/update/save data from the Activity to the database. Opening and closing the database in each method isn’t a good idea, even worse is creating an adapter each time you need to access the database so.

A database should be instantiated in the onCreate. This ensures that we only have only one when the Activity is paused and resumed and that we don’t have to create a new on each resume.

public class ListEntry extends ListActivity {
private NotesDbAdapter mDbHelper;

/** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
   super.onCreate(savedInstanceState);
   setContentView(R.layout.listentry_main);

   mDbHelper = new NotesDbAdapter(this);

   registerForContextMenu(getListView());
 }

Filler functions should not be called in the onCreate, because when an Activity is created. onResume is also called after onCreate. So to be able to have the correct behavior when the Activity is just paused and resumed the open-statement should be there. This “incorrect” behavior can be seen in the Notepad Tutorial V3 (NoteEdit.java, onCreate) which calls populateFields twice when the Activity is created (first onCreate, then onResume).

 @Override
 protected void onResume() {
 super.onResume();
 mDbHelper.open();
 fillData();            // function that populates the view with values from the database
 }

onPause should close the database so that it frees up resources for other Activities. This is also called when the Activity is destroyed or finished so there’s no need to close the database “onFinish” or “onDestroy”. Closing of the database is not present in the NotePad tutorial and will create Leaks when NoteEdit tries to open an already open database when started again.

@Override
 protected void onPause() {
   super.onPause();
   Log.d("ListEntry onResume db.close()", "close");
   mDbHelper.close();
 }

Functions that create intents to start other Actives should not do anything with the database this is already handled with onPause. For example:

 @Override
 protected void onListItemClick(ListView l, View v, int position, long id) {
   super.onListItemClick(l, v, position, id);

   Intent i = new Intent(this, AddEntry_Tabbed.class);
   startActivityForResult(i, ACTIVITY_EDIT);
 }

Functions that gets called when the Activity is called should not try to open the database and use fillData. This is already taken care of in onResume which also in called when a result is returned from another Activity. For example:


 // Callback when you get back from "StartActivityForResult"
 @Override
 protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
   super.onActivityResult(requestCode, resultCode, intent);
   // Do something.
 }