屏幕关闭时 Android 加速计不工作

2024-04-08

我正在为计算机科学的期末论文开发一个应用程序,我需要收集和记录加速度计数据。我需要使用一整天,因此电池存在严重限制(例如,我无法让屏幕保持打开状态)。此外,这不是一个针对市场的应用程序,因此如果需要的话,进行一些严重的黑客攻击,甚至是低级 C/C++ 编码是完全可以接受的。

众所周知,在许多设备上,当屏幕关闭时,加速度计事件的侦听器会停止生成事件(有关此问题的一些链接:http://code.google.com/p/android/issues/detail?id=3708 http://code.google.com/p/android/issues/detail?id=3708 , 当 Droid/Nexus One 屏幕关闭时,即使使用 WakeLock,加速计也会停止提供样本 https://stackoverflow.com/questions/2143102/accelerometer-stops-delivering-samples-when-the-screen-is-off-on-droid-nexus-one)。我彻底搜索了一些替代方案,其中一些包括不适用于我的设备(LG P990,库存 ROM)的解决方法。

那么发生的事情是这样的: 当您在服务中为 Android 加速计传感器注册事件侦听器时,它会正常工作,直到屏幕关闭。我已经尝试在服务上注册 eventListener,在 IntentService 上尝试获取 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: " + e.getMessage());


            }
        }
    }       
}


@Override
public void onSensorChanged(SensorEvent event) {
    Log.d("accelerometer event received", "xyz: "+ event.values[0] + "," + event.values[1] + "," +  event.values[2]);
}

这确实使得每次我们注销/注册监听器时都会调用 onSensorChange 。问题是,无论我摇动设备,接收到的事件始终包含相同的值。

所以,基本上我的问题是:(请耐心等待,我即将完成:P)

  1. 是否可以在不注册事件侦听器的情况下对加速度计硬件进行低级访问(C/C++ 方法)?

  2. 还有其他解决方法或黑客吗?

  3. 任何拥有更新手机的人都可以测试一下固件3.0及以上版本中问题是否仍然存在吗?

[UPDATE]

不幸的是,这似乎是某些手机的一个错误。更多细节在我的回答中。


基本上是我手机的问题。其他用户报告说,他们的手机也会出现这种情况,这些手机来自不同品牌但具有相同的 Android 版本。其他人根本没有问题 - 强烈表明这不是 Android 的库存版本的问题,而是来自每个公司的硬件驱动程序的实现。

我需要提供恒定的加速度计数据,但无法让加密狗为我测量该数据 - 我有一个带有蓝牙和加速度计的 Arduino,所以我可以实现这个解决方案。因此,我决定手机的临时解决方案是让屏幕打开(变暗)并忽略电池消耗。稍后我将使用另一部在屏幕关闭的情况下工作的 Android 手机来执行电池使用情况测试。

有关该错误的更多信息

我做了更多研究,找到了其他 Android 用户的报告,我想也许我明白发生了什么。包含手机传感器驱动程序的库 libsensors.so 不是由 Google 开发的,而是由每个手机供应商开发的 - 当然,因为每个手机都有自己特定的硬件。 Google 只提供了一个 C 头文件,以便开发人员知道他们必须实现什么。在这些驱动程序的某些实现中,开发人员只需在屏幕关闭时关闭加速度计,从而阻止传感器事件侦听器接收新事件。

我还用 CyanogenMod RC7.2 对此进行了测试,但它也不起作用,因为加速度计驱动程序是 LG 原装的。

与LG HR部门交换电子邮件

我给LG P990的开发者发了一封邮件,终于得到了一些具体的答复!这对于像我这样在 Android 上遇到这些问题的人来说可能会有很大帮助。我写了以下问题

