I am quite a beginner in programing, and this is in fact my first project in android. I'm developing a pedometer application. For this purpose, I need to collect data at a frequency rate of exactly 50 Hz. None of the available options allows me to get satisfactory results:
SensorManager.SENSOR_DELAY_FASTES
SensorManager.SENSOR_DELAY_GAME
SensorManager.SENSOR_DELAY_NORMAL
SensorManager.SENSOR_DELAY_UI
So i tried like this:
sm.registerListener(this, accelerometer, 20000);
And here arises the problem. Despite a given frequency, the system does not return the samples on every 20ms interwal. I made some messurments to show you what i mean:
ms x y z
71048 -0.0059945136 7.981956E-4 -0.17364979
71068 -0.024843872 0.0054850876 -0.22273922
71086 0.016724974 0.0061867684 -0.12516594
71106 0.008605644 0.0050877184 -0.15809155
71127 -0.016088352 0.0035609156 -0.19820023
71150 7.1662664E-4 0.010106161 -0.14373398
71167 0.007880032 0.0055761486 -0.15989017
71187 0.016164377 7.1927905E-4 -0.1634798
71209 -0.0028537065 -0.0033412725 -0.17127609
71227 0.0044119656 -0.0018739849 -0.16169643
As you can see at provided data, the interval between samples is not always 20ms.
Here I found the idea of how to deal with it:
Impossibility to change the rate of the accelerometer
" Unfortunately as suggested by other answers, the delay (or sampling rate) that you set is only a suggestion (for the system) of the minimum your application requires however, this can change drastically depending on other applications running or your device entering on power saving modes (turning off cpu etc). One way I was able to get a somewhat good sampling rate was by recording my data from a service, making the service a foreground service and having a power lock with the flag PARTIAL_WAKE_LOCK."
However, I am not able to implement this method. It gives me an error:
Caused by: java.lang.NullPointerException: class name is null
Which leads to the line:
startForeground(notificationId, notification);
Here is my code (i know it's a bit messy, sorry for that):
Notification notification = null;
Intent viewIntent = new Intent(this, SensorService.class);
PendingIntent viewPendingIntent =
PendingIntent.getActivity(contex, 0, viewIntent, 0);
NotificationCompat.Builder notificationBuilder =
new NotificationCompat.Builder(contex)
.setContentTitle("test")
.setContentText("testt")
.setContentIntent(viewPendingIntent);
NotificationManagerCompat notificationManager = NotificationManagerCompat.from(contex);
notification = notificationBuilder.build();
int notificationId = 1;
notificationManager.notify(notificationId, notification);
startForeground(notificationId, notification);
}
And method onStartCommand:
public int onStartCommand(Intent intent, int flags, int startId) {
//Power management
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); //Uzyskujemy dostęp do PowerManager'a.
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "My Tag"); //PARTIAL_WAKE_LOCK zapewnia że CPU pracuje.
wl.acquire();
Log.d(TAG,"onStartCommand");
return START_STICKY;
}
The above code is in a class SensorService:
public class SensorService extends Service implements SensorEventListener{
....
}
And SensorService class is called like this:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pedometer_test);
Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
setSupportActionBar(toolbar);
FloatingActionButton fab = (FloatingActionButton) findViewById(R.id.fab);
fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
}
});
xText = (TextView)findViewById(R.id.xText);
yText = (TextView)findViewById(R.id.yText);
zText = (TextView)findViewById(R.id.zText);
textViewSteps = (TextView)findViewById(R.id.textViewSteps);
this.stepCounter = new StepCounter(textViewSteps);
this.filterValues = new FilterValues(stepCounter, filteredFileWriter);
this.sensorService = new SensorService(xText, yText, zText, textViewSteps, stepCounter, filterValues, getApplicationContext());
}
Do you guys have any ideas on how to fix this error? Maybe there is another easier way to set this even sampling rate? Or maybe I am trying to implement a method that will not work at all? I would appreciate any sort of help.
PS: This is my first post on StacOverFlow, so I apologize in advance for incorrect formating and my poor english. I have not been writing anything in this language for a while.
EDIT: Whole idea of pedometer algorithm is based on:
http://www.analog.com/media/en/technical-documentation/analog-dialogue/pedometer.pdf