While debugging one of my apps (one that sits in the background and
logs accelerometer data), I noticed that it would randomly and without
any prompt reset itself. It would be running it's normal timer task
and suddenly it would stop, the create function would be called and
any running task would halt. Here's the trace:
03-11 07:50:34.574: VERBOSE/AccelerLogService(29277):
0.088633,1.253072,1.103248,9.629586
03-11 07:50:34.584: VERBOSE/AccelerLogService(29277): History Size:
0.083333336
03-11 07:50:35.064: VERBOSE/AccelerLogService(29277):
0.096283,1.253072,1.035146,9.629586
03-11 07:50:35.084: VERBOSE/AccelerLogService(29277): History Size:
0.1
03-11 07:50:35.544: VERBOSE/AccelerLogService(29277):
0.104550,1.253072,1.007906,9.575105
03-11 07:50:36.044: VERBOSE/AccelerLogService(29277): History Size:
0.11666667
03-11 07:50:36.484: VERBOSE/AccelerLogService(29277):
0.120600,1.239452,1.035146,9.615966
03-11 07:50:37.024: VERBOSE/AccelerLogService(29277): History Size:
0.13333334
03-11 07:50:38.994: VERBOSE/AccelerLogService(29277):
0.136867,1.293933,1.035146,9.615966
03-11 07:50:39.014: VERBOSE/AccelerLogService(29277): History Size:
0.15
03-11 07:51:03.984: VERBOSE/AccelerLogService(29395): CREATED
03-11 07:52:41.624: VERBOSE/AccelerLogService(29502): CREATED
And here's the service code:
public class AccelerLogService extends Service implements
SensorEventListener {
private static final String LOG_TAG = AccelerLogService.class
.getSimpleName();
private static final String base_dir = "/sdcard/";
private static WakeLock wl;
private long startTime;
private volatile float[] lastData;
private static Queue<float[]> lastFiveMinutes;
private static BufferedWriter br;
private static Timer timer;
private static TimerTask tt;
float threshold = 0.0f;
int interval;
private boolean getAccelerometer() {
SensorManager sensorMgr = (SensorManager)
getSystemService(SENSOR_SERVICE);
List<Sensor> sensorList = sensorMgr
.getSensorList(Sensor.TYPE_ACCELEROMETER);
boolean addedListener = sensorMgr.registerListener(
(SensorEventListener) this, sensorList.get(0),
SensorManager.SENSOR_DELAY_UI);
if (addedListener)
Log.v(LOG_TAG, "Listener Added");
else
Log.v(LOG_TAG, "Listener Not Added");
return addedListener;
}
@Override
public void onCreate() {
super.onCreate();
if (timer == null)
timer = new Timer();
if (lastFiveMinutes == null)
lastFiveMinutes = new LinkedList<float[]>();
Log.v(LOG_TAG, "CREATED");
}
@Override
public void onStart(Intent intent, int startid) {
super.onStart(intent, startid);
Log.v(LOG_TAG, "STARTED");
if (intent.getExtras().containsKey("ms")) {
interval = intent.getExtras().getInt("ms");
} else {
interval = 5000;
}
startNewLog();
}
private String getFileName() {
return base_dir + getHardwareID() + "_"
+ String.valueOf(System.currentTimeMillis()) +
".csv";
}
public String getHardwareID() {
TelephonyManager tm = (TelephonyManager)
getSystemService(Context.TELEPHONY_SERVICE);
return tm.getDeviceId();
}
private void startNewLog() {
try {
if (getAccelerometer()) {
// acquire a partial wake lock
wl = ((PowerManager)
getSystemService(Context.POWER_SERVICE))
.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
AccelerLogService.class.getPackage().getName());
wl.acquire();
br = new BufferedWriter(new OutputStreamWriter(
new
FileOutputStream(getFileName())));
br
.write("time(mins),X,Y,Z,varX(last 5 minutes),varY(last 5
minutes),varZ(last 5 minutes),magVar(last 5 minutes)\n");
startTime = System.currentTimeMillis();
tt = new TimerTask() {
@Override
public void run() {
float x =
lastData[SensorManager.DATA_X];
float y =
lastData[SensorManager.DATA_Y];
float z =
lastData[SensorManager.DATA_Z];
boolean recordVar = false;
float[] var = new float[3];
int maxSize = 5 * 60 * 1000 /
interval;
if (lastFiveMinutes.size() >=
maxSize) {
recordVar = true;
var = calcVar();
lastFiveMinutes.poll();
}
lastFiveMinutes.add(lastData);
Log.v(LOG_TAG, "History Size: "
+ ((float)
(lastFiveMinutes.size() * interval))
/ 60000.0f);
float timeInMinutes = (float)
(System
.currentTimeMillis() - startTime)
/ (60.0f *
1000.0f);
try {
if (recordVar) {
float mag =
(float) Math.sqrt((double) (var[0]
* var[0] + var[1] * var[1] + var[2]
* var[2]));
String value =
String.format(
"%f,%f,%f,%f,%f,%f,%f,%f\n",
timeInMinutes, x, y, z, var[0], var[1],
var[2], mag);
Log.v(LOG_TAG,
value);
br.append(value);
br.flush();
} else {
String value =
String.format("%f,%f,%f,%f\n",
timeInMinutes, x, y, z);
Log.v(LOG_TAG,
value);
br.append(value);
br.flush();
}
} catch (IOException e) {
e.printStackTrace();
}
}
};
timer.scheduleAtFixedRate(tt, 0, 1000);
}
} catch (FileNotFoundException e1) {
Log.v(LOG_TAG, "UNABLE TO CREATE FILE!");
e1.printStackTrace();
} catch (IOException e) {
Log.v(LOG_TAG, "UNABLE TO WRITE TO FILE!");
e.printStackTrace();
}
}
public float[] calcVar() {
float[] ret = new float[3];
for (int i = 0; i < 3; i++) {
float sum = 0.0f;
for (float[] f : lastFiveMinutes) {
sum += f[i];
}
float mean = sum / (float) lastFiveMinutes.size();
float sum_squares = 0.0f;
for (float[] f : lastFiveMinutes) {
sum_squares += f[i] * f[i];
}
float avg_sum_square = sum_squares / (float)
lastFiveMinutes.size();
float diff = avg_sum_square - mean * mean;
if (diff > 0)
ret[i] = (float) Math.sqrt(diff);
else
ret[i] = 0;
}
return ret;
}
public void stopLog() {
try {
if (timer != null)
timer.cancel();
if (br != null)
br.close();
if (wl != null)
wl.release();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void onDestroy() {
stopLog();
super.onDestroy();
}
@Override
public IBinder onBind(Intent arg0) {
return null;
}
@Override
public void onAccuracyChanged(Sensor arg0, int arg1) {
}
@Override
public void onSensorChanged(SensorEvent arg0) {
lastData = arg0.values;
}
}
All my Activity does is just pass it a polling interval. Is there a
reason the dalvik would simply restart a service like this? I have a
wake lock and I thought that was enough to keep it from getting kicked
out of memory.
Thanks in advance for any replies, I've just discovered that this is a
recurring bug in several of my programs :/.
--
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en