2

I want to perform a certain task when a shake is detected through an accelerometer but the problem is every device's sensitivity level is different. For example: look at this code on sensor changed `

public void onSensorChanged(SensorEvent event) {

    float[] values = event.values;
    // Movement
    float x = values[0];
    float y = values[1];
    float z = values[2];
    //formula
    float accelationSquareRoot = ((x * x + y * y + z * z)
            / (SensorManager.GRAVITY_EARTH * SensorManager.GRAVITY_EARTH));
    float acc = accelationSquareRoot - 1;
    String s1 = String.valueOf(acc);
    //if I used a value 10 instead of 7 below it will be fine for samsung 
    phones but will not work on most nokia phones
    if (acc >= 7){//perform certain task} }

For my Nokia 6.1 the shake detection is min 1 to max 10 and if the value is above 10 nothing will be detected, for Samsung Galaxy Note7, the detection level is from min 1 to max 30, which means every manufactures hardware is a bit different from others. If I set the value to 7, I have to shake hard on my Nokia 6.1 but on Samsung phones, value 7 is considered a very low sensitivity and the code will run even on touching the phone. I want the user's having various android devices to set the sensitivity level they want like small, medium, hard. What should I do to run this on devices from nearly 1300 brands with over 24,000 distinct android devices?

  • Please check this answer https://stackoverflow.com/a/59837164/10084073. It performs well across devices for me. – M Amd Nov 23 '20 at 09:42

1 Answers1

0

Please Try this way,

import androidx.appcompat.app.AppCompatActivity;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.widget.Toast;
import java.util.Objects;
public class MainActivity extends AppCompatActivity {
   private SensorManager mSensorManager;
   private float mAccel;
   private float mAccelCurrent;
   private float mAccelLast;
   @Override
   protected void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.activity_main);
      mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
      Objects.requireNonNull(mSensorManager).registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
      SensorManager.SENSOR_DELAY_NORMAL);
      mAccel = 10f;
      mAccelCurrent = SensorManager.GRAVITY_EARTH;
      mAccelLast = SensorManager.GRAVITY_EARTH;
   }
   private final SensorEventListener mSensorListener = new SensorEventListener() {
      @Override
      public void onSensorChanged(SensorEvent event) {
         float x = event.values[0];
         float y = event.values[1];
         float z = event.values[2];
         mAccelLast = mAccelCurrent;
         mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
         float delta = mAccelCurrent - mAccelLast;
         mAccel = mAccel * 0.9f + delta;
         if (mAccel > 12) {
            Toast.makeText(getApplicationContext(), "Shake event detected", Toast.LENGTH_SHORT).show();
         }
      }
      @Override
      public void onAccuracyChanged(Sensor sensor, int accuracy) {
      }
   };
   @Override
   protected void onResume() {
      mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
      SensorManager.SENSOR_DELAY_NORMAL);
      super.onResume();
   }
   @Override
   protected void onPause() {
      mSensorManager.unregisterListener(mSensorListener);
      super.onPause();
   }
}
  • Ravi, this code will not run on some devices like Nokia 6.1 and some other phones, every phone's sensor is a bit different. – Muhammad Awais Jan 29 '20 at 06:50