我正在为计算机科学的最终论文开发一个应用程序,我需要收集并记录加速度计数据.我需要一整天才能获得它,因此存在严重的电池限制(例如,我无法启动屏幕).此外,这不是一个以市场为目标的应用程序,因此如果需要,做一些严重的黑客攻击,甚至低级C/C++编码是完全可以接受的.
众所周知,在许多设备上,加速计事件的监听器在屏幕关闭时停止生成事件(关于此问题的一些链接:http://code.google.com/p/android/issues/detail?id = 3708,加速度计当Droid/Nexus One屏幕关闭时,即使使用WakeLock,也会停止传送样本.我已经彻底搜索了一些替代方案,其中一些包括对我的设备不起作用的解决方法(LG P990,股票ROM).
所以会发生这样的事情:当你在服务中为android加速计传感器注册事件监听器时,它可以正常运行,直到屏幕关闭.我已经尝试在IntentService上的服务上注册eventListener,试图获取WakeLocks.关于唤醒锁,我可以验证服务是否仍在运行,观察LOGcat输出,但似乎加速度计进入睡眠模式.某些链接中提供的解决方法之一是使用IntentService的线程定期取消注册和重新注册事件侦听器,如下面的代码片段所示
synchronized private static PowerManager.WakeLock getLock(Context context) {
if (lockStatic==null) {
PowerManager mgr=(PowerManager)context.getSystemService(Context.POWER_SERVICE);
lockStatic = mgr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,NAME);
lockStatic.setReferenceCounted(true);
}
return(lockStatic);
}
@Override
protected void onHandleIntent(Intent intent) {
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
synchronized (this) {
boolean run = true;
while (run){
try {
wait(1000);
getLock(AccelerometerService.this).acquire();
sensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
sensorManager.unregisterListener(this);
sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
Log.d("Accelerometer service", "tick!");
} catch (Exception e) {
run = false;
Log.d("Accelerometer service", "interrupted; cause: " …
Run Code Online (Sandbox Code Playgroud) (编辑:我在我的增强现实框架中添加了最好的工作方法,现在也考虑了陀螺仪,这使它再次更加稳定:DroidAR框架)
我编写了一个TestSuite来了解如何根据您获得的数据计算旋转角度SensorEventListener.onSensorChanged()
.我真的希望你能完成我的解决方案,以帮助那些像我一样遇到同样问题的人.这是代码,我想你会在阅读之后理解它.
随意改变它,主要的想法是实现几种方法将方向角发送到opengl视图或任何其他需要它的目标.
方法1到4正在工作,它们直接将rotationMatrix发送到OpenGl视图.
方法6现在也可以工作,但我没有解释为什么必须进行旋转yx z ..
所有其他方法都没有工作或有问题,我希望有人知道让他们工作.我认为最好的方法是方法5,如果它可行,因为它是最容易理解,但我不确定它是多么有效.完整的代码没有优化,所以我建议不要在项目中使用它.
这里是:
/**
* This class provides a basic demonstration of how to use the
* {@link android.hardware.SensorManager SensorManager} API to draw a 3D
* compass.
*/
public class SensorToOpenGlTests extends Activity implements Renderer,
SensorEventListener {
private static final boolean TRY_TRANSPOSED_VERSION = false;
/*
* MODUS overview:
*
* 1 - unbufferd data directly transfaired from the rotation matrix to the
* modelview matrix
*
* 2 …
Run Code Online (Sandbox Code Playgroud) 我正在开发汽车加速跟踪应用程序.我使用标准加速度计,事先在特定位置校准.
然后,假设手机的方向没有改变,我将加速度计数据记录了指定的时间并计算了移动参数,其中一个是测试结束时的汽车速度.
它在一条平直的水平道路上工作得相当好:几个百分点的误差.
但后来我发现,在API级别10中有一个叫做的虚拟传感器TYPE_LINEAR_ACCELERATION
,据我所知,它必须做我需要的东西:过滤重力,方向变化 - 所以我可以使用它并获得纯粹的线性加速度移动设备.
但在现实生活中......
我做了一个简单的应用程序,做了一点测试:
//public class Accelerometer implements SensorEventListener { ...
public void onSensorChanged(SensorEvent se)
{
if(!active)
return;
lastX = se.values[SensorManager.DATA_X];
lastY = se.values[SensorManager.DATA_Y];
lastZ = se.values[SensorManager.DATA_Z];
long now = System.currentTimeMillis();
interval = now - lastEvetn;
lastEvetn = now;
out.write(Float.toString(lastX) + ";" +
Float.toString(lastY) + ";" +
Float.toString(lastZ) + ";" +
Long.toString(interval) + "\n");
}
Run Code Online (Sandbox Code Playgroud)
我用以下参数绑定一个监听器:
mSensorManager.registerListener(linAcc,
mSensorManager.getDefaultSensor(Sensor.TYPE_LINEAR_ACCELERATION),
SensorManager.SENSOR_DELAY_GAME);
Run Code Online (Sandbox Code Playgroud)
它工作正常,但是当我分析数据转储时,计算速度,比如V = V0 + AT
,V0 = 0
首先,然后 - 之前的间隔速度,A = …
我需要有关如何检测Android设备的移动量的建议.假设我已将手机放在桌子或床上,然后如果有人敲击桌子或坐在或躺在床上,那么我想检测Android设备的移动.
实际上我知道android有运动传感器API但是我不知道使用哪种传感器以及哪种传感器类型最适合这种类型的运动检测.
如果有人可以分享一些基本的演示代码,我会很高兴.
我有一个非常简单的Android应用程序:在活动中我有一个按钮,我启动/停止OrientationListener.但是,在取消注册后,在ddms中我仍然可以看到线程android.hardware.SensorManager $ SensorThread](正在运行).
注册码:
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
List<Sensor> sensors = sensorManager.getSensorList(Sensor.TYPE_ORIENTATION);
if (sensors.size() > 0)
{
sensor = sensors.get(0);
running = sensorManager.registerListener(sensorEventListener, sensor, SensorManager.SENSOR_DELAY_FASTEST);
}
Run Code Online (Sandbox Code Playgroud)
和取消注册:
try
{
if (sensorManager != null && sensorEventListener != null)
{
sensorManager.unregisterListener(sensorEventListener,sensor);
running = false;
}
}
catch (Exception e)
{
Log.w(TAG, e.getMessage());
}
Run Code Online (Sandbox Code Playgroud)
该unregisterListener()
方法确实被执行,但它不会经常杀死传感器线程,这会使电池继续运行和耗尽.几个小时后,我的应用程序列出了20-30%的电池消耗.怎么可能?如何确保传感器未注册?我没有在logcat中得到任何异常或任何错误.我尝试在服务中运行监听器 - 同样的事情.
我发现很难获得有关哪些Android手机有陀螺仪的整合信息,或者是否有Android手机都有这种传感器.我读到了至少有一个6轴加速度计的一些(特别是三星)手机型号,但我也读到这与真正的陀螺仪不同.
所以我的问题是:
Sensor.TYPE_GYROSCOPE
自API 3以来可用的Android API )任何参考如链接,规格等都非常感谢,当然会得到回报.:-)
谢谢你的帮助!
我正在创建一个地图应用程序,包括显示您面向哪个方向的位置箭头,如下所示:
我SensorManager.getOrientation()
使用第一个返回值:azimuth 直接从中获取方向.当手机被按住以使屏幕指向地平线以上时,并且在纵向中,箭头正常工作.然而:
下面精心构造和科学的图像显示了我的意思(蓝色是用户面对的,红色是箭头方向,屏幕大致面向用户的脸,Google地图完全符合我的要求):
(请注意,使用谷歌地图,如果自动旋转关闭,它就无法成功执行列表中的最后两个操作.但我甚至还没有达到那个阶段.一次只做一件事.)
它似乎只是使用Y轴指向方向,如下所示:http://developer.android.com/reference/android/hardware/SensorEvent.html,当我希望它使用Z轴指向的反向,大部分时间,和手机平坦时的Y. 但是,考虑到getOrientation()
返回的值,我必须编写复杂的案例来解决一些问题,而面向电话的用例是无法解决的.我确信有一种更简单的方法.
这是我的代码(其中lastAcceleration和lastMagneticField都来自内部传感器):
float[] rotationMatrix = new float[9];
if(SensorManager.getRotationMatrix(rotationMatrix, null, lastAcceleration, lastMagneticField)){
float[] orientMatrix = new float[3];
SensorManager.getOrientation(rotationMatrix, orientMatrix);
orientation = orientMat[0]*180/(float)Math.PI;
}
Run Code Online (Sandbox Code Playgroud)
我究竟做错了什么?有更简单的方法吗?
编辑:只是为了澄清,我假设用户正在将设备放在他们面前,屏幕指向他们.除此之外,我显然无法分辨是否只有其中一个旋转.此外,我正在使用用户移动时的动作,但这是在他们静止的时候.
同样的问题但更好地解释
这个问题被认为是正确的,但它完全没有,我用我的旧设备ZTE尝试了它并且大部分时间工作,但现在我有三星Galazy A5 2016并且它不起作用,在LG G3上都没有.
事情正在尝试使用Accelerometer
,有些Sensors
我必须能够检测到我在视频上制作的那两个动画中的任何一个.
有两个动作:
我让你来决定,并说服了我什么是更好的选择和EASIER一个做的,具有更好的我的意思是,在大多数设备的工作原理.
我希望我的视图仅在横向模式下旋转,顺时针和逆时针旋转.
我读到了android <2.2的唯一逆时针方向,这不是问题,我的App现在是+2.2.
我修改我的清单以捕获配置更改
android:configChanges="keyboardHidden|orientation"
Run Code Online (Sandbox Code Playgroud)
我重写我的活动以捕获配置更改
@Override
public void onConfigurationChanged(Configuration newConfig) {
Run Code Online (Sandbox Code Playgroud)
而且我知道如何抓住方向
Display display = ((WindowManager) getSystemService(WINDOW_SERVICE)).getDefaultDisplay();
int rot = display.getRotation();
Run Code Online (Sandbox Code Playgroud)
但是......我不知道如何触发适当的横向方向,我这样做:
if (rot == Surface.ROTATION_90 || rot == Surface.ROTATION_270){
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
}
Run Code Online (Sandbox Code Playgroud)
但总是旋转到counterclocwise :-(
如何设置左右横向?
编辑
如果我在清单中设置方向:
机器人:screenOrientation = "风景"
活动的布局始终保持"左侧景观",我想要在左右景观之间进行更改:S
[编辑] @Claudio的回答给了我一个关于如何过滤掉异常值的非常好的提示.我确实想开始在我的数据上使用卡尔曼滤波器.所以我改变了下面的示例数据,以便它具有微妙的变化噪声,这不是那么极端(我也看到了很多).如果有其他人可以给我一些关于如何在我的数据上使用PyKalman的方向,这将是很好的.[/编辑]
对于机器人项目,我试图用相机跟踪空中的风筝.我正在使用Python进行编程,并在下面粘贴了一些嘈杂的位置结果(每个项目都包含一个日期时间对象,但为了清晰起见,我将它们留下了).
[ # X Y
{'loc': (399, 293)},
{'loc': (403, 299)},
{'loc': (409, 308)},
{'loc': (416, 315)},
{'loc': (418, 318)},
{'loc': (420, 323)},
{'loc': (429, 326)}, # <== Noise in X
{'loc': (423, 328)},
{'loc': (429, 334)},
{'loc': (431, 337)},
{'loc': (433, 342)},
{'loc': (434, 352)}, # <== Noise in Y
{'loc': (434, 349)},
{'loc': (433, 350)},
{'loc': (431, 350)},
{'loc': (430, 349)},
{'loc': (428, 347)},
{'loc': (427, 345)},
{'loc': (425, 341)},
{'loc': (429, 338)}, # <== Noise …
Run Code Online (Sandbox Code Playgroud)