Так что он отлично работает, когда приложение на переднем плане и первая минута на заднем плане. Но после этого слушатель перестает получать гироскопические данные. Но пост-ветка и слушатель местоположения продолжают работать.
Я много чего перепробовал, и у меня ничего не получалось.
public final class Secret extends Service implements SensorEventListener, LocationListener {
private final String create = "CREATE TABLE IF NOT EXISTS data(lat float, lon float, x float, y float, z float, timestamp bigint)";
private SensorManager sensorManager;
private Database database;
private Location location;
@Override
public final void onCreate() {
/* Init sensor manager */
this.sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
@Override
public final int onStartCommand(final Intent intent, final int flags, final int startId) {
/* Initialize & load database */
this.database = new Database(openOrCreateDatabase("name_data.db", MODE_PRIVATE, null));
this.database.exec(this.create);
/* Init location manager */
final LocationManager locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
try {
/* Register sensor change listener */
this.sensorManager.registerListener(this, this.sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY), SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
/* Register location change listener */
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 1, this);
} catch (final SecurityException e) {
Toast.makeText(this, "Failed to start: " + e.getMessage(), Toast.LENGTH_LONG).show();
e.printStackTrace();
}
/* Post data every 5 minutes */
final Thread thread = new Thread(new Runnable() {
@Override
public final void run() {
/* Secret instance */
final Secret secret = Secret.this;
/* 5 minutes */
final long time = 15000;
while (true) {
try {
/* Wait 5 minutes */
Thread.sleep(time);
/*
* Unregister sensor change listener,
* this way posting wont cause any database errors,
* and the sensor events wont time out when app is running in the background
*/
sensorManager.unregisterListener(secret);
/* Post database */
final int returned = post();
/* Register sensor change listener */
sensorManager.registerListener(secret, sensorManager.getDefaultSensor(Sensor.TYPE_GYROSCOPE), SensorManager.SENSOR_STATUS_ACCURACY_HIGH);
switch (returned) {
case -1:
System.err.println("Database too small to post");
break;
case HttpURLConnection.HTTP_OK:
System.out.println("Posted database");
break;
default:
System.err.println("Post failed: " + returned);
}
} catch (final InterruptedException e) {
System.err.println("Failed to sleep");
e.printStackTrace();
}
}
}
});
/* Set thread priority and start */
thread.setPriority(Thread.MIN_PRIORITY);
thread.start();
return START_STICKY;
}
@Nullable
@Override
public final IBinder onBind(final Intent intent) {
return null;
}
@Override
public final void onSensorChanged(final SensorEvent event) {
System.out.println(System.currentTimeMillis());
/* Store data if location is known */
if (event == null || this.location == null) return;
float[] gyro = event.values;
/* Insert data into database */
this.database.exec("INSERT INTO data(lat, lon, x, y, z, timestamp) VALUES(" + this.location.getLatitude() + "," + this.location.getLongitude() + "," + gyro[0] + "," + gyro[1] + "," + gyro[2] + "," + System.currentTimeMillis() + ")");
}
@Override
public final void onAccuracyChanged(final Sensor sensor, final int accuracy) {
}
@Override
public final void onLocationChanged(final Location location) {
this.location = location;
}
@Override
public final void onStatusChanged(final String provider, final int status, final Bundle extras) {
}
@Override
public final void onProviderEnabled(final String provider) {
}
@Override
public final void onProviderDisabled(final String provider) {
}
/**
* Post database to server
*/
private final int post() {
/* Check if database is large enough (8 MB) to be pushed */
if (this.database.getFile().length() <= 8192) return -1;
/* Push database to server */
final int returned = Connection.post(this.database.getFile());
/* Check if database was pushed successfully */
if (returned == HttpURLConnection.HTTP_OK) {
/* Clear database if it was pushed to server successfully */
this.database.close();
this.database.getFile().delete();
/* Create new database */
this.database = new Database(openOrCreateDatabase("name_data.db", MODE_PRIVATE, null));
this.database.exec(this.create);
}
return returned;
}
}
OnDestroy срабатывает, а затем датчик перестает давать данные. Поток и локация продолжают работать.