stwierdzam, że czułość będzie się zmieniać w zależności od urządzenia. to, co wydawało się całkowicie akceptowalnym wykrywaniem wstrząsów w nexusie galaktyki, musi być znacznie bardziej gwałtownym wstrząsem w galaktyce III z tą samą aplikacją. jeśli sprawię, że będzie mniej czuły dla tego urządzenia, będzie zbyt wrażliwy na czymś takim jak Nexus. hmmmmmmm.
topwik
Dlaczego należy pomnożyć przez 10000 i czy w mianowniku powinny znajdować się nawiasy?
Yoda,
3
To działa, ale możesz chcieć sprawdzić matematykę, aby obliczyć przyspieszenie: Wartości zwracane przez czujniki są wm / s ^ 2 - nie ma potrzeby dzielenia przez czas. Możesz również przyjrzeć się, jak mnożysz wektory przyspieszenia.
// Get a sensor manager to listen for shakes
mSensorMgr =(SensorManager) getSystemService(SENSOR_SERVICE);// Listen for shakesSensor accelerometer = mSensorMgr.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);if(accelerometer !=null){
mSensorMgr.registerListener(this, accelerometer,SensorManager.SENSOR_DELAY_NORMAL);}
SensorEventListener metody do przesłonięcia:
@Overridepublicvoid onSensorChanged(SensorEventevent){if(event.sensor.getType()==Sensor.TYPE_ACCELEROMETER){long curTime =System.currentTimeMillis();if((curTime - mLastShakeTime)> MIN_TIME_BETWEEN_SHAKES_MILLISECS){float x =event.values[0];float y =event.values[1];float z =event.values[2];double acceleration =Math.sqrt(Math.pow(x,2)+Math.pow(y,2)+Math.pow(z,2))-SensorManager.GRAVITY_EARTH;Log.d(APP_NAME,"Acceleration is "+ acceleration +"m/s^2");if(acceleration > SHAKE_THRESHOLD){
mLastShakeTime = curTime;Log.d(APP_NAME,"Shake, Rattle, and Roll");}}}}@Overridepublicvoid onAccuracyChanged(Sensor sensor,int accuracy){// Ignore}
Kiedy skończysz
// Stop listening for shakes
mSensorMgr.unregisterListener(this);
Ostatnio sprawdzałem filtr dolnoprzepustowy [alfa * prąd + (1-alfa) * poprzedni], a 0,9 (alfa?) Jest całkowicie zależne od częstotliwości próbkowania czujnika np. Dla 100ms alfa powinno wynosić 0,146 ish i nie można zakładać wszystkie urządzenia używają dokładnie tej samej częstotliwości czujnika.
escape-llc
Jestem całkiem nowy w Androidzie. Czy możesz mi pomóc zrozumieć, dlaczego onResume i onPause są wywoływane, gdy ekran się trzęsie? Nie rozumiem tej części.
Pikamander2
1
@ Pikamander2 Musimy zarejestrować słuchacza w sensorManager, zrobiliśmy to w onResume i wyrejestrowaliśmy słuchacza w onPause, więc gdy użytkownik opuści aplikację, ten odbiornik nie będzie działał, dopóki użytkownik nie wróci do aplikacji.
classShakeDetector:SensorEventListener{privatevar mListener:OnShakeListener?=nullprivatevar mShakeTimestamp:Long=0privatevar mShakeCount =0
fun setOnShakeListener(listener:OnShakeListener?){
mListener = listener
}interfaceOnShakeListener{
fun onShake(count:Int)}override fun onAccuracyChanged(
sensor:Sensor,
accuracy:Int){// ignore}override fun onSensorChanged(event:SensorEvent){if(mListener !=null){
val x =event.values[0]
val y =event.values[1]
val z =event.values[2]
val gX = x /SensorManager.GRAVITY_EARTH
val gY = y /SensorManager.GRAVITY_EARTH
val gZ = z /SensorManager.GRAVITY_EARTH
// gForce will be close to 1 when there is no movement.
val gForce:Float= sqrt(gX * gX + gY * gY + gZ * gZ)if(gForce > SHAKE_THRESHOLD_GRAVITY){
val now =System.currentTimeMillis()// ignore shake events too close to each other (500ms)if(mShakeTimestamp + SHAKE_SLOP_TIME_MS > now){return}// reset the shake count after 3 seconds of no shakesif(mShakeTimestamp + SHAKE_COUNT_RESET_TIME_MS < now){
mShakeCount =0}
mShakeTimestamp = now
mShakeCount++
mListener!!.onShake(mShakeCount)}}}
companion object{/*
* The gForce that is necessary to register as shake.
* Must be greater than 1G (one earth gravity unit).
* You can install "G-Force", by Blake La Pierre
* from the Google Play Store and run it to see how
* many G's it takes to register a shake
*/privateconst val SHAKE_THRESHOLD_GRAVITY =2.7fprivateconst val SHAKE_SLOP_TIME_MS =500privateconst val SHAKE_COUNT_RESET_TIME_MS =3000}}
Twoja główna aktywność
classMainActivity:AppCompatActivity(){// The following are used for the shake detectionprivatevar mSensorManager:SensorManager?=nullprivatevar mAccelerometer:Sensor?=nullprivatevar mShakeDetector:ShakeDetector?=nulloverride fun onCreate(savedInstanceState:Bundle?){super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
initSensor()}override fun onResume(){super.onResume()// Add the following line to register the Session Manager Listener onResume
mSensorManager!!.registerListener(
mShakeDetector,
mAccelerometer,SensorManager.SENSOR_DELAY_UI
)}override fun onPause(){// Add the following line to unregister the Sensor Manager onPause
mSensorManager!!.unregisterListener(mShakeDetector)super.onPause()}private fun initSensor(){// ShakeDetector initialization// ShakeDetector initialization
mSensorManager = getSystemService(SENSOR_SERVICE)asSensorManager
mAccelerometer = mSensorManager!!.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
mShakeDetector =ShakeDetector()
mShakeDetector!!.setOnShakeListener(object:OnShakeListener{override fun onShake(count:Int){/*
* The following method, "handleShakeEvent(count):" is a stub //
* method you would use to setup whatever you want done once the
* device has been shook.
*/Toast.makeText(this@MainActivity, count.toString(),Toast.LENGTH_SHORT).show()}})}}
Na koniec dodaj ten kod do Manifestów, aby upewnić się, że telefon ma akcelerometr
Próbuję wykryć, czy użytkownik trzykrotnie potrząsnął telefonem, a następnie odtworzył dźwięk ...
Si8
Kod taki (i wiele innych podobnych przykładów) wykrywa tylko długotrwały okres przyspieszenia, niekoniecznie wstrząsania. Nie wykryje ruchu tam iz powrotem, który jest w rzeczywistości przyspieszeniem, po którym następuje ujemne przyspieszenie.
escape-llc
1
Nie zapomnij dodać tego kodu do MainActivity.java:
Odpowiedzi:
Z punktu widzenia kodu musisz zaimplementować SensorListener:
Będziesz musiał nabyć SensorManager:
I zarejestruj ten czujnik z wybranymi flagami:
W metodzie onSensorChange () określasz, czy jest to wstrząs, czy nie:
Próg drgań definiuje się jako:
Istnieją również inne metody wykrywania drgań. spójrz na ten link. (Jeśli ten link nie działa lub jest martwy, zajrzyj do tego archiwum WWW ).
Spójrz na ten przykład dotyczący odbiornika wykrywania wstrząsów w systemie Android.
Uwaga:
SensorListener
jest przestarzały. możemy użyćSensorEventListener
zamiast tego. Oto krótki przykład użycia SensorEventListener.Dzięki.
źródło
Google bardzo pomaga .
źródło
java.lang.SecurityException: Requires VIBRATE permission
SensorManager.DATA_[X,Y,Z]
są teraz przestarzałe.Możesz również zajrzeć do biblioteki Seismic
źródło
Jest już wiele rozwiązań na to pytanie, ale chciałem zamieścić takie, które:
Oto takie rozwiązanie:
Aby zainicjować licznik czasu:
SensorEventListener
metody do przesłonięcia:Kiedy skończysz
źródło
Ponieważ SensorListener jest przestarzały , użyj następującego kodu:
Następnie:
Pytanie z pełnymi szczegółami można znaleźć tutaj:
Android: Chcę tym potrząsnąć
źródło
Możesz użyć Seismic :
Zobacz kod tutaj:
https://github.com/square/seismic/blob/master/library/src/main/java/com/squareup/seismic/ShakeDetector.java
źródło
To jest
Kotlin
i używaćSensorEventListener
Utwórz nową klasę
ShakeDetector
Twoja główna aktywność
Na koniec dodaj ten kod do Manifestów, aby upewnić się, że telefon ma akcelerometr
źródło
Wykonaj następujące czynności:
Umieść to w metodzie onCreate.
A teraz główna część.
źródło
Nie zapomnij dodać tego kodu do
MainActivity.java
:MainActivity.java
Albo dam ci link do tych rzeczy.
źródło