Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/222.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android:在Shake Listener类中使用SharedReferences_Android_Sharedpreferences - Fatal编程技术网

Android:在Shake Listener类中使用SharedReferences

Android:在Shake Listener类中使用SharedReferences,android,sharedpreferences,Android,Sharedpreferences,首先,我对安卓和编程基本上都是新手,所以请放轻松- 第二,我认为这个网站是一个救星! 好的,现在来谈谈问题的实质 在我努力学习更多关于Android开发和使用用户偏好的知识的过程中,我创建了一个运行良好的小应用程序,它有许多选项,用户可以更改这些选项以使其看起来与众不同。然而,我遇到了一个小障碍,试图让它设置为允许定制抖动检测的灵敏度和抖动检测之间的时间 我的一切都正常工作,所以如果用户摇晃手机,它就会按我的要求操作。以下是我根据stackoverflow上的一篇文章所做的抖动检测的基本内容:

首先,我对安卓和编程基本上都是新手,所以请放轻松- 第二,我认为这个网站是一个救星! 好的,现在来谈谈问题的实质

在我努力学习更多关于Android开发和使用用户偏好的知识的过程中,我创建了一个运行良好的小应用程序,它有许多选项,用户可以更改这些选项以使其看起来与众不同。然而,我遇到了一个小障碍,试图让它设置为允许定制抖动检测的灵敏度和抖动检测之间的时间

我的一切都正常工作,所以如果用户摇晃手机,它就会按我的要求操作。以下是我根据stackoverflow上的一篇文章所做的抖动检测的基本内容:

创建了一个名为ShakeDetector的新类,并将以下代码放入其中:

import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;

public class ShakeDetector implements SensorEventListener {

/*
 * The gForce that is necessary to register as shake.
 * Must be greater than 1G (one earth gravity unit).
 * You can install "G-Force", by Blake La Pierre
 * from the Google Play Store and run it to see how
 *  many G's it takes to register a shake
 */
private static final float SHAKE_THRESHOLD_GRAVITY = 2.7F;
private static final int SHAKE_SLOP_TIME_MS = 500;
private static final int SHAKE_COUNT_RESET_TIME_MS = 3000;

private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;

public void setOnShakeListener(OnShakeListener listener) {
    this.mListener = listener;
}

public interface OnShakeListener {
    public void onShake(int count);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // ignore
}

@Override
public void onSensorChanged(SensorEvent event) {

    if (mListener != null) {
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        float gX = x / SensorManager.GRAVITY_EARTH;
        float gY = y / SensorManager.GRAVITY_EARTH;
        float gZ = z / SensorManager.GRAVITY_EARTH;

        // gForce will be close to 1 when there is no movement.
        float gForce = FloatMath.sqrt(gX * gX + gY * gY + gZ * gZ);

        if (gForce > SHAKE_THRESHOLD_GRAVITY) {
            final long now = System.currentTimeMillis();
            // ignore shake events too close to each other (500ms)
            if (mShakeTimestamp + SHAKE_SLOP_TIME_MS > now) {
                return;
            }

            // reset the shake count after 3 seconds of no shakes
            if (mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now) {
                mShakeCount = 0;
            }

            mShakeTimestamp = now;
            mShakeCount++;

            mListener.onShake(mShakeCount);
        }
    }
}
}
同样,在这一点上,一切都按预期进行。但是,我不确定如何在ShakeDetector类中设置SHAKE_THRESHOLD_GRAVITY和SHAKE_COUNT_RESET_TIME_MS,以使用我在应用程序中已经设置的共享首选项。所有内容都在应用程序中配置,允许用户进入并为这两个设置选择不同的值,但我不确定如何将SharedReferences设置从活动传递到此类。我尝试了很多不同的方法,但都没有成功,我在网上似乎找不到任何详细的方法。这可能是很简单的事情,但我没有太多的运气弄明白

简而言之,我尝试在ShakeDetector类中创建另一个方法,例如setShakePreferences,然后在其中放入类似于以下内容的代码:

    public void setShakePreferences() {

    shake_sensitivity = myPrefs.getString(SHAKE_THRESHOLD_GRAVITY2, "2.7");
    shake_time_between = myPrefs.getString(SHAKE_COUNT_RESET_TIME_MS2, "3000");
    float shake_threshold_gravity = Float.valueOf(shake_sensitivity);
    int shake_count_reset_time_ms = Integer.valueOf(shake_time_between);

}
我尝试过以各种不同的方式传入SharedReferences,例如SetShakePreferenceSharedPreferences myPrefs,但是,我尝试过的让myPrefs实际包含SharedReferences的所有操作似乎都以myPrefs的空值结束。我在我的主要活动中有一些设置,这些设置是通过用户偏好控制的,我有一些类似于上面的方法,可以很好地工作。我只是不知道如何将myPrefs设置为ShakeDetector类中的实际SharedReferences值


请帮忙。解决方案的详细代码示例最能帮助我理解如何实现这一点。谢谢

在阅读了更多关于如何实现接口的内容后,我明白了这一点。当我弄明白它的时候,它其实很简单,我不知道为什么我一开始就没抓住它

