簡體   English   中英

僅在用戶移動時收集傳感器數據

[英]Collect sensor data only when user is moving

我想在用戶移動/手機不固定時跟蹤傳感器數據(加速度計、陀螺儀)。

我能夠做的事情:

  1. 使用 Sensor Listener 偵聽傳感器數據
        sensorManager = getSystemService(SENSOR_SERVICE) as SensorManager
        
        val accelerometerSensor = 
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    
        sensorManager.registerListener(
                accSensor,
                accelerometerSensor,
                SensorManager.SENSOR_DELAY_NORMAL
            )
  1. 運行始終在后台運行的前台服務以跟蹤傳感器,即使該應用程序從最近的應用程序中被刷掉
serviceIntent = Intent(context, SensorService::class.java)
context.startForegroundService(serviceIntent)
  1. 使用偵聽啟動完成事件的廣播偵聽器重新啟動應用程序后立即啟動服務。

但我無法:

  1. 在設備停止移動時停止收集傳感器數據的傳感器服務。
  2. 當用戶的設備開始移動並收集傳感器數據時啟動傳感器(未運行)。

從系統接收 Motion 開始和 Motion 結束通知/回調的方式可能是什么,以便我們可以決定開始/結束前台服務。

評論太大了,所以我會把它作為答案發布。 這在某種程度上是一個答案,但沒有證據,只是我的經驗。

我絕不是 Android 方面的專家。 但總的來說,我對傳感器了解一兩件事。 最重要的是它們總是處於活動狀態(如果沒有完全關閉),並且總是有一些噪音 所以

  1. 不能100%肯定地說是否有任何運動。 相反,您需要收集所有事件,選擇閾值自行決定 (可能您希望匯總來自多個傳感器的測量結果以做出決定,甚至考慮測量的歷史記錄 - 例如,如果用戶在崎嶇不平的道路上駕駛汽車,則噪音會在很長一段時間內更高)。
  2. 如果相應的代碼將由操作系統或您的服務執行,則能耗幾乎沒有區別。 但是有更多的機會使用您的代碼自定義閾值、聚合和其他邏輯。 這就是為什么我相信操作系統將 API 保持在最低限度,並且沒有moving starts / moving stops類的事件。
  3. 唯一消耗能量高於最小值的是您的代碼 沒有其他人,但您的代碼決定是否通過持續的通知流來惹惱用戶。

所以,考慮聚合策略和閾值,如果沒有通過閾值就不要顯示通知,並且讓你的代碼快速(這樣它不會消耗太多能量)。 你已經完成了......或多或少......因為這些決定並不容易做出。 來自大公司的許多應用程序未能在所有情況下都正確。 只需安裝幾個計步器應用程序,您就會看到它們都會顯示不同的步數。

什么是“移動”的閾值取決於您的應用程序,因此沒有很多現成的選項(例如,您是否關心用戶是否搖晃手機,或者只是他們是否在汽車中移動了幾條街?)。

有檢測運動開始/停止的傳感器類型。 這里 它們是否適合您的應用取決於您的應用。

  1. 停止傳感器:

TYPE_STATIONARY_DETECT在用戶 5 秒內沒有移動時觸發事件。 傾聽它,並用它來停止您的服務。 如果你想要比這更快,你必須自己做。

  1. 啟動傳感器

TYPE_MOVEMENT_DETECT與靜止檢測相反,當用戶移動 5 秒時觸發。 如果 5 秒延遲不是交易破壞者,您可以監聽此消息以啟動服務備份。

如果您希望您的動作將應用程序從睡眠中喚醒,則SIGNIFICANT_MOTION類型也可以使用,但我從來沒有很幸運地找到該傳感器類型的“重要”類型。

如果您的運動不是這兩件事之一——持續 5 秒的運動或任何引起“重要”標志的東西——那么你將需要自己實現開始和停止,因為傳感器無法檢測到什么運動如果尚未開始並檢測運動,則開始 例如我使用了類似這個偽代碼的東西

class MotionSensorMediator:
    
    enum state=[waiting, active]

    def ctor():
        state = waiting

    def onSensorEvent(SensorEvent event):
        switch state:
             case waiting:
                  checkMovementThreshold(event)
                  break
             case active:
                  checkMovementThreshold(event)
                  sendToListener(event)
                  break

    def checkMovementThreshold(SensorEvent event):
        results = //some distance calculations
        if result > threshold && state == waiting:
             state = active
        else if result < threshold && state == active:
             state = waiting

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM