I am create a demo from receive step from reboot like this.
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private SensorManager sensorManager;
#Override
public void onCreate(Bundle savedInstanceState) {
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
}
#Override
protected void onResume() {
super.onResume();
countSensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
sensorManager.registerListener(this, countSensor, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_STEP_COUNTER) {
Log.i("TAG","step from reboot" + String.valueOf(event.values[0]));
}
}
}
But when I test on my device (SamSung Galaxy S4), the STEP_COUNTER sometime not work well :(. I figure out it by compare with SHealth
After many many test I found
Almost time, STEP_COUNTER return the step equals SHealth BUT sometime different. Therefore I think SHealth may use another sensor for counting step but I don't know which sensor? I think it is not STEP_DETECTOR because STEP_DETECTOR return very few step when turn off the screen.
Sometime, STEP_COUNTER stop working while SHealth still return the step, for example, I walk about 100 steps => SHealth display 110 and demo app display 100, then I continue walk about 200 steps => SHealth display 305 and demo app display 121 (seem like it stop work)
I also receive the report from many user with different device (with low rating :( ) but I can only reproduce it on my device.
I don't know how to fix this problem. I think STEP_COUNTER is the best sensor for receive step (compare with STEP_DETECTOR)
Any help or suggestion would be great appreciated.
We've also encountered in this problem, when using the default steps sensors of the phone. However, we're using TYPE_STEP_DETECTOR - and we don't have the issue you have(more than 100000 users), so perhaps something is wrong there?
This issue is quite resemble in the way that you can't rely on such mechanism. For our case, we've received a lot of steps in a short amount of time. Even if you're a tiger, you can't make that many steps.
Here's the thing, Samsung manipulates the OS and there are a lot of stuff that works well on say, nexus devices, BUT not on Samsung devices.
After trying to fix the behaviour of the step sensor, we've figured out we need an alternative for Samsung phones, or, for phones that do not support it.
FYI, We've encountered that some phones (mostly Motorola) doesn't have the steps sensors in the device, so trying to find the sensors, returns null.
SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
Sensor stepDetector = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
if (stepsDetector != null) {
//Do something
}
You could implement your own mechanism, using wakelock and accelerometer(which has a huge battery consumption, watch out).
Do you unregister the sensor when you leave the app? According to the SDK documentation :
"If you want to continuously track the number of steps over a long period of time, do NOT unregister for this sensor, so that it keeps counting steps in the background even when the AP is in suspend mode and report the aggregate count when the AP is awake".
Hope this will help...
Related
I am building a tracking app that requires regular updates from the step counter. I have been working on this for a couple of months and have not faced any problems with the step counter so far. Now from one day to the next, the step counter is counting up to a certain number, then stops increasing the step number.
I am initializing the sensor from a foreground service like this:
float steps = 0;
mStepSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
mStepSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
mSensorManager.registerListener(this, mStepSensor, SensorManager.SENSOR_DELAY_NORMAL);
#Override
public void onSensorChanged(SensorEvent sensorEvent) {
System.out.println("TrackingService/onSensorChanged", "Steps: " + sensorEvent.values[0]);
mSteps = sensorEvent.values[0];
}
After a reboot, the steps count up properly. Some time after a couple of thousand steps, the sensor just stops to emit any events. I haven't had that problem with exactly the same code in the past, but wanted to hear: Has anyone experienced a similar issue and can recommend a solution?
D5 runs Android 4.4
I want to measure the heart rate, but standard way of registerListener is not working (not hardware problem, with inbuilt app is working).
I get all sensors from device and i found this:
{Sensor name="ULPSH Heart Rate M", vendor="QuickLogic Inc", version=1, type=87, maxRange=100.0, resolution=1.0, power=1.1, minDelay=0}
In android.hardware.Sensor i don't found this type id 87 so i tried the following:
mSensorManager = (SensorManager)getSystemService(Context.SENSOR_SERVICE);
mHeartRate = mSensorManager.getDefaultSensor(87);
mSensorManager.registerListener(this, mHeartRate, SensorManager.SENSOR_DELAY_NORMAL);
....
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == 87) {
//do something
}
}
but unfortunately is not working, the measurement is not getting started.
I tried this code with another sensor (Step Counter, type 19) that works well.
Any idea what I'm doing wrong?
I have the same problem. I think the problem is the firmware. You also can't get access to gyro, barometer and etc.
I found in the Launcher app how you can access the last heart rate.
System.getInt(getContentResolver(), "last_heart_rate", 0);
The problem I'm having is that my count is totally off, from any pedometers, fitbit, or the Samsung Step Counter.
It appears to shut down, and not add any steps after awhile.
If I enter that I'm starting at 3000 for example, it calculates an offset and it stores as a shared preference. It tries to remain registered for the the Sensor. I also store the current steps, so that if the activity that is listening for Step Broadcasts is resumed, it will request for the steps to be output.
I have tried making the service provide notifications and be a foreground service, but the accuracy does not improve, and it uses a ton of power, I have tried a wakelock, with similiar results, not accurate, and uses too much power.
As it stands, my app does not show up in the power usage statistics, so it is hardly using power at all. The hardware sensor should be capturing steps from the accelerometers, and when it does wake up, it should output the newest steps. When it does update, it is closer to the value that I set as the step count.
I am using the Step Counter which was made available in kitkat or above, on some devices. The following code registers for the sensor.
Sensor sensor = sensorManager.getDefaultSensor(Sensor.TYPE_STEP_COUNTER);
if (null != sensor)
{
sensorManager.registerListener(this, sensor,
SensorManager.SENSOR_DELAY_NORMAL);
}
This is within the OnCreate Method of a Service, that I have constructed.
The Service is created as sticky. And uses a broadcast receiver to receive starting steps from an activity, to compute an offset. It also broadcasts the steps that have happened. Here is more of the code.
class MyBroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ACTION_REQUEST_STEPS))
{
SendStepBroadcast(currentSteps);
}
else if (intent.getAction().equals(ACTION_SET_STEPS))
{
setSteps = intent.getFloatExtra(
STEPS_OCCURRED, -1);
SendStepBroadcast(setSteps);
}
}
}
#Override
public void onSensorChanged(SensorEvent event) {
if (setSteps > -1) {
offset = setSteps - event.values[0] + 1;
SharedPreferences prefs = getSharedPreferences("com.halfwaythere",
MODE_PRIVATE);
prefs.edit().putFloat("offset", offset).apply();
setSteps = -1;
}
currentSteps = event.values[0] + offset;
SharedPreferences prefs = getSharedPreferences("com.halfwaythere",
MODE_PRIVATE);
prefs.edit().putFloat("currentSteps", currentSteps).apply();
SendStepBroadcast(currentSteps);
}
private void SendStepBroadcast(float steps) {
Intent broadcastSteps = new Intent();
broadcastSteps.setAction(ACTION_STEPS_OCCURRED);
broadcastSteps.putExtra(STEPS_OCCURRED, steps);
this.sendBroadcast(broadcastSteps);
}
In the Activity the following code is used to start the service:
#Override
protected void onStart() {
super.onStart();
Intent intent = new Intent(this, StepService.class);
startService(intent);
}
My most recent set of attempts to fix this, I tried the following:
Use android:process=":background" to start the service in it's own process. I will try this tomorrow in a field test, and see how it works.
I tried setting the count to zero, and found out my code would not allow, so in the above code I used > -1. Since -1 shouldn't be a valid step count.
All of the code above has test wrapped around it, and I've tried to find any edge cases, and have looked over stack overflow for pedometer problems with Step Counter on Samsung Galaxy S4. Or anything about best practices.
Thanks, and if you need any additional info, please let me know.
From my research:
When the screen is locked, the Hardware Sensor waits before outputting steps. It does count steps, but once you press the button on the side it wakes up, and it receives a SensorEvent.
Service was occasionally having Start Command being called. Was very important that I only register once, so I added a boolean that would be flipped once the initialization was called, and flip off after that. Service was paused, but not killed, and Start Command would run upon it being awoken.
Setting Service to Foreground, seems to be getting closer to the value from other pedometers. Uses more battery, but is keeping it going more, so that makes sense.
Did not require wakelock, it was only on for several milliseconds, but that did not cause the hardware sensor to send results.
Will have my Service run till goal is achieved, or offer the option to stop tracking at half way point. I really just wanted something to tell me that I would get my goal if I turned around, anything else will be equivalent to extra steps.
So I will apply what I found and continue on with my app, should be on the App Store by mid July.
I developed a Data collector which collects data from Accelerometer, Gyroscope, Magnetometer and it worked fine for a while. Then I added Linear Acceleration to it as well (After 4 months, this week). Now both the version are behaving very strangely. Sometime they log the data perfectly when I do some physical activities like walking etc. However, sometimes it doesn't update sensors values and just repeat old values i.e each sensor value is updated lets after 5 seconds, 2 sec etc randomly and I need a sampling rate of 50 samples per second. I experimented with 10-15 participants and all my data was invalid because of this. The strange things is that the same app has worked perfectly before. I can't find any problem in it. I am placing some of the snapshots here. May be if someone can point to any bug or something ?
The buffered Writter:
FileWriter fow;
BufferedWriter bow;
extfile = new File(extfilepath, message + ".csv");
fow = new FileWriter(extfile);
bow = new BufferedWriter(fow);
This bow.writer is then being used in timertask thread to log data every 20 milliseconds.
Can anyone please comment or help me with this ? This weird behavior of this app is beyond my understanding.
Check that you have a wake lock acquired if your application goes to background. I've used PowerManager.PARTIAL_WAKE_LOCK successfully in a data collection application.
When your display turns off, your application is at least paused (and system might even stop it). The partial wake lock "Ensures that the CPU is running; the screen and keyboard backlight will be allowed to go off." So reading between the lines it means that otherwise your CPU might go to sleep for small periods of time in order to save power.
Did you forget to paste in:
else if (event.sensor.getType() == Sensor.TYPE_LINEAR_ACCELERATION){} ?
Are you using the accelerometer data, then subtracting gravity?
OK. What's your code look like to call the timer?? Something like this?
Timer updateTimer = new Timer("linear accel");
updateTimer.scheduleAtFixedRate(new TimerTask() {
public void run() {
updateGUI();
}
}, 0, 100);
}
private void updateGUI() {
runOnUiThread(new Runnable() {
public void run() {} } ?
I am trying to read multiple sensors from a Samsung Galaxy Tab GT-P1000 and they seem to be hogging the CPU quite badly relative to the applications I've used.
As a test, I created a short program which implements the SensorEventListener for the Accelerometer sensor, but does nothing with the sensor readings:
public class SensorTestActivity extends Activity implements SensorEventListener {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
SensorManager oSensorManager = (SensorManager)getSystemService(SENSOR_SERVICE);
oSensorManager.registerListener(this, oSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_GAME);
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// TODO Auto-generated method stub
}
#Override
public void onSensorChanged(SensorEvent event) {
// TODO Auto-generated method stub
}
}
This results in 10% constant CPU usage while I'm debugging (ie my device is plugged in to my PC) and 5% usage while I'm not. If I use SENSOR_DELAY_FASTEST, the usage skyrockets to constant 30% while I'm debugging and 20% while I'm not.
This creates a massive problem when I want to use multiple sensors, because they all have high CPU usage and that's without any data processing. I've used Compass applications from the Android Market and none of them use more than 5% of the CPU at a given time, so I feel like I'm missing something blatantly obvious, but can't find anyone else having the same problem.
I've not edited the manifest file or layout for this application - it's the default template made by Eclipse and I've added the Sensor.
UPDATE: My method of reading the CPU usage is flawed, because I was using the task manager to measure it. My application isn't stopping the sensors using onPause when the task manager opens, whereas most other applications would do so.
This results in 10% constant CPU usage while I'm debugging (ie my device is plugged in to my PC) and 5% usage while I'm not. If I use SENSOR_DELAY_FASTEST, the usage skyrockets to constant 30% while I'm debugging and 20% while I'm not.
Then use SENSOR_DELAY_UI or SENSOR_DELAY_NORMAL, both of which update you with sensor data less frequently and should consume correspondingly less CPU time.
I've used Compass applications from the Android Market and none of them use more than 5% of the CPU at a given time
They probably don't use SENSOR_DELAY_GAME or SENSOR_DELAY_FASTEST.
Beyond that, different devices (perhaps with different sensor chipsets) may result in different CPU utilization. For example, some devices are annoyingly chatty in LogCat -- devices that log based on sensor readings would be commensurately slower.
Also, I don't know how you are measuring CPU utilization, but I'm not aware of any officially supported means for doing that. I'd focus instead on things like frame rate in your game or whatever it is that you are writing.