基本上,我修改了onCreate以传递SharedReferences,如下所示,只是添加了this.myPrefs作为参数:

        // ShakeDetector initialization
    mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    mShakeDetector = new ShakeDetector();
    mShakeDetector.setOnShakeListener(new OnShakeListener() {

        @Override
        public void onShake(int count) {
            /*
             * The following method, "handleShakeEvent(count):" is a stub //
             * method you would use to setup whatever you want done once the
             * device has been shook.
             */
            handleShakeEvent(count);
        }
    }, this.myPrefs); // <<<--- ADDED IT HERE
然后,我必须修改ShakeDetector类中的setOnShakeListener,以接受myPrefs作为参数,并添加所有内容,以便它能够正确处理变量。以下是我最终得到的结果:

import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;
import android.util.Log;

public class ShakeDetector implements SensorEventListener {

/*
 * The gForce that is necessary to register as shake.
 * Must be greater than 1G (one earth gravity unit).
 * You can install "G-Force", by Blake La Pierre
 * from the Google Play Store and run it to see how
 *  many G's it takes to register a shake
 */
private static final String SHAKE_THRESHOLD_GRAVITY = "<replace this with the android:key value you have configured in you preferences XML file.>";
private static final String SHAKE_COUNT_RESET_TIME_MS = "<replace this with the android:key value you have configured in you preferences XML file.>";
private static final String SHAKE_SLOP_TIME_MS = "<replace this with the android:key value you have configured in you preferences XML file.>";

private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;
private SharedPreferences myPrefs;

public void setOnShakeListener(OnShakeListener listener, SharedPreferences myPrefs) {
    this.mListener = listener;
    this.myPrefs = myPrefs;
}

public interface OnShakeListener {
    public void onShake(int count);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // ignore
}

@Override
public void onSensorChanged(SensorEvent event) {

    if (mListener != null) {
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        float gX = x / SensorManager.GRAVITY_EARTH;
        float gY = y / SensorManager.GRAVITY_EARTH;
        float gZ = z / SensorManager.GRAVITY_EARTH;

        // gForce will be close to 1 when there is no movement.
        float gForce = FloatMath.sqrt(gX * gX + gY * gY + gZ * gZ);

        if (gForce > Float.parseFloat(myPrefs.getString(SHAKE_THRESHOLD_GRAVITY, "2.7F"))) {
            final long now = System.currentTimeMillis();
            // ignore shake events too close to each other (500ms)
            if (mShakeTimestamp + Integer.parseInt(myPrefs.getString(SHAKE_SLOP_TIME_MS, "500")) > now) {
                return;
            }

            // reset the shake count after 3 seconds of no shakes
            if (mShakeTimestamp + Integer.parseInt(myPrefs.getString(SHAKE_COUNT_RESET_TIME_MS, "3000")) < now) {
                mShakeCount = 0;
            }

            mShakeTimestamp = now;
            mShakeCount++;

            mListener.onShake(mShakeCount);
        }
    }
}
}
希望这对其他人有所帮助

import android.content.SharedPreferences;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.util.FloatMath;
import android.util.Log;

public class ShakeDetector implements SensorEventListener {

/*
 * The gForce that is necessary to register as shake.
 * Must be greater than 1G (one earth gravity unit).
 * You can install "G-Force", by Blake La Pierre
 * from the Google Play Store and run it to see how
 *  many G's it takes to register a shake
 */
private static final String SHAKE_THRESHOLD_GRAVITY = "<replace this with the android:key value you have configured in you preferences XML file.>";
private static final String SHAKE_COUNT_RESET_TIME_MS = "<replace this with the android:key value you have configured in you preferences XML file.>";
private static final String SHAKE_SLOP_TIME_MS = "<replace this with the android:key value you have configured in you preferences XML file.>";

private OnShakeListener mListener;
private long mShakeTimestamp;
private int mShakeCount;
private SharedPreferences myPrefs;

public void setOnShakeListener(OnShakeListener listener, SharedPreferences myPrefs) {
    this.mListener = listener;
    this.myPrefs = myPrefs;
}

public interface OnShakeListener {
    public void onShake(int count);
}

@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
    // ignore
}

@Override
public void onSensorChanged(SensorEvent event) {

    if (mListener != null) {
        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        float gX = x / SensorManager.GRAVITY_EARTH;
        float gY = y / SensorManager.GRAVITY_EARTH;
        float gZ = z / SensorManager.GRAVITY_EARTH;

        // gForce will be close to 1 when there is no movement.
        float gForce = FloatMath.sqrt(gX * gX + gY * gY + gZ * gZ);

        if (gForce > Float.parseFloat(myPrefs.getString(SHAKE_THRESHOLD_GRAVITY, "2.7F"))) {
            final long now = System.currentTimeMillis();
            // ignore shake events too close to each other (500ms)
            if (mShakeTimestamp + Integer.parseInt(myPrefs.getString(SHAKE_SLOP_TIME_MS, "500")) > now) {
                return;
            }

            // reset the shake count after 3 seconds of no shakes
            if (mShakeTimestamp + Integer.parseInt(myPrefs.getString(SHAKE_COUNT_RESET_TIME_MS, "3000")) < now) {
                mShakeCount = 0;
            }

            mShakeTimestamp = now;
            mShakeCount++;

            mListener.onShake(mShakeCount);
        }
    }
}
}