I am trying to display the data from two different sensors and if i comment out the accelerometer data the app will run and show the light sensor data but trying to display the accelerometer data being displayed causes it to crash on launch. if i comment out everything to do with the light sensor i do get the accelerometer data to be shown but they will not be able to be shown at the same time.
the issue being that both sensors use event.values yet at least from my own research this should work although else if gives error in on sensorChanged
which was how Get multiple sensor data at the same time in Android recommended to solve this issue
any help would be great
public class MainActivity extends AppCompatActivity implements SensorEventListener {
//System sensor manager
SensorManager sensorManager;
//active sensors
Sensor lightSensor;
Sensor acelSensor;
TextView xText, yText, zText, lightS;
double ax,ay,az;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initulise veriables
lightS = (TextView) findViewById(R.id.lightS);
xText = (TextView) findViewById(R.id.xText);
yText = (TextView) findViewById(R.id.yText);
zText = (TextView) findViewById(R.id.zText);
//instance of sensor manager
sensorManager = (SensorManager) getSystemService(Service.SENSOR_SERVICE);
//get sensors from sensor manager
lightSensor = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
acelSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
//if error
if (lightSensor == null) { lightS.setText("sensor_error"); }
if (acelSensor == null) {
xText.setText("sensor_error");
}}
#Override
public void onStart() {
super.onStart();
if (lightSensor !=null)
{
sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_FASTEST);
}
if (acelSensor !=null)
{
sensorManager.registerListener(this, acelSensor, SensorManager.SENSOR_DELAY_FASTEST);
}
}
#Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
#Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this, lightSensor, SensorManager.SENSOR_DELAY_FASTEST);
sensorManager.registerListener(this, acelSensor, SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_LIGHT) ;
{
float lux = event.values[0];
lightS.setText(String.valueOf(lux));
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) ;{
/*ax=event.values[0];
ay=event.values[1];
az=event.values[2];*/
xText.setText("X: " + event.values[0]);
yText.setText("Y: " + event.values[1]);
zText.setText("Z: " + event.values[2]);
}
}
You are registering your sensors twice, once at onstart(), and again at onresume().
I removed the extra onregistersensor().
public class MainActivity extends AppCompatActivity implements SensorEventListener {
//System sensor manager
SensorManager sensorManager;
//active sensors
Sensor lightSensor;
Sensor acelSensor;
TextView xText, yText, zText, lightS;
double x;
double y;
double z;
double ax, ay, az;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//initulise veriables
// lightS = (TextView) findViewById(R.id.lightS);
// xText = (TextView) findViewById(R.id.xText);
// yText = (TextView) findViewById(R.id.yText);
// zText = (TextView) findViewById(R.id.zText);
//instance of sensor manager
sensorManager = (SensorManager) getSystemService(Service.SENSOR_SERVICE);
}
#Override
public void onStart() {
super.onStart();
}
#Override
public void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
#Override
public void onResume() {
super.onResume();
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_UI);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT),
SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_LIGHT) ;
{
float lux = event.values[0];
System.out.println("lux " + lux);
}
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
x = event.values[0] /9.8;
y = event.values[1] /9.8;
z = event.values[2] /9.8;
System.out.println("x: " + x);
System.out.println("y: " + y);
System.out.println("z: " + z);
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
Related
I have created a simple app that uses the accelerometer sensor to calculate the outside force then start a mp3 file. It seems to work well unless I turn screen off (or it automaticlly turns itself off) then it stops completely. How can i fix it. My code here, Thanks.
private MediaPlayer mediaPlayer;
private TextView textView;
private SensorManager sensorManager;
private Sensor accelerometerSensor;
private float maxf;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
textView = (TextView) this.findViewById(R.id.textView);
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
accelerometerSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
sensorManager.registerListener(this, accelerometerSensor, SensorManager.SENSOR_DELAY_UI);
}
#Override
public void onSensorChanged(SensorEvent event) {
if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER){
return;
}
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
float f = Math.round(Math.abs(x*x + y*y + z*z));
if (f>maxf ){ maxf =f;}
StringBuilder sb = new StringBuilder();
sb.append("forrce:").append(f).append("\n");
sb.append("MaxForce:").append(maxf).append("\n");
textView.setText(sb.toString());
if (maxf>150) {
mediaPlayer = MediaPlayer.create(this, R.raw.b);
mediaPlayer.start();
maxf=1;
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
Add on-lock services
[Reference][1]https://developer.android.com/guide/components/services.html
And use accelerometer in that particular activity...Hope it helps :)
I've implemented SensorEventListener in my MainActivity, and it works quite well, i'd even say most of the time very well.
But weirdly, sometimes it completely stops working, I need to shake it in every direction for 5-10 seconds and it's magically back on.
It seems to be after the phone as idle/asleep for a long time.
I did implemented the register/unregister on onResume/onPause.
Here is my code, mostly coming from stackoverflow:
SensorManager sensorManager;
private float accel; // acceleration apart from gravity
private float accelCurrent; // current acceleration including gravity
private float accelLast; // last acceleration including gravity
private static final float SHAKE_THRESHOLD = 12.f;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
initSensor();
}
private void initSensor() {
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
registerSensor();
}
private void registerSensor() {
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME_SENSOR);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL, handler);
accel = 0.00f;
accelCurrent = SensorManager.GRAVITY_EARTH;
accelLast = SensorManager.GRAVITY_EARTH;
}
#Override
protected void onPause() {
super.onPause();
sensorManager.unregisterListener(this);
}
#Override
protected void onResume() {
super.onResume();
registerSensor();
}
#Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
accelLast = accelCurrent;
accelCurrent = (float) Math.sqrt((double) (x*x + y*y + z*z));
float delta = accelCurrent - accelLast;
accel = accel * 0.9f + delta; // perform low-cut filter
//Log.d(TAG, ">>> ALL shake accel = "+ accel);
if (accel > SHAKE_THRESHOLD) {
Log.d(TAG, "shake accel = "+ accel);
runOnUiThread(new Runnable() {
#Override
public void run() {
// Do stuffs in the UI
}
});
}
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// Nothing do to here
}
It was fixed by changing the sensor delay to SensorManager.SENSOR_DELAY_FASTEST;
The registration now looks like :
// Global
private static final String HANDLER_THREAD_NAME_SENSOR = "sensorThread";
// ...Registration
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME_SENSOR);
handlerThread.start();
Handler handler = new Handler(handlerThread.getLooper());
mSensorManager.registerListener(this,
mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_FASTEST,
handler);
I am using AccessibilityService to monitor whenever the foreground activity is changed. Additionally whenever a such a change occurs, I need to read the accelerometer readings for the next 5 seconds. I implemented the following code, but I am not getting continuous readings. Sometimes No reading is shown in between 2 app switches
I am able to detect the foreground activity change accurately, and I can run an activity independently that can show the sensor state changes. But problem exists in combining both.
public class WindowChangeDetectingService extends AccessibilityService implements SensorEventListener {
#Override
protected void onServiceConnected() {
...
}
SensorManager mSensorManager;
Sensor mAccelerometerSensor;
SensorEventListener mListener;
#Override
public void onAccessibilityEvent(AccessibilityEvent event) {
if (event.getEventType() == AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED) {
try {
mSensorManager.unregisterListener(mListener);
}
catch (Exception e){
Log.d("not unregs",e.toString());
}
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this, mAccelerometerSensor, SensorManager.SENSOR_DELAY_NORMAL);
Handler h = new Handler();
h.postDelayed(new Runnable() {
#Override
public void run() {
// do stuff with sensor values
mSensorManager.unregisterListener(mListener);
}
}, 5000);
ComponentName componentName = new ComponentName(
event.getPackageName().toString(),
event.getClassName().toString()
);
ActivityInfo activityInfo = tryGetActivity(componentName);
boolean isActivity = activityInfo != null;
if (isActivity)
Log.i("CurrentActivity", componentName.flattenToShortString());
}
}
#Override
public void onInterrupt() {}
#Override
public void onSensorChanged(SensorEvent event) {
float x = event.values[0];
float y = event.values[1];
float z = event.values[2];
Log.i("\nAccelerometer: \n","X:"+x+"\tY:"+y+"\tZ:"+z);
}
}
Use SENSOR_DELAY_GAME or SENSOR_DELAY_FASTEST instead of SENSOR_DELAY_NORMAL
mSensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
mAccelerometerSensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener(this,
mAccelerometerSensor, SensorManager.SENSOR_DELAY_GAME);//change here
If the user turns over the phone I want to react to that by stopping my text to speech reading. It would be a nice feature for my app, but how can I detect this motion? I'm not really familiar with motion sensors and I could not find this specific motion listener anywhere, mostly just screen orientations. Thanks for the help!
This sample activity demonstrates how a device's gravity sensor can be used to detect when the device is turned over. In method onSensorChanged(), term factor determines how complete the "turn over" must be. Typical range might be 0.7 to 0.95.
Support for Gravity Sensor was added in Android API 9. Not all devices have a gravity sensor.
public class MainActivity extends AppCompatActivity implements SensorEventListener {
private static final String TAG = "Demo";
private SensorManager mSensorManager;
private Sensor mGravitySensor;
private boolean mFacingDown;
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
// nothing
}
#Override
public void onSensorChanged(SensorEvent event) {
final float factor = 0.95F;
if (event.sensor == mGravitySensor) {
boolean nowDown = event.values[2] < -SensorManager.GRAVITY_EARTH * factor;
if (nowDown != mFacingDown) {
if (nowDown) {
Log.i(TAG, "DOWN");
} else {
Log.i(TAG, "UP");
}
mFacingDown = nowDown;
}
}
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mGravitySensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY);
if (mGravitySensor == null) {
Log.w(TAG, "Device has no gravity sensor");
}
}
#Override
protected void onResume() {
super.onResume();
if (mGravitySensor != null) {
mSensorManager.registerListener(this, mGravitySensor, SensorManager.SENSOR_DELAY_NORMAL);
}
}
#Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}
}
with your help and some guides on the internet, i'm managed to knock out this code. But I find myself with several problems, the application, according to my idea, it should start the media player at the time the phone is shaken, and start it once, but now the media player is started every time the phone is shaken . Furthermore, I would like that, the application worked and the screen off when the phone is shaken starts the media player and the screen is turned on
public class SensorTestActivity extends Activity implements SensorEventListener {
private SensorManager sensorManager;
private boolean color = false;
private View view;
private long lastUpdate;
MediaPlayer mMediaPlayer;
#Override
public void onCreate(Bundle savedInstanceState) {
requestWindowFeature(Window.FEATURE_NO_TITLE);
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
view = findViewById(R.id.textView);
view.setBackgroundColor(Color.BLUE);
sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
lastUpdate = System.currentTimeMillis();
}
#Override
public void onSensorChanged(SensorEvent event) {
if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
getAccelerometer(event);
}
}
private void getAccelerometer(SensorEvent event) {
float[] values = event.values;
// Movement
float x = values[0];
float y = values[1];
float z = values[2];
float accelationSquareRoot = (x * x + y * y + z * z)/(SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH);
long actualTime = System.currentTimeMillis();
if (accelationSquareRoot >= 2) //
{
if (actualTime - lastUpdate < 200) {
return;
}
lastUpdate = actualTime;
Toast.makeText(this, "Device was shuffed", Toast.LENGTH_SHORT).show();
if (color) {
view.setBackgroundColor(Color.GREEN);
try {
mMediaPlayer = MediaPlayer.create(getBaseContext(), R.raw.mymusic);
mMediaPlayer.setLooping(false);
mMediaPlayer.start();
mMediaPlayer.setOnCompletionListener(new
OnCompletionListener() {
public void onCompletion(MediaPlayer arg0) {
// if (mMediaPlayer != null) {
// mMediaPlayer.release();
// mMediaPlayer = null;
// }
}
});
} catch (Exception e) {
if (mMediaPlayer != null) {
mMediaPlayer.release();
mMediaPlayer = null;
}
}
}
} else {
view.setBackgroundColor(Color.RED);
}
color = !color;
}
#Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
#Override
protected void onResume() {
super.onResume();
// register this class as a listener for the orientation and
// accelerometer sensors
sensorManager.registerListener(this,
sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
SensorManager.SENSOR_DELAY_NORMAL);
}
#Override
protected void onPause() {
// unregister listener
super.onPause();
sensorManager.unregisterListener(this);
}
}
To start something just once, add a boolean.
boolean startOnce = true;
if (startOnce) {
....
startOnce = false;
}