【发布时间】:2018-10-11 06:15:56
【问题描述】:
我正在开发一个使用加速度传感器在屏幕上移动球的应用程序。我使用 Canvas 绘制了球,每次绘图“触摸”屏幕末端时,都会显示一条消息,告诉用户对应的一侧。
如下图所示:
Toast 显示一条消息:“向左移动”,从西班牙语翻译成英语。
您看到消息显示正确。
点击手机返回键出现问题:
您的症状:
- 图像信息会根据手机的方向再次显示。
- 消息显然是循环的,也就是说,即使您不移动消息也是随机的。
Toast 消息的行为就好像它们仍在上一个活动中一样,也就是说,我已经离开了。有时它只在我移动手机时显示警告,有时它没有随机移动几次。
主屏幕的手动按钮是将视图引导至第一张带球照片的活动。
虽然在此视图中按下返回按钮,但即使我返回应用程序屏幕,消息也会继续显示。
消除此问题的唯一方法是从应用程序库中删除应用程序,并且过程再次相同。
我强调只有当我进入该视图并返回时才会出现问题,在此之前不会发生。
我附上主要代码:
btnManual.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent intent = new Intent(MainActivity.this, MovimientoActivity.class);
startActivity(intent);
}
曾经在 MovimientoActivity.class 中
public class MovimientoActivity extends AppCompatActivity{
private DrawView view; //Class where the ball is created with the accelerometer
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Toast.makeText(this, "Cliclo-onCreate", Toast.LENGTH_SHORT).show();
DisplayMetrics displaymetrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(displaymetrics);
view = new DrawView(this, displaymetrics); //Se llama a esa vista
view.setBackgroundColor(Color.parseColor("#F5B041"));
setContentView(view);
//Definimos usar toda la pantalla
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
WindowManager.LayoutParams.FLAG_FULLSCREEN);
}
}
});
Class DrawView.java
public class DrawView extends View implements SensorEventListener {
Cliente cliente = null;
Sensor accelerometer = null;
SensorManager manager;
static String TAG = "DrawView";
int BLOQUEO_ARRIBA = 0;
int BLOQUEO_ABAJO = 0;
int BLOQUEO_DERECHO = 0;
int BLOQUEO_IZQUIERDO = 0;
private Bitmap pelota;
public int ALTURA;
public int ANCHO;
DisplayMetrics displaymetrics;
Punto posicion = new Punto();
final int X = 0;
final int Y = 1;
final int Z = 2;
public DrawView(Context context, DisplayMetrics displaymetrics) {
super(context);
this.displaymetrics = displaymetrics;
manager = (SensorManager) context.getSystemService(Context.SENSOR_SERVICE);
if (manager.getSensorList(Sensor.TYPE_ACCELEROMETER).size() != 0) {
accelerometer = manager.getSensorList(
Sensor.TYPE_ACCELEROMETER).get(0);
if (!manager.registerListener(this, accelerometer,
SensorManager.SENSOR_DELAY_FASTEST)) {
}
}
try {
AssetManager assetManager = context.getAssets();
InputStream inputStream;
inputStream = assetManager.open("bola_2.png");
pelota = BitmapFactory.decodeStream(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
// Obtenemos las medidas de la pantalla
ALTURA = displaymetrics.heightPixels;
ANCHO = displaymetrics.widthPixels;
}
@Override
public void onSensorChanged(SensorEvent event) {
// Modificamos la posicion de la bola en el eje X
posicion.x -= event.values[X];
//Comprobamos si se sale de la pantalla, y en ese caso, modificamos su valor
if (posicion.x < 0) {
if(BLOQUEO_IZQUIERDO == 0){
Log.i(TAG, "onSensorChanged: izquierdo");
Toast.makeText(getContext(), "Movimiento a la izquierda", Toast.LENGTH_SHORT).show();
BLOQUEO_DERECHO = 0;
BLOQUEO_ARRIBA = 0;
BLOQUEO_ABAJO = 0;
BLOQUEO_IZQUIERDO++;
}
posicion.x = 0;
}else if (posicion.x > this.ANCHO -pelota.getWidth()) {
if(BLOQUEO_DERECHO == 0){
Log.i(TAG, "onSensorChanged: derecho");
Toast.makeText(getContext(), "Movimiento a la derecha", Toast.LENGTH_SHORT).show();
BLOQUEO_IZQUIERDO = 0;
BLOQUEO_ARRIBA = 0;
BLOQUEO_ABAJO = 0;
BLOQUEO_DERECHO++;
}
posicion.x = this.ANCHO - pelota.getWidth();
}
//Modificamos la posicion de la bola en el eje Y
posicion.y += event.values[Y];
//Comprobamos si se sale de la pantalla, y en ese caso, modificamos su valor
if (posicion.y < 0) {
if(BLOQUEO_ARRIBA == 0){
Log.i(TAG, "onSensorChanged: arriba");
Toast.makeText(getContext(), "Movimiento hacia arriba", Toast.LENGTH_SHORT).show();
BLOQUEO_DERECHO = 0;
BLOQUEO_IZQUIERDO = 0;
BLOQUEO_ABAJO = 0;
BLOQUEO_ARRIBA++;
}
posicion.y = 0;
}else if (posicion.y > this.ALTURA - pelota.getHeight()) {
if(BLOQUEO_ABAJO == 0){
Log.i(TAG, "onSensorChanged: abajo");
Toast.makeText(getContext(), "Movimiento hacia abajo", Toast.LENGTH_SHORT).show();
BLOQUEO_DERECHO = 0;
BLOQUEO_ARRIBA = 0;
BLOQUEO_IZQUIERDO = 0;
BLOQUEO_ABAJO++;
}
posicion.y = this.ALTURA - pelota.getHeight();
}
//Método invalidate para llamar onDraw
invalidate();
}
@Override
public void onDraw(Canvas canvas) {
canvas.drawBitmap(pelota, posicion.x, posicion.y, null);
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
我声明为 BLOQUEO 的变量是因为我只需要传感器通知我一次事件,所以如果它被满足我会做另一个动作,直到另一端被“触摸”。
到目前为止,这就是问题所在。最后,我的目标是防止传感器在球的屏幕被移除后继续工作,或者如果出现问题,它会在后台停止工作。
感谢您给予我的帮助。
【问题讨论】: