Android 如何实现最具成本效益的震动检测器

Android 如何实现最具成本效益的震动检测器,android,android-sensors,Android,Android Sensors,我有一个应用程序,当用户打开手机屏幕时,可能需要检测震动。我已经找到了很多关于如何检测震动的例子。下面的例子是迄今为止使用Google代码并添加重力组件最有趣的例子。我的问题是,这个代码可以改进吗?震动检测非常可靠,我没有得到任何误报。我最关心的是电池寿命的提高 private static final int mMinimumForce = 5; private static final int mShakeFrequency = 500; private static final int

我有一个应用程序,当用户打开手机屏幕时,可能需要检测震动。我已经找到了很多关于如何检测震动的例子。下面的例子是迄今为止使用Google代码并添加重力组件最有趣的例子。我的问题是,这个代码可以改进吗?震动检测非常可靠,我没有得到任何误报。我最关心的是电池寿命的提高

private static final int mMinimumForce   = 5;
private static final int mShakeFrequency = 500;
private static final int mMovesRequired  = 4;
private float[] mGravity                 = { 0.0f, 0.0f, 0.0f };
private float[] mAcceleration            = { 0.0f, 0.0f, 0.0f };
private static final int mXAxis          = 0;
private static final int mYAxis          = 1;
private static final int mZAxis          = 2;
private long mCurrentTime                = 0;
private long mLastTime                   = 0;
private int mMoveCount                   = 0;
private final float mAlpha               = 0.8f;

public void onSensorChanged(SensorEvent event)
{
        if(event.sensor.getType() != Sensor.TYPE_ACCELEROMETER)
        {
            return;
        }


        // Set linear acceleration
        // Gravity components of x, y, and z acceleration
        mGravity[mXAxis] = mAlpha * mGravity[mXAxis] + (1 - mAlpha) * event.values[mXAxis];
        mGravity[mYAxis] = mAlpha * mGravity[mYAxis] + (1 - mAlpha) * event.values[mYAxis];
        mGravity[mZAxis] = mAlpha * mGravity[mZAxis] + (1 - mAlpha) * event.values[mZAxis];

        // Linear acceleration of x, y, z with gravity effect removed
        mAcceleration[mXAxis] = event.values[mXAxis] - mGravity[mXAxis];
        mAcceleration[mYAxis] = event.values[mYAxis] - mGravity[mYAxis];
        mAcceleration[mZAxis] = event.values[mZAxis] - mGravity[mZAxis];


        // Set maximum linear acceleration amongst x, y, z
        float maxAcceleration = mAcceleration[mXAxis];

        if (mAcceleration[mYAxis] > maxAcceleration)
        {
            maxAcceleration = mAcceleration[mYAxis];
        }

        if (mAcceleration[mZAxis] > maxAcceleration)
        {
            maxAcceleration = mAcceleration[mZAxis];
        }


        // Process shake
        if (maxAcceleration > mMinimumForce)
        {
            Log.d(TAG, "Shake detected");

            mCurrentTime = System.currentTimeMillis();

            if (mLastTime == 0)
            {
                mLastTime = mCurrentTime;
            }

            long elapsedTime = mCurrentTime - mLastTime;

            if (elapsedTime > mShakeFrequency)
            {
                    mLastTime  = 0;
                    mMoveCount = 0;
            }
            else
            {
                mMoveCount++;

                if (mMoveCount > mMovesRequired)
                {
                    Log.d(TAG, "Shake moves detected: " + mMovesRequired);
                    // do some work here

                        mLastTime  = 0;
                        mMoveCount = 0;
                }
            }
        }
}

Google I/O文档提供了关于您所有问题的大量信息。这里有一份这样的文件。

你关于浮点数学的观点是正确的。虽然您的代码在计算方面做的不多,但在高频率下不断调用它可能会对CPU造成负担

你的点在使用电池的加速计上。虽然每台设备的功耗不同,并且该设备的使用与陀螺仪的使用不尽相同,但如果在一整天的活动屏幕使用中不间断地使用,则会显示出明显的差异

我同意,无论您是否看到电池使用方面的显著差异,按照最高标准和效率编码都是好的。这只是做一个好公民。如果我能多用30分钟打电话,给我

我对你的代码的建议,其实只是反映了谷歌的建议和许多你已经谈到的

  • 以尽可能低的轮询率注册侦听器
  • 在代码开头添加一个过滤器,根据不满足的轮询率立即返回第一点。(当前时间-上次)>投票率。这一点很重要,因为Android可能不会遵守侦听器中注册的投票率
  • 如果可以的话,喜欢整数数学而不是浮点数学
  • 在使用加速计之前,请先研究是否可以使用AlarmManager和/或其他更具成本效益的传感器。我不知道这在你的情况下是否可行,但值得检查一下

为什么您认为您的代码正在使用电池?它依赖于操作系统的传感器事件。所以传感器使用的是独立于代码的电源。谢谢你的回复。说到你的观点。我的代码注册了侦听器,对吗?其他想法,我的代码选择做浮点运算。关于CPU,浮点数学是一个更昂贵的选项。我可以继续…你不能不注册就收听活动。此外,您似乎没有做太多的计算(无循环)。那有什么意义呢?应用程序的所有其他部分将消耗更多。想想一次屏幕刷新会占用多少资源。你似乎在努力节约1nano啊,而其余的打开手机要多花上千倍的时间…很明显,我给SensorManager.registerListener打了电话。也许你可以帮助清理其他人关于电池耗尽的帖子,当他们在加速计上注册Listener时?也许你也可以从d.android.com上澄清这句话?始终确保禁用不需要的传感器,尤其是在活动暂停时。否则可能会在几个小时内耗尽电池电量。请注意,当屏幕关闭时,系统不会自动禁用传感器。举个例子,我的手机的加速计在使用时使用.1mA的功率。关于循环,你认为代码是按频率调用的,对吗?基于您注册侦听器的速率。最后也是更重要的一点,我想告诉你们洛伦兹,我的电池消耗“明显”快了,让我的听众注册。谢谢史蒂夫。谢谢你的帮助。我不确定AlarmManager是否会工作,但是谢谢你给我们考虑。