Android Shake(Sensor) 服务,用于在应用程序后台进行抖动检测

Posted

技术标签:

【中文标题】Android Shake(Sensor) 服务,用于在应用程序后台进行抖动检测【英文标题】:Android Shake(Sensor) Service For shake Detection in Application Background 【发布时间】:2014-08-12 05:09:03 【问题描述】:

我开发了一个应用程序,该应用程序具有抖动功能以使某些功能正常工作,因此我使用了振动类并实现到主活动,因此它在应用程序运行时工作顺利,但我的问题是我的应用程序何时进入睡眠或杀死或停止如何检测后台抖动(服务)

我的窝棚课

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];
        
    


主要活动

    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);
                
            
        );

更新内容

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);



    

【问题讨论】:

您可以使用服务在后台运行您的程序,即当您的应用程序不在焦点时,但如果您的应用程序被用户杀死或停止(在设置->应用程序中),那么您的服务将被杀死太 @jaimin 如何使服务像摇晃检测然后服务活着? this question 会解决你的问题 @android_Paradise 你是如何解决你的问题的? 【参考方案1】:

我在我的应用程序https://play.google.com/store/apps/details?id=com.deep.profilemaper 中创建了这种类型的功能。

要实现此功能,您只需在服务的 onStartCommand() 方法中创建返回标志 START_STICKY 的后台服务。如果有人终止您的服务,此服务将重新启动。

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

        //your code here

        return START_STICKY;

    

这只是演示。

【讨论】:

你能说明你是如何在 onStartCommand() 中返回 START_STICKY 的吗 BroadcastService 还是仅服务..? 它只是服务,因为你只需要在服务中实现你的抖动检测代码并启动服务。它将继续在后台运行,如果发生抖动,则会调用 onShake() 方法。这是抖动检测的好例子:jasonmcreynolds.com/?p=388 仅在服务中如何获取 Context.. 的实例?【参考方案2】:

杀死应用后的震动事件:

编译'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();
    

【讨论】:

以上是关于Android Shake(Sensor) 服务,用于在应用程序后台进行抖动检测的主要内容,如果未能解决你的问题,请参考以下文章

Android Sensor 介绍

APP获取Sensor对象-Android12

Sensor与android Manager机制

android旋转动画质量

Android Sensor详解Sensor ADSP Sensor1 api使用

Android Sensor软件架构分析