0

我正在尝试构建一个简单的关卡应用程序。我想要的是当设备完全平坦(加速度计的 x,y 值几乎为 0)时,设备会在 5 秒后而不是立即发出哔声。

我正在使用以下代码,但我不知道我必须更改什么才能让声音在 5 秒后始终正常工作,而不是随机或立即工作。有人可以帮助我吗?

public void onSensorChanged(SensorEvent event) {
  x = event.values[0];
  y = event.values[1];
  long actualTime = System.currentTimeMillis();
  if(x > -0.1 && x < 0.1 && y > -0.1 && y < 0.1) {
    if(actualTime - lastUpdate >= 5000) {
      return;
    }
    lastUpdate = actualTime;
    try {
      AssetFileDescriptor afd = getAssets().openFd("beep.wav");
      mMediaplayer = new MediaPlayer();
      mMediaplayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
      afd.close();
      mMediaplayer.prepare();
      mMediaplayer.start();
      mMediaplayer.setOnCompletionListener(new OnCompletionListener() {
        public void onCompletion(MediaPlayer mp) {
          //mp.setLooping(false);
          mp.stop();
          mp.release();
        }
      });
    } catch(Exception e) {
      e.printStackTrace();
    }
  }
}
4

2 回答 2

0

我认为 Timer 很适合你。可能是这样的,每次检测到运动时取消计时器并启动新计时器:

在您的活动中定义您的计时器(并确保在您离开活动时取消它)

Timer lastTouchedTimer = null;

然后像这样更改您的 onSensorChanged:

  public void onSensorChanged(SensorEvent event) {
        float x = event.values[0];
        float y = event.values[1];

        if(x > -0.1 && x < 0.1 && y > -0.1 && y < 0.1) {
            if (lastTouchedTimer == null) {
                lastTouchedTimer = new Timer();
            } else
                lastTouchedTimer.cancel();
            }
            lastTouchedTimer.schedule(new TimerTask() {
                @Override
                public void run() {
                    try {
                        AssetFileDescriptor afd = getAssets().openFd("beep.wav");
                        mMediaplayer = new MediaPlayer();
                        mMediaplayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                        afd.close();
                        mMediaplayer.prepare();
                        mMediaplayer.start();
                        mMediaplayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                    public void onCompletion(MediaPlayer mp) {
                                //mp.setLooping(false);
                                mp.stop();
                                mp.release();
                            }
                        });
                    } catch(Exception e) {
                        e.printStackTrace();
                    }
                }
            }, 5000);
        }
    }

这是我在示例活动中使用的活动。

package com.example.test;

import android.app.Activity;
import android.content.res.AssetFileDescriptor;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.media.MediaPlayer;
import android.os.Bundle;

import java.util.Timer;
import java.util.TimerTask;

public class MyActivity extends Activity {
    Timer lastTouchedTimer;
    MediaPlayer mMediaplayer;
    /**
     * Called when the activity is first created.
     */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        SensorEventListener newListener = new SensorEventListener() {
            @Override
            public void onSensorChanged(SensorEvent sensorEvent) {
                float x = sensorEvent.values[0];
                float y = sensorEvent.values[1];

                if(x > -0.1 && x < 0.1 && y > -0.1 && y < 0.1) {
                    if (lastTouchedTimer == null) {
                        lastTouchedTimer = new Timer();
                    } else
                        lastTouchedTimer.cancel();
                }
                lastTouchedTimer.schedule(new TimerTask() {
                    @Override
                    public void run() {
                        try {
                            AssetFileDescriptor afd = getAssets().openFd("beep.wav");
                            mMediaplayer = new MediaPlayer();
                            mMediaplayer.setDataSource(afd.getFileDescriptor(), afd.getStartOffset(), afd.getLength());
                            afd.close();
                            mMediaplayer.prepare();
                            mMediaplayer.start();
                            mMediaplayer.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
                                public void onCompletion(MediaPlayer mp) {
                                    //mp.setLooping(false);
                                    mp.stop();
                                    mp.release();
                                }
                            });
                        } catch(Exception e) {
                            e.printStackTrace();
                        }
                    }
                }, 5000);
            }

            @Override
            public void onAccuracyChanged(Sensor sensor, int i) {
                //To change body of implemented methods use File | Settings | File Templates.
            }
        };
    }
}

它使用一个非常简单的 xml 文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              android:orientation="vertical"
              android:layout_width="fill_parent"
              android:layout_height="fill_parent"
        >
    <TextView
            android:layout_width="fill_parent"
            android:layout_height="wrap_content"
            android:text="Heallo World, MyActivity"
            />
</LinearLayout>
于 2013-04-07T00:15:56.543 回答
0

使用处理程序。当设备变平时(该代码播放声音)从现在开始向处理程序发布一条延迟消息 5 秒。让处理程序在收到消息时播放声音。

这是“在 Y 秒内做 X”的标准方式。

于 2013-04-06T23:18:05.303 回答