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