2013-05-29 85 views
3

我想要在手機靜止2秒時發生操作。我搜索了谷歌和堆棧溢出周圍的年齡。我發現「Accelerometer DidAccelerate」已被折舊,並且CoreMotion是替代產品。我所看到的一切都與「搖晃」動作有關。我試過閱讀蘋果的文檔,但它只是讓我困惑!如何檢測手機何時放下

基本上,我希望應用程序能夠檢測到手機上的g力已經在一定的時間內保持在一個小的極限內(建議手機已放在桌子上或其他東西上)調用並實例化或使應用程序執行某些操作。

任何幫助將不勝感激。

+0

在[apple docs]中有示例代碼(http://developer.apple.com/library/ios/#documentation/EventHandling/Conceptual/EventHandlingiPhoneOS/motion_event_basics/motion_event_basics.html) –

回答

4

它與Simple iPhone motion detect中描述的問題類似。蘋果文檔中描述了CMMotionManager的基本設置,如Mike Pollard在他的評論中所述。我特別推薦Handling Processed Device Motion Data部分。

然後你需要的是CMDeviceMotion.userAcceleration其中包含沒有重力的純粹加速度。

CMMotionManager *motionManager = [[CMMotionManager alloc] init]; 
// UPDATE: set interval to 0.02 sec 
motionManager.deviceMotionUpdateInterval = 1.0/50.0; 
[motionManager startDeviceMotionUpdatesToQueue:[NSOperationQueue mainQueue] 
     withHandler:^(CMDeviceMotion *deviceMotion, NSError *error) { 
    CMAcceleration userAcceleration = deviceMotion.userAcceleration; 
    double totalAcceleration = sqrt(userAcceleration.x * userAcceleration.x + 
     userAcceleration.y * userAcceleration.y + userAcceleration.z * userAcceleration.z); 
    // UPDATE: print debug information 
    NSLog (@"total=%f x=%f y=%f z=%f", totalAcceleration, userAcceleration.x, userAcceleration.y, userAcceleration.z); 
    // if(totalAcceleration < SOME_LIMIT) ... 

然後繼續按照codeplasma描述in his answer above

另外請注意,如果由於外部加速度的原因,在地下,公交車等場合使用該解決方案可能不準確。

+0

感謝您的幫助,但我有問題(一如既往)。我沒有收到任何錯誤,但它不起作用。我已經告訴它執行的行動沒有被執行。我試圖讓SOME_LIMIT大到100,但無濟於事。你會建議我做什麼?我可能忘記了什麼或做錯了什麼? –

+0

確保處理程序完全被調用:某些NSLog語句只是爲了安全起見。 'totalAcceleration'的平均值應該是1(以_g_度量)。因此,打印'accelerometerData.acceleration'和'totalAcceleration'來查看值。告訴我,但它是在歐洲的夜晚,所以可能我們會明天看到:-) – Kay

+0

早上好:)我該怎麼做?我只熟悉簡單的'NSLog(@「test」)'種類的東西(我試過'NSLog(@「%f」,totalAcceleration)''但我認爲它不對,它抱怨「使用未申報的標識符「)。無論如何,我試着將'NSLog(@「test」)'放入'// do something'(在codeplasma的代碼中)位(在codeplasma的代碼中),但是沒有在控制檯中顯示出來,但是當我把它放入像'ViewDidLoad'這樣的地方。 –

4

你可以做這樣的事情:

CMMotionManager *mManager = [[CMMotionManager alloc] init]; 

if ([mManager isAccelerometerAvailable] == YES) { 
    __block float lastActivityBefore = 0.0; 
    [mManager setAccelerometerUpdateInterval:0.1]; 
    [mManager startAccelerometerUpdatesToQueue:[NSOperationQueue mainQueue] withHandler:^(CMAccelerometerData *accelerometerData, NSError *error) { 

     double totalAcceleration = sqrt(accelerometerData.acceleration.x * accelerometerData.acceleration.x + accelerometerData.acceleration.y * accelerometerData.acceleration.y + accelerometerData.acceleration.z * accelerometerData.acceleration.z); 
     if(totalAcceleration < SOME_LIMIT) 
      lastActivityBefore = lastActivityBefore + 0.1; 
     else 
      lastActivityBefore = 0.0; 

     if(lastActivityBefore >= 2.0) 
     { 
      //do something 
     } 
    }]; 
} 

加速度計會顯示一些最小的加速,即使你的設備穩定,所以你應該以確定SOME_LIMIT值進行測試。

另外要注意的是,你應該只有一個實例CMMotionManager類,所以你最好把它放在你的AppDelegate中並初始化它一次。

+0

這是行不通的,因爲'accelerometerData.acceleration'包含重力 – Kay

+0

感謝codeplasma的幫助。經過一些調整後,它表現出色。另一個upvote –