I wrote an application that logs data coming from my smartphone's sensors. I have a thread that writes this data to a file every hour. When hooked to my laptop, the app works fine. Every hour a new file is created.
But when the smartphone is disconnected from a laptop it doesn't do that. It doesn't crash but the app ran the whole night and only one file was created...
My code uses Thread.sleep() is this an issue?
I am testing this an a Nexus 5 with android 4.4.4
@Override
public void run()
{
String filename = "";
String directory = "";
Date now = new Date();
while (!stopped)
{
Log.i(TAG, "Start the one hour sleep");
sleepForOneHour(now);
now = new Date();
directory = directoryDateFormat.format(now);
filename = filenameDateFormat.format(now);
Log.i(TAG, "Write data to SD-card");
setFileWriteDirectory(directory);
writeDataToSdCard(filename);
}
super.run();
}
private void sleepForOneHour(Date filesWritten)
{
Date now = new Date();
long nowMillies = now.getTime();
long filesWrittenMillies = filesWritten.getTime();
long passedMillies = (nowMillies - filesWrittenMillies);
long milliesPerHour = (60 * 60 * 1000);
long waitMillies = (milliesPerHour - passedMillies);
try
{
sleep(waitMillies);
} catch (InterruptedException e)
{
Log.d(TAG, "Interrupted sleep in filehandler thread");
}
}
UPDATE
I tried using Android.Timer
instead of Thread.sleep
but this gave the same result.
When the phone is not connected to a laptop, it seems that some threads are not executed anymore. Timers and sleeping threads are apparently one of them.
The solution that work for me is to use a WAKE_LOCK. This does seriously affect the power consumption...
In the onCreate
of my main Activity I acquire a WAKE_LOCK like this.
private static WakeLock lockStatic;
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
PowerManager mgr = (PowerManager) this.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
lockStatic.setReferenceCounted(true);
lockStatic.acquire();
...
}
I release the wakelock in the onDestroy
. This is not recommended because this will cause the battery to drain a lot faster, but I use the phone as a dedicated logging device, so I don't care that much about the battery life.
@SuppressLint("Wakelock")
@Override
protected void onDestroy()
{
...
lockStatic.release();
super.onDestroy();
}