diff --git a/android/src/app/organicmaps/location/SensorHelper.java b/android/src/app/organicmaps/location/SensorHelper.java index 883f7ba395..ee3f2f17bb 100644 --- a/android/src/app/organicmaps/location/SensorHelper.java +++ b/android/src/app/organicmaps/location/SensorHelper.java @@ -5,67 +5,101 @@ import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; +import android.util.Log; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import app.organicmaps.MwmApplication; +import app.organicmaps.R; class SensorHelper implements SensorEventListener { - @Nullable + @NonNull private final SensorManager mSensorManager; @Nullable - private Sensor mRotation; - @SuppressWarnings("NotNullFieldNotInitialized") + private final Sensor mRotationVectorSensor; @NonNull private final MwmApplication mMwmApplication; + private final float[] mRotationMatrix = new float[9]; + private final float[] mRotationValues = new float[3]; + // Initialized with purposely invalid value. + private int mLastAccuracy = -42; + @Override public void onSensorChanged(SensorEvent event) { - if (!mMwmApplication.arePlatformAndCoreInitialized()) + // Here we can have events from one out of these two sensors: + // TYPE_GEOMAGNETIC_ROTATION_VECTOR + // TYPE_ROTATION_VECTOR + + if (mLastAccuracy != event.accuracy) + { + mLastAccuracy = event.accuracy; + switch (mLastAccuracy) + { + case SensorManager.SENSOR_STATUS_ACCURACY_HIGH: + break; + case SensorManager.SENSOR_STATUS_ACCURACY_MEDIUM: + Toast.makeText(mMwmApplication, + mMwmApplication.getString(R.string.compass_calibration_recommended), + Toast.LENGTH_LONG).show(); + break; + case SensorManager.SENSOR_STATUS_ACCURACY_LOW: + case SensorManager.SENSOR_STATUS_UNRELIABLE: + default: + Toast.makeText(mMwmApplication, + mMwmApplication.getString(R.string.compass_calibration_required), + Toast.LENGTH_LONG).show(); + } + } + + if (event.accuracy == SensorManager.SENSOR_STATUS_UNRELIABLE) return; - notifyInternal(event); - } + SensorManager.getRotationMatrixFromVector(mRotationMatrix, event.values); + SensorManager.getOrientation(mRotationMatrix, mRotationValues); - private void notifyInternal(@NonNull SensorEvent event) - { - if (event.sensor.getType() == Sensor.TYPE_ROTATION_VECTOR) { - float[] rotMatrix = new float[9]; - SensorManager.getRotationMatrixFromVector(rotMatrix, event.values); - SensorManager.remapCoordinateSystem(rotMatrix, - SensorManager.AXIS_X, SensorManager.AXIS_Y, rotMatrix); - - float[] rotVals = new float[3]; - SensorManager.getOrientation(rotMatrix, rotVals); - - // rotVals indexes: 0 - yaw, 2 - roll, 1 - pitch. - LocationHelper.INSTANCE.notifyCompassUpdated(rotVals[0]); - } + // mRotationValues indexes: 0 - yaw (azimuth), 1 - pitch, 2 - roll. + LocationHelper.INSTANCE.notifyCompassUpdated(mRotationValues[0]); } @Override - public void onAccuracyChanged(Sensor sensor, int accuracy) {} + public void onAccuracyChanged(Sensor sensor, int accuracy) + { + Log.w("onAccuracyChanged", "Sensor " + sensor.getStringType() + " has changed accuracy to " + accuracy); + // This method is called _only_ when accuracy changes. To know the initial startup accuracy, + // and to show calibration warning toast if necessary, we check it in onSensorChanged(). + // Looks like modern Androids can send this event after starting the sensor. + } SensorHelper(@NonNull Context context) { mMwmApplication = MwmApplication.from(context); mSensorManager = (SensorManager) mMwmApplication.getSystemService(Context.SENSOR_SERVICE); - if (mSensorManager != null) - mRotation = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); + Sensor sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_ROTATION_VECTOR); + if (sensor == null) + { + Log.w("SensorHelper", "WARNING: There is no ROTATION_VECTOR sensor, requesting GEOMAGNETIC_ROTATION_VECTOR"); + sensor = mSensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR); + if (sensor == null) + Log.w("SensorHelper", "WARNING: There is no GEOMAGNETIC_ROTATION_VECTOR sensor, device orientation can not be calculated"); + } + // Can be null in rare cases on devices without magnetic sensors. + mRotationVectorSensor = sensor; } void start() { - if (mRotation != null && mSensorManager != null) - mSensorManager.registerListener(this, mRotation, SensorManager.SENSOR_DELAY_UI); + if (mRotationVectorSensor != null) + mSensorManager.registerListener(this, mRotationVectorSensor, SensorManager.SENSOR_DELAY_UI); } void stop() { - if (mSensorManager != null) + if (mRotationVectorSensor != null) mSensorManager.unregisterListener(this); } } diff --git a/data/strings/strings.txt b/data/strings/strings.txt index 8f2fa736ce..5ce99b5647 100644 --- a/data/strings/strings.txt +++ b/data/strings/strings.txt @@ -6178,6 +6178,90 @@ zh-Hans = 指南针校准 zh-Hant = 指南針校準 + [compass_calibration_recommended] + comment = Toast text when compass calibration may improve the correctness of the current position arrow + tags = android + en = Improve arrow direction by moving the phone in a figure-eight motion to calibrate the compass. + ar = قم بتحسين اتجاه السهم عن طريق تحريك الهاتف في حركة على شكل ثمانية لمعايرة البوصلة. + be = Палепшыце кірунак стрэлкі, перамяшчаючы тэлефон у выглядзе васьмёркі, каб адкалібраваць компас. + bg = Подобрете посоката на стрелката, като движите телефона с движение тип "осмица", за да калибрирате компаса. + ca = Milloreu la direcció de la fletxa movent el telèfon amb un moviment de vuit per calibrar la brúixola. + cs = Zlepšete směr šipky pohybem telefonu do osmičky a zkalibrujte kompas. + da = Forbedre pilens retning ved at bevæge telefonen i en ottetalsbevægelse for at kalibrere kompasset. + de = Verbessern Sie die Pfeilrichtung, indem Sie das Telefon in einer Achterbewegung bewegen, um den Kompass zu kalibrieren. + el = Βελτιώστε την κατεύθυνση των βελών μετακινώντας το τηλέφωνο με μια κίνηση σχήματος οκτώ για να βαθμονομήσετε την πυξίδα. + es = Mejora la dirección de la flecha moviendo el teléfono en forma de ocho para calibrar la brújula. + et = Parandage noole suunda, liigutades telefoni kaheksakäigulise liigutusega, et kalibreerida kompass. + eu = Hobetu geziaren norabidea telefonoa zortzi irudiko mugimenduan mugituz iparrorratza kalibratzeko. + fa = برای کالیبره کردن قطب نما، جهت پیکان را با حرکت دادن تلفن در یک حرکت شکل هشت بهبود دهید. + fi = Paranna nuolien suuntaa liikuttamalla puhelinta kahdeksikon suuntaisesti kompassin kalibroimiseksi. + fr = Améliorez la direction de la flèche en déplaçant le téléphone en huit pour calibrer la boussole. + he = שפר את כיוון החץ על ידי הזזת הטלפון בתנועה של שמונה כדי לכייל את המצפן. + hu = Javítsa a nyíl irányát a telefon nyolcas mozgatásával az iránytű kalibrálásához. + id = Perbaiki arah panah dengan menggerakkan ponsel dalam gerakan angka delapan untuk mengkalibrasi kompas. + it = Migliorare la direzione della freccia muovendo il telefono con un movimento a otto per calibrare la bussola. + ja = 携帯電話を8の字に動かしてコンパスを較正することで、矢印の方向を改善します。 + ko = 나침반을 보정하기 위해 휴대폰을 8자 모양으로 움직여 화살표 방향을 개선하세요. + lt = Patobulinkite rodyklės kryptį judindami telefoną aštuoniukės judesiu, kad kompasas būtų sukalibruotas. + mr = कंपास कॅलिब्रेट करण्यासाठी फोनला आकृती-आठ मोशनमध्ये हलवून बाणाची दिशा सुधारा. + nb = Forbedre pilretningen ved å bevege telefonen i en åttetallsbevegelse for å kalibrere kompasset. + nl = Verbeter de richting van de pijl door de telefoon in een achtvormige beweging te bewegen om het kompas te kalibreren. + pl = Popraw kierunek strzałki, poruszając telefonem w ruchu w kształcie ósemki, aby skalibrować kompas. + pt = Melhore a direcção das setas movendo o telemóvel num movimento em forma de oito para calibrar a bússola. + pt-BR = Melhore a direção da seta movendo o telefone em um movimento em forma de oito para calibrar a bússola. + ro = Îmbunătățiți direcția săgeții prin mișcarea telefonului într-o mișcare în opt pentru a calibra busola. + ru = Улучшите направление стрелки, перемещая телефон восьмеркой, чтобы откалибровать компас. + sk = Zlepšite smer šípok pohybom telefónu v tvare osmičky, aby ste kalibrovali kompas. + sv = Förbättra pilens riktning genom att flytta telefonen i en åttarörelse för att kalibrera kompassen. + th = ปรับปรุงทิศทางลูกศรโดยขยับโทรศัพท์เป็นเลขแปดเพื่อปรับเทียบเข็มทิศ + tr = Pusulayı kalibre etmek için telefonu sekiz şeklinde hareket ettirerek ok yönünü iyileştirin. + uk = Покращіть напрямок стрілки, повернувши телефон вісімкою, щоб відкалібрувати компас. + vi = Cải thiện hướng mũi tên bằng cách di chuyển điện thoại theo chuyển động hình số tám để hiệu chỉnh la bàn. + zh-Hans = 通过以八字形运动移动手机来改善箭头方向,以校准罗盘。 + zh-Hant = 通過以八字形移動手機來校準指南針來改善箭頭方向 + + [compass_calibration_required] + comment = Toast text when compass calibration may improve the correctness of the current position arrow + tags = android + en = Move the phone in a figure-eight motion to calibrate the compass and fix the arrow direction on the map. + ar = حرك الهاتف في حركة على شكل ثمانية لمعايرة البوصلة وإصلاح اتجاه السهم على الخريطة. + be = Перамяшчайце тэлефон у выглядзе васьмёркі, каб адкалібраваць компас і зафіксаваць кірунак стрэлкі на карце. + bg = Преместете телефона с движение тип "осмица", за да калибрирате компаса и да фиксирате посоката на стрелката върху картата. + ca = Moveu el telèfon amb un moviment de vuit per calibrar la brúixola i fixar la direcció de la fletxa al mapa. + cs = Pohybem telefonu do osmičky zkalibrujte kompas a zafixujte směr šipky na mapě. + da = Bevæg telefonen i en ottetalsbevægelse for at kalibrere kompasset og fastgøre pilens retning på kortet. + de = Bewegen Sie das Telefon in einer Achterbewegung, um den Kompass zu kalibrieren und die Pfeilrichtung auf der Karte festzulegen. + el = Μετακινήστε το τηλέφωνο με μια κίνηση σχήματος οκτώ για να βαθμονομήσετε την πυξίδα και να καθορίσετε την κατεύθυνση του βέλους στο χάρτη. + es = Mueve el teléfono en forma de ocho para calibrar la brújula y fijar la dirección de la flecha en el mapa. + et = Liigutage telefoni kaheksakandilise liigutusega, et kalibreerida kompass ja määrata noole suund kaardil. + eu = Mugitu telefonoa zortzi irudiko mugimenduan iparrorratza kalibratzeko eta geziaren norabidea mapan finkatzeko. + fa = تلفن را به شکل هشت حرکت دهید تا قطب نما را کالیبره کنید و جهت پیکان را روی نقشه ثابت کنید. + fi = Liikuta puhelinta kahdeksikon suuntaisella liikkeellä kompassin kalibroimiseksi ja nuolen suunnan määrittämiseksi kartalla. + fr = Déplacez le téléphone en huit pour calibrer la boussole et fixer la direction de la flèche sur la carte. + he = הזז את הטלפון בתנועה של דמות שמונה כדי לכייל את המצפן ולתקן את כיוון החץ במפה. + hu = Mozgassa a telefont egy nyolcas mozdulattal az iránytű kalibrálásához és a nyíl irányának rögzítéséhez a térképen. + id = Gerakkan ponsel dengan gerakan angka delapan untuk mengkalibrasi kompas dan memperbaiki arah panah pada peta. + it = Muovere il telefono con un movimento a otto per calibrare la bussola e fissare la direzione della freccia sulla mappa. + ja = 携帯電話を8の字に動かしてコンパスを校正し、地図上の矢印の方向を固定します。 + ko = 휴대폰을 8자 모양으로 움직여 나침반을 보정하고 지도에서 화살표 방향을 수정합니다. + lt = Judinkite telefoną aštuoniukės formos judesiu, kad sukalibruotumėte kompasą ir žemėlapyje nustatytumėte rodyklės kryptį. + mr = होकायंत्र कॅलिब्रेट करण्यासाठी आणि नकाशावर बाणाची दिशा निश्चित करण्यासाठी फोनला आकृती-आठ मोशनमध्ये हलवा. + nb = Beveg telefonen i en åttetallsbevegelse for å kalibrere kompasset og fikse pilretningen på kartet. + nl = Beweeg de telefoon in een achtvormige beweging om het kompas te kalibreren en de richting van de pijl op de kaart vast te stellen. + pl = Przesuń telefon ruchem w kształcie ósemki, aby skalibrować kompas i ustalić kierunek strzałki na mapie. + pt = Mova o telemóvel num movimento em forma de oito para calibrar a bússola e fixar a direcção da seta no mapa. + pt-BR = Mova o telefone em um movimento em forma de oito para calibrar a bússola e fixar a direção da seta no mapa. + ro = Mișcați telefonul într-o mișcare în formă de opt pentru a calibra busola și a fixa direcția săgeții pe hartă. + ru = Двигайте телефон восьмеркой, чтобы откалибровать компас и зафиксировать направление стрелки на карте. + sk = Pohybom telefónu v tvare osmičky kalibrujte kompas a zafixujte smer šípky na mape. + sv = Flytta telefonen i en åttarörelse för att kalibrera kompassen och fastställa pilens riktning på kartan. + th = ขยับโทรศัพท์เป็นเลขแปดเพื่อปรับเทียบเข็มทิศและกำหนดทิศทางลูกศรบนแผนที่ + tr = Pusulayı kalibre etmek ve haritadaki ok yönünü sabitlemek için telefonu sekiz şeklinde hareket ettirin. + uk = Рухайте телефон вісімкою, щоб відкалібрувати компас і зафіксувати напрямок стрілки на карті. + vi = Di chuyển điện thoại theo chuyển động hình số tám để hiệu chỉnh la bàn và cố định hướng mũi tên trên bản đồ. + zh-Hans = 以八字动作移动手机,校准罗盘,并在地图上固定箭头方向。 + zh-Hant = 以 8 字形移動手機以校準指南針並固定地圖上的箭頭方向 + [downloader_update_all_button] comment = Update all button text tags = android,ios