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);
}
}
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.
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();
}
}
来源:https://stackoverflow.com/questions/25256541/android-shakesensor-service-for-shake-detection-in-application-background