3

I have develop an Application that have shaking functionality for some function to work so i have use shaking class and implement to Main Activity so its work smoothly while Application running but my question is when my application going to sleep or kill or stop then how to detect shake in background (Service)

My shacking class

public class Shaker implements SensorListener
{
    private static final int FORCE_THRESHOLD = 350;
    private static final int TIME_THRESHOLD = 200;
    private static final int SHAKE_TIMEOUT = 500;
    private static final int SHAKE_DURATION = 1000;
    private static final int SHAKE_COUNT = 3;

    private SensorManager mSensorMgr;
    private float mLastX=-1.0f, mLastY=-1.0f, mLastZ=-1.0f;
    private long mLastTime;
    private OnShakeListener mShakeListener;
    private Context mContext;
    private int mShakeCount = 0;
    private long mLastShake;
    private long mLastForce;

    public interface OnShakeListener
    {
        public void onShake();
    }

    public  Shaker(Context context)
    {
        mContext = context;
        resume();
    }

    public void setOnShakeListener(OnShakeListener listener)
    {
        mShakeListener = listener;
    }

    public void resume() {
        mSensorMgr = (SensorManager)mContext.getSystemService(Context.SENSOR_SERVICE);
        if (mSensorMgr == null) {
            throw new UnsupportedOperationException("Sensors not supported");
        }
        boolean supported = mSensorMgr.registerListener(this, SensorManager.SENSOR_ACCELEROMETER, SensorManager.SENSOR_DELAY_GAME);
        if (!supported) {
            mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER);
            throw new UnsupportedOperationException("Accelerometer not supported");
        }
    }

    public void pause() {
        if (mSensorMgr != null) {
            mSensorMgr.unregisterListener(this, SensorManager.SENSOR_ACCELEROMETER);
            mSensorMgr = null;
        }
    }

    public void onAccuracyChanged(int sensor, int accuracy) { }

    public void onSensorChanged(int sensor, float[] values)
    {
        if (sensor != SensorManager.SENSOR_ACCELEROMETER) return;
        long now = System.currentTimeMillis();

        if ((now - mLastForce) > SHAKE_TIMEOUT) {
            mShakeCount = 0;
        }

        if ((now - mLastTime) > TIME_THRESHOLD) {
            long diff = now - mLastTime;
            float speed = Math.abs(values[SensorManager.DATA_X] + values[SensorManager.DATA_Y] + values[SensorManager.DATA_Z] - mLastX - mLastY - mLastZ) / diff * 10000;
            if (speed > FORCE_THRESHOLD) {
                if ((++mShakeCount >= SHAKE_COUNT) && (now - mLastShake > SHAKE_DURATION)) {
                    mLastShake = now;
                    mShakeCount = 0;
                    if (mShakeListener != null) {
                        mShakeListener.onShake();
                    }
                }
                mLastForce = now;
            }
            mLastTime = now;
            mLastX = values[SensorManager.DATA_X];
            mLastY = values[SensorManager.DATA_Y];
            mLastZ = values[SensorManager.DATA_Z];
        }
    }

}

Main Activity

    public class MainActivity extends Activity implements View.OnClickListener {

      private Shaker shaker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.mainscreen);
shaker = new Shaker(context);

shaker.setOnShakeListener(new Shaker.OnShakeListener() {

            @Override
            public void onShake() {
                    vibrator.vibrate(100);
                }
            }
        });
}

Updated content

public class ShakerService extends Service implements Shaker.OnShakeListener {


    private Shaker mShaker;
    private SensorManager mSensorManager;
    private Sensor mAccelerometer;

    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    public void onCreate() {

        super.onCreate();
        this.mSensorManager = ((SensorManager)getSystemService("sensor"));
        this.mAccelerometer = this.mSensorManager.getDefaultSensor(1);
        mShaker = new Shaker(this);
        mShaker.setOnShakeListener(this);
    }

    @Override
    public void onShake() {
        Utils.DoOnShake(this);
    }

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        return super.onStartCommand(intent, flags, startId);



    }
}
Android_Paradise
  • 325
  • 1
  • 5
  • 15
  • you can use service to run your program in background i.e when your app is not in focus, but if your app is killed or stopped by users(in settings->Apps) then your service will be killed too – jaimin Aug 12 '14 at 05:14
  • @jaimin how to make service like when shake detect then service alive ? – Android_Paradise Aug 12 '14 at 05:18
  • [this question](http://stackoverflow.com/questions/15492599/background-sensing-of-shake-and-gps-problems) will solve your problem – jaimin Aug 12 '14 at 05:40
  • @Android_Paradise how u resolved your issue ? – Erum Feb 19 '15 at 10:19

2 Answers2

3

I have created this type of functionality in my application https://play.google.com/store/apps/details?id=com.deep.profilemaper .

To achieve this functionality you just have to create background service with returning flag START_STICKY in onStartCommand() method of service. This service restart if someone kill your service.

    public int onStartCommand (Intent intent, int flags, int startId)
    {
        super.onStartCommand(intent, flags, startId);

        //your code here

        return START_STICKY;

    }

It is just demo.

Deep Shah
  • 1,334
  • 3
  • 20
  • 41
1

shake event after killed app:

compile 'com.squareup:seismic:1.0.2'

public class serviceShake extends Service implements ShakeDetector.Listener {
    @Override

    public void onCreate() {
        super.onCreate();
        SensorManager sensorManager = (SensorManager) getSystemService(SENSOR_SERVICE);
        ShakeDetector sd = new ShakeDetector(this);
        sd.start(sensorManager);
//register your sensor manager listener here
    }

    @Override
    public void onDestroy() {
//unregister your listener here
    }

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        return null;
    }

    @Override
    public void hearShake() {
        Context ctx = this; // or you can replace **'this'** with your **ActivityName.this**
        try {
            Intent i = ctx.getPackageManager().getLaunchIntentForPackage("com.vyaapaarsamachar");
            ctx.startActivity(i);
        } catch (Exception e) {
            e.printStackTrace();
            // TODO Auto-generated catch block
        }
        Toast.makeText(this, "ShackFromService", Toast.LENGTH_SHORT).show();
    }
}
tej shah
  • 2,995
  • 2
  • 25
  • 35