使用摇一摇功能开启不同的活动

Posted

技术标签:

【中文标题】使用摇一摇功能开启不同的活动【英文标题】:Using the Shake Feature to open different activities 【发布时间】:2019-01-07 13:36:29 【问题描述】:

我有一个链接到 4 个不同活动(页面)的主页。我已经使用SensorEventListener 实现了摇动功能,它响应正确,但我现在只能用它来打开一个活动,例如:我可以让它摇一次来打开一个活动,或者摇两次来打开一个活动但不能同时使用这两个 if 语句。

我尝试过使用带边界的 if 和 else 语句,因为我知道如何设置摇动次数,但我不明白如何让程序检测到完全等待我做多少次摇动后再执行任务。

 private final SensorEventListener sensorListener = new SensorEventListener() 

    @Override
    public void onSensorChanged(SensorEvent event) 

        Intent tts = new Intent(context, ttsScreen.class);
        Intent stt = new Intent(context, sttScreen.class);
        Intent cbb = new Intent(context, cbbScreen.class);
        Intent ocr = new Intent(context, ocrScreen.class);

        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        acelLast = acelValue;
        acelValue = (float) Math.sqrt((double) (x*x + y*y + z*z));
        float difference = acelValue - acelLast;
        shake = shake * 0.9f + difference;

        if(shake > 12 && shake < 24 ) 
            startActivity(tts);
        
        else if (shake > 24 && shake < 36) 
            startActivity(stt);
        
        else if (shake > 36 && shake < 48) 
            startActivity(cbb);
        
        else if (shake > 48) 
            startActivity(ocr);
        


    

在我的onCreate 方法中,我有以下内容:

 sm = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
 sm.registerListener(sensorListener,sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);

 acelValue = SensorManager.GRAVITY_EARTH;
 acelLast = SensorManager.GRAVITY_EARTH;
 shake = 0.00f;

目前它将始终打开startActivity(tts)。我不确定我需要采取什么方法,但我在想可能是一个计时器或其他东西,以便它在打开活动之前完全检查我做了多少次摇晃。或者 if/else 方法不是正确的方法?

【问题讨论】:

【参考方案1】:

免责声明:我不是 android 开发人员,对此没有经验。我还没有测试我的解决方案

在用户停止摇晃手机之前,请勿拨打startActivity()。您可以通过查看加速度的最后几个差异来发现这一点。如果它足够低以至于不再算作晃动,那么最后您可以使用正确的 Intent 调用 startActivity。

private final SensorEventListener sensorListener = new SensorEventListener() 
    private float differenceMedian = 0f;

    @Override
    public void onSensorChanged(SensorEvent event) 

        Intent tts = new Intent(context, ttsScreen.class);
        Intent stt = new Intent(context, sttScreen.class);
        Intent cbb = new Intent(context, cbbScreen.class);
        Intent ocr = new Intent(context, ocrScreen.class);

        float x = event.values[0];
        float y = event.values[1];
        float z = event.values[2];

        acelLast = acelValue;
        acelValue = (float) Math.sqrt((double) (x*x + y*y + z*z));
        float difference = acelValue - acelLast;
        shake = shake * 0.9f + difference; // will increase shake as long as user continues to shake (I think?)

        // differenceMedian will relatively slowly drop towards 0 when difference stays low
        differenceMedian =  (difference + differenceMedian ) /2; 

        if(differenceMedian < 1) // depends. try to adjust the 1 here
            if(shake > 12 && shake <= 24 )  // please notice <= because what if shake is exactly 24? same for following else-ifs.
                startActivity(tts);
            
            else if (shake > 24 && shake <= 36) 
                startActivity(stt);
            
            else if (shake > 36 && shake <= 48) 
                startActivity(cbb);
            
            else if (shake > 48) 
                startActivity(ocr);
            
        
    

编辑:正如 Gabe 指出的那样,在多次调用 onSensorChanged() 时差异必须非常小,以确保用户确实停止摇晃手机

【讨论】:

关闭。两件事-加速度是加速度值,而不是速度。通过加速度计值寻找最小速度是行不通的。相反,您希望等到几个事件的差异接近 0。为什么有几个事件?因为在方向改变期间它也会接近 0,但这并不会结束抖动。 另外,我假设这些是已经考虑了重力的加速度值,否则你总是期望 9.8m/s^2 的加速度 是的,这很有意义,谢谢@Gabe。将进行编辑 好吧,让我将我在onCreate 方法上的代码添加到主线程。 @GabeSechan 查看编辑。请注意,有很多方法可以检查差异历史。我使用这个是为了可读性,因为它会(或多或少地)慢慢下降到零,所以如果startActivity() 仍然被调用得太早或太晚,你可以很好地调整阈值。 (differenceMedian 永远不会达到绝对零。)

以上是关于使用摇一摇功能开启不同的活动的主要内容,如果未能解决你的问题,请参考以下文章

(IOS)摇一摇功能

H5摇一摇为啥有的手机不好使

微信小程序 摇一摇

如何理解微信公会平台摇一摇软件中的iBeacon技术

shake.js实现微信摇一摇功能

iOS之摇一摇功能实现