你好!我正在撰写计算机科学论文,目前我 正在从加速计硬件获取数据。到现在我才发现 当屏幕关闭时,加速度计不会发送事件,所以 即使我从我的一个程序中获取唤醒锁,我也可以 验证我的程序是否仍在运行(通过 LOGcat 输出)但没有 加速度计事件出来了。我必须把屏幕调暗(我 无法承受,电池耗尽太快)开始接收 再次加速计事件。我也尝试通过本机 C 访问它 代码,注册加速度计事件,但结果是 同样,加速度计没有抛出任何值,即使我是 旋转我的设备。所以我想知道我是否可以直接访问 使用本机代码连接到硬件,无需注册到 听众。这可能吗?如果是这样,您能否进一步提供一些 建议?我将非常感谢任何帮助!马丁

对于我收到的回复:

亲爱的马丁, 我们收到了开发人员的答复。团队。他们说你 手机屏幕关闭时无法获取加速度计事件。因为 HAL 层没有实现 sysFS 路径来获取 H/W 事件,例如 加速度计,并且没有公共 API 来获取事件。谢谢。最好的 问候。 (肖恩·金)

然后我发回一封电子邮件,除其他外,说我认为这是一个错误,因为在获取唤醒锁时应该有权访问所有硬件:

[...]我问这个问题是因为我有一些朋友也有 具有相同姜饼版本但来自其他版本的 Android 手机 手机品牌,其中一些报告称他们收到了来自 屏幕关闭时的加速度计。我读过一些 论坛上发现这个错误 - 我认为它是一个错误,因为当我获得一个 唤醒锁我希望进行一些处理 - 取决于 供应商为其手机实施的传感器驱动程序。是 这些驱动程序有可能被更新吗? bug 会在某个时候得到纠正吗?这将对我的工作有很大帮助 正在进行的工作 [...]

然后我收到了这个答案:

据我从 Dev 了解到。团队,这不是错误。那是无限的 这款手机是因为 H/W 架构。我们需要重新设计HAL 架构和设备驱动程序来支持您的请求。但是,正如你 知道由于缺乏资源而这太困难了。我们正在努力 我们竭尽全力帮助您,但我们无法支持您的请求,因为我 提及。 (肖恩·金)

所以他们显然知道这一点,但并没有试图纠正它,因为要么他们不认为这是一个错误 - 我仍然坚信这是一个逻辑缺陷 - 或者他们没有时间/资源来纠正它。

底线如果您的手机在屏幕关闭时不发送加速度计事件,请尝试更新固件。如果这不能解决问题,并且您确实想做一些严重的黑客攻击,请重新实现您的硬件层 - 提示:这可能与 libsensors.so 有关。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

屏幕关闭时 Android 加速计不工作 的相关文章

  • 如何在红米手机上通过应用程序图标显示徽章数量?

    我可以使用以下代码在三星设备上使用应用程序图标显示徽章计数
  • 如何设置itemTouchHelper选择性滑动?

    所以我在 recyclerview rv 上实现了这个 itemtouchhelper simple 回调 现在 在这个 rv 中 我根据内容类型将 2 种布局设置为一行 因此 当我在 rv 上设置此 touchhelper 时 它正在这两
  • Android 视图展开动画

    我正在尝试编辑这些来源 https github com gabrielemariotti androiddev tree master AnimationTest创建一个适用于我所有视图的简单函数 Override public void
  • Android 中的 XmlPullParser 陷入困境

    经过多个小时的搜索和调试后 我仍然停留在同一个地方 并且 Eclipse 没有帮助我 我试图解析这个 RSS 提要 http fr espnf1 com rss motorsport story feeds 0 xml type 2 这很简
  • 将文本视图包裹在图像视图周围

    晚上好 我正在尝试将文本包裹在图像视图中 就像这里提出的问题一样 Textview 环绕 View https stackoverflow com questions 3626750 textview wrap around view 在风
  • 如何防止 Activity 在后退操作时重新加载

    我有连接到互联网以获取数据的应用程序 我可以多层次访问数据 假设我从第 3 级开始 在第 4 级我决定返回 每当我按回之前的活动时 就会从互联网重新加载数据 有可能阻止这种情况吗 我尝试以单顶模式运行该活动 将数据加载代码移至 single
  • 使用反向无限滚动添加到 ListView 时保持滚动位置

    我正在构建一个类似聊天的 Android 应用程序 类似于环聊 为此 我使用垂直 ListViewstackFromBottom true and transcriptMode normal 该列表按从较旧的消息 顶部 到较新的消息 底部
  • 如何使用RecyclerView.State保存RecyclerView滚动位置?

    我有一个关于 Android 的问题RecyclerView State http developer android com reference android support v7 widget RecyclerView State h
  • Android 可检查子菜单选项

    所以我有一个用于选项菜单项的子菜单 我想要一个可检查条目的列表 用户可以根据需要选择 取消选择多个条目 我无法解决的唯一问题是如何防止单击其中一个复选框时关闭选项菜单 我看到 PerformShortcut 有一个 FLAG PERFORM
  • GSON:自定义对象反序列化

    好吧 我编辑了这个问题 因为它不够清楚 Edit 2 更新了 JSON 文件 我在 Android 应用程序中使用 GSON 我需要解析来自服务器的 JSON 文件 而且有点太复杂了 我不想让我的对象结构太重 所以我想简化内容 所以我的对象
  • 适用于 Droid 手机的数学或 LaTeX 引擎 [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 Android 手机有可用的数学或 LaTeX 引擎吗 我最喜欢的抽认卡应用程序 AnyMemo 似乎
  • 如何通过代码设置Fragment标签?

    我还没有找到类似的东西setTag String tagName 方法中的Fragment班级 唯一的方法是设置Fragment我发现的标签是通过做FragmentTransaction并传递标签名称作为参数 这是显式设置的唯一方法吗Fra
  • Android 视图上的动态气泡

    任何人都可以如何在Android布局上制作可点击的动态气泡 我的设计师对屏幕的想法如下 我的图像中所有气泡都是分配给用户的一组任务 气泡的标签根据任务而变化 1 1 根据我的项目要求 颜色和半径将根据 api 响应而变化 您能建议任何演示或
  • 为什么设置 MediaRecorder 时显示错误 IllegalStateException?

    我的代码设置 MediaRecorder 它显示行集质量错误 mMediaRecorder new MediaRecorder Step 1 Unlock and set camera to MediaRecorder mCamera st
  • 如何在Webview中保存用户名和密码

    目前 我还在学习Android开发的过程中 所以如果我的这个问题对你来说不太容易理解 请原谅 我创建了一个 Android 应用程序 它使用 RecyclerView 显示一组列表 当用户单击列表中的每个名称时 它会将它们重定向到一组不同的
  • Android - 保持用户登录状态

    我正在尝试使用 PHP 和 MySQLi for Android 进行登录 我不明白的是如何保持用户登录状态 我看到一个简单的教程 其中有人使用 SQLite 来保护信息 但我不知道这是否真的安全 如何保存用户信息以保持用户登录状态 谢谢
  • Android Windows:它们何时以及如何创建?

    我已经阅读了标准的 Windows 相关文档并翻阅了 一堆源代码 试图理解 Android 如何以及何时 窗口已创建 我相信我已经拥抱它并愿意 对其进行验证或更正 据我所知 只有两种方法可以获得 Window 对象的句柄 1 Activit
  • Android 图标与徽标

    The
  • Android应用程序中的模式输入

    我想知道是否有其他替代方案可以替代 Android 上平庸的 EditText 密码输入 是否有 API 或开源代码可以集成到我的应用程序中 类似于锁屏图案解锁 Intent 可能会返回哈希值 数字 字符串或代表用户输入的模式的任何内容 我
  • 如何检测文本是否可读?

    我想知道是否有一种方法可以告诉给定的文本是人类可读的 我所说的人类可读的意思是 它有一些含义 格式就像某人写的文章 或者至少是由软件翻译器生成的供人类阅读的文章 这是背景故事 最近我正在制作一个应用程序 允许用户将短文本上传到数据库 在部署

随机推荐