How to intercept tilting in Android? - android

I would like to write a program using tilting functionality in android.
Is there any way to intercept it? What do I get back? a vector indicating the direction of the tilt?

The main thing to get your head around it the concept of a listener.
In Android there isn't a method called getXtilt(), getYtilt() etc to get the orientation.
Instead you need to create a listener which you register with the system.
Look at this.
See the onSensorChanged(SensorEvent event) method? The Android system will invoke that method every time the sensor changes (which is very frequently). In this case it will be the TYPE_ACCELEROMETER sensor readings you will be receiving.
So when you get the SensorEvent 'event' have a look at the event.values[] array. It will contain the sensor readings. In the example code in the Android doc they register the Sensor.TYPE_ACCELEROMETER. You should register the
Sensor.TYPE_ORIENTATION. Have a look at the values array for
Sensor.TYPE_ORIENTATION. They are the tilt values you are looking for.
hope that helps

Sounds like you would have to use the Accelerometer and interpret the values and then make a decision based on them. Look up SensorEventListener and it should get you in the right direction.

Related

Pedometer (Step Counter)

I am developing a Pedometer Android application to count number of steps taken and using the steps calculate the distance covered and calories burned. I have followed the tutorial
Create a Simple Pedometer and Step Counter in Android and done exactly like it. It detects number of steps when the sensor detects motion.
But there are some problems with it:
When I stand at the same place with my device in my hand and just move my hand or give a jerk to device, it detects the change and adds to step count.
If I move very slowly with device in my hand it does not detect the change.
If i jump, then it adds several steps in the counter.
I have checked some other applications from Play Store they do not do this kind of stuff.
I have searched but cannot find an appropriate solution or tutorial for it. Any help or suggestions. Thanks
The problem here is that your implementation is not sophisticated enough: it only checks if there is a spike in the accelerometer data and assumes that the spike is coming from a step. It has no idea where the spike in acceleration is really coming from: it might as well come from you jumping or shaking the device in your hand.
How to make it more accurate then? Well, that is a really difficult question which has been topic for scientific papers for a really long time. Even the most sophisticated fitness trackers (which use machine learning, signal processing and other statistical methods) have difficulties to determine when the step is real and when it is just noice or user playing with the device.
Luckily Android does have it's own builtin step counter and step detector, which are more sophisticated than the class in yor example.
So unless you really want to learn signal processing and AI (which I highly recommended, although I don't know much about the data science of step detection), I would suggest to use builtin detector and counter.
By implementing SensorEventListener listener within a class and overriding the two methods onSensorChanged and onAccuracyChanged you can start tracking steps.
public class StepActivity extends Activity implements SensorEventListener{
SensorManager sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
Sensor sSensor= sensorManager .getDefaultSensor(Sensor.TYPE_STEP_DETECTOR);
...
}
Now we have initialised the SensorManager and Sensor and have the Sensor registered as a listener within the activity, we now need to implement the onSensorChanged function that will be triggered by a SensorEvent whenever there is a change to the Sensor we registered, in our case the TYPE_STEP_DETECTOR.
private long steps = 0;
#Override
public void onSensorChanged(SensorEvent event) {
Sensor sensor = event.sensor;
float[] values = event.values;
int value = -1;
if (values.length > 0) {
value = (int) values[0];
}
if (sensor.getType() == Sensor.TYPE_STEP_DETECTOR) {
steps++;
}
}
That's a very naive method to achieve step count. You should use Android's built-in step counter because it also uses other sensors if available such as gyroscope which can improve the step detection. You should especially use this built-in version if you are going to built things on top it. You need a reliable underlying layer. You can also try using linear acceleration sensor which is calculated by removing gravity component from the accelerometer. The gravity makes accelerometer very sensitive, that's why you see step counter increasing when you are just standing.
The details can be found here:
https://source.android.com/devices/sensors/sensor-types#step_detector
If you still want to develop your own from scratch, then look at this code:
https://github.com/bagilevi/android-pedometer
You can also try Google scholar for the latest papers on step counting algorithms. Especially try to read the latest survey on the topic.

Android:Why not use TYPE_GRAVITY data in getRotationMatrix(float[] R, float[] I, float[] gravity, float[] geomagnetic)?

gravity is an array of 3 floats containing the gravity vector expressed in the device's coordinate. You can simply use the values returned by a SensorEvent of a Sensor of type TYPE_ACCELEROMETER. This is noted in SensorManager.getRotationMatrix, but I want to know why not use values of TYPE_GRAVITY ? I think it will be better than using TYPE_ACCELEROMETER.because ACCELEROMETER = GRAVIDY - LINEAR_ACCELEROMETER, ACCELEROMETER won't point to the earth when moving.
The three sensors Sensor.TYPE_ACCELEROMETER, Sensor.TYPE_GRAVITY and Sensor.TYPE_LINEAR_ACCELERATION are related by the equation
"Sensor.TYPE_ACCELEROMETER" = "Sensor.TYPE_GRAVITY" + "Sensor.TYPE_LINEAR_ACCELERATION"
If you register for updates for all three, what you find is that Sensor.TYPE_ACCELEROMETER always arrives first, followed by Sensor.TYPE_GRAVITY and Sensor.TYPE_LINEAR_ACCELERATION, and that the values always satisfy that equation. Internally, Android is using filtering, and in particular a Kalman filter, to separate the two.
A low pass filter is a simple way of doing something similar. However, a lot of thought will have gone into the Android mechanism, so I'm sure that if a low pass filter was better, then Android would have implemented that.

Get accelerometer values in time

I have to get the accelerometer values in time.
I saw the Sensor class and the SensorEventListener but this listener notify only when the value changes and I need a periodic notification (also if the value do not change).
Otherwise I would like to continuously read the accelerometer value but it is not possible according to this thread: Get current SensorEvent value
What can I do?
Why do you need to continuously "read" the sensor values even when they are the same as before? If you need to calculate some output on a regular basis, then a better solution might be to set up a timer that triggers on the required intervals at which time you use the values from a set of variables that are updated whenever the sensor values change. That way even if they don't change, the timer will initiate the calculations.
Kaamel

Detect collision between two bodies in Box2d and libgdx(android)

I am new to libgdx and Box2d engine and I'm developing a game using same .I want to detect collision between two bodies to perform some function.But I'm not aware about the optimum way to do that and also want get point of collision.Kindly provide some suggestion with code.I have already implemented ContactListener but to no avail.
I'm using this code as a reference.
Thanks
You already did it the right way to create and set a ContactListener... (for a general setup, the libgdx wiki is great: https://github.com/libgdx/libgdx/wiki/box2d#contact-listeners)
If you now want to handle the specific contacts, you for exmaple need to add some implementation in the beginContact(); method of your listener. The beginContact(); method contains a Contact instance, which holds all you need:
FixtureA - the first fixture of a contact
FixtureB - the fixture, which FixtureA has collided with
WorldManifold - an object that holds the collision points etc
Through the fixtures you can access the bodies and the actors which you are drawing. The connection to your Actor can be done through the body.setUserData(actor); method.
Now you need to decide on how to find out the correct collisions. You can either work with sensors, which are box2d fixtures that just act as a sensor. That means that when an object collides with a sensor, it won't bounce, but fall through it instead. But you then are able to detect this contact within the listener.
Also, it might be a good idea to add some kind of GameObjectType to your actors. Imagine you create a jumping game where the player jumps from platform to platform with water below. Then you would create your actors with types like PLAYER, WATER, PLATFORM ... through the getUserData() method of the box2d bodies yu can now access the Actors and compare their types.
E.g. when an Actor of type PLAYER collides with one of type WATER, he will drown...
Hope it helps...

Pull single value from sensor without using an event

I need some help getting info from the orientation sensor. As I have seen in just about every tutorial/guide out there, the values are passed to an event (onSensorChanged(SensorEvent event) in which they can be manipulated.
My problem is that I don't want to keep the electro-magnetic/orientation sensor running constantly (for the sake of battery life). I want to be able to turn it on, grab the current value and switch it off. Is there any way to do this?
I have done some searching and found that I can try multi-threading, but I'm not fully comfortable with that.
What I'm looking for is something like (Sorry for lack of formatting I can't seem to figure it out):
private void getOrientationNOW() {
m_SensorManager.registerListener(mySensorEventListener, m_MagneticSensor, SensorManager.SENSOR_DELAY_FASTEST);
//---->Something here to get the current value from the sensor
m_SensorManager.unregisterListener(mySensorEventListener);
}
If this is possible, please help me!
Thank you all in advance!
When you register a listener for a sensor the activity will be called every time the sensor values changes according to the parameters. So if you want to get the values only one once what you could do is unregister the listener for that sensor after getting the value once.

Categories

Resources