سنسورهای موقعیت

پلتفرم اندروید دو حسگر ارائه می‌دهد که به شما امکان می‌دهد موقعیت دستگاه را تعیین کنید: حسگر میدان ژئومغناطیسی و شتاب‌سنج. پلتفرم اندروید همچنین حسگری را ارائه می‌دهد که به شما امکان می‌دهد میزان نزدیکی صورت دستگاه به یک جسم را تعیین کنید (که به عنوان حسگر مجاورت شناخته می‌شود). حسگر میدان ژئومغناطیسی و حسگر مجاورت مبتنی بر سخت‌افزار هستند. اکثر تولیدکنندگان گوشی و تبلت یک حسگر میدان ژئومغناطیسی را در دستگاه خود قرار می‌دهند. به همین ترتیب، تولیدکنندگان گوشی معمولاً یک حسگر مجاورت را برای تعیین زمان نزدیک شدن گوشی به صورت کاربر (به عنوان مثال، در حین تماس تلفنی) در دستگاه خود قرار می‌دهند. برای تعیین جهت دستگاه، می‌توانید از داده‌های شتاب‌سنج و حسگر میدان ژئومغناطیسی دستگاه استفاده کنید.

توجه: حسگر جهت‌یابی در اندروید ۲.۲ (سطح API ۸) و نوع حسگر جهت‌یابی در اندروید ۴.۴W (سطح API ۲۰) منسوخ شده‌اند.

حسگرهای موقعیت برای تعیین موقعیت فیزیکی یک دستگاه در چارچوب مرجع جهانی مفید هستند. به عنوان مثال، می‌توانید از حسگر میدان ژئومغناطیسی در ترکیب با شتاب‌سنج برای تعیین موقعیت دستگاه نسبت به قطب شمال مغناطیسی استفاده کنید. همچنین می‌توانید از این حسگرها برای تعیین جهت دستگاه در چارچوب مرجع کاربرد خود استفاده کنید. حسگرهای موقعیت معمولاً برای نظارت بر حرکت یا جابجایی دستگاه، مانند لرزش، کج شدن یا رانش، استفاده نمی‌شوند (برای اطلاعات بیشتر، به حسگرهای حرکتی مراجعه کنید).

حسگر میدان ژئومغناطیسی و شتاب‌سنج، آرایه‌های چندبعدی از مقادیر حسگر را برای هر SensorEvent برمی‌گردانند. به عنوان مثال، حسگر میدان ژئومغناطیسی مقادیر قدرت میدان ژئومغناطیسی را برای هر یک از سه محور مختصات در طول یک رویداد حسگر ارائه می‌دهد. به همین ترتیب، حسگر شتاب‌سنج، شتاب اعمال شده به دستگاه را در طول یک رویداد حسگر اندازه‌گیری می‌کند. برای اطلاعات بیشتر در مورد سیستم‌های مختصاتی که توسط حسگرها استفاده می‌شوند، به سیستم‌های مختصات حسگر مراجعه کنید. حسگر مجاورتی برای هر رویداد حسگر، یک مقدار واحد ارائه می‌دهد. جدول 1 خلاصه‌ای از حسگرهای موقعیتی را که در پلتفرم اندروید پشتیبانی می‌شوند، نشان می‌دهد.

جدول 1. حسگرهای موقعیتی که در پلتفرم اندروید پشتیبانی می‌شوند.

سنسور داده‌های رویداد حسگر توضیحات Units of measure
TYPE_GAME_ROTATION_VECTOR SensorEvent.values[0] مولفه بردار چرخش در امتداد محور x (x * sin(θ/2)). بدون واحد
SensorEvent.values[1] مولفه بردار چرخش در امتداد محور y (y * sin(θ/2)).
SensorEvent.values[2] مولفه بردار چرخش در امتداد محور z (z * sin(θ/2)).
TYPE_GEOMAGNETIC_ROTATION_VECTOR SensorEvent.values[0] مولفه بردار چرخش در امتداد محور x (x * sin(θ/2)). بدون واحد
SensorEvent.values[1] مولفه بردار چرخش در امتداد محور y (y * sin(θ/2)).
SensorEvent.values[2] مولفه بردار چرخش در امتداد محور z (z * sin(θ/2)).
TYPE_MAGNETIC_FIELD SensorEvent.values[0] شدت میدان ژئومغناطیسی در امتداد محور x. میکروتسلا
SensorEvent.values[1] شدت میدان ژئومغناطیسی در امتداد محور y.
SensorEvent.values[2] شدت میدان ژئومغناطیسی در امتداد محور z.
TYPE_MAGNETIC_FIELD_UNCALIBRATED SensorEvent.values[0] قدرت میدان ژئومغناطیسی (بدون کالیبراسیون آهن سخت) در امتداد محور x. میکروتسلا
SensorEvent.values[1] قدرت میدان ژئومغناطیسی (بدون کالیبراسیون آهن سخت) در امتداد محور y.
SensorEvent.values[2] قدرت میدان ژئومغناطیسی (بدون کالیبراسیون آهن سخت) در امتداد محور z.
SensorEvent.values[3] تخمین بایاس آهن در امتداد محور x.
SensorEvent.values[4] تخمین بایاس آهن در امتداد محور y.
SensorEvent.values[5] تخمین بایاس آهن در امتداد محور z.
TYPE_ORIENTATION ۱ SensorEvent.values[0] آزیموت (زاویه حول محور z). مدارک تحصیلی
SensorEvent.values[1] گام (زاویه حول محور x).
SensorEvent.values[2] غلتش (زاویه حول محور y).
TYPE_PROXIMITY SensorEvent.values[0] فاصله از جسم. ۲ سانتی‌متر

۱ این حسگر در اندروید ۲.۲ (سطح API ۸) منسوخ شده است و این نوع حسگر در اندروید ۴.۴W (سطح API ۲۰) نیز منسوخ شده است. چارچوب حسگر روش‌های جایگزینی برای بدست آوردن جهت دستگاه ارائه می‌دهد که در بخش محاسبه جهت دستگاه مورد بحث قرار گرفته‌اند.

۲- برخی از حسگرهای مجاورتی فقط مقادیر دودویی ارائه می‌دهند که نشان‌دهنده‌ی نزدیکی و دوری هستند.

از حسگر بردار چرخش بازی استفاده کنید

حسگر بردار چرخش بازی مشابه حسگر بردار چرخش است، با این تفاوت که از میدان ژئومغناطیسی استفاده نمی‌کند. بنابراین محور Y به سمت شمال اشاره نمی‌کند، بلکه به سمت مرجع دیگری است. آن مرجع می‌تواند با همان مرتبه بزرگی که ژیروسکوپ حول محور Z حرکت می‌کند، تغییر جهت دهد.

از آنجا که حسگر بردار چرخش بازی از میدان مغناطیسی استفاده نمی‌کند، چرخش‌های نسبی دقیق‌تر هستند و تحت تأثیر تغییرات میدان مغناطیسی قرار نمی‌گیرند. اگر به شمال اهمیتی نمی‌دهید و بردار چرخش معمولی به دلیل وابستگی به میدان مغناطیسی با نیازهای شما مطابقت ندارد، از این حسگر در بازی استفاده کنید.

کد زیر نحوه دریافت نمونه‌ای از حسگر بردار چرخش پیش‌فرض بازی را نشان می‌دهد:

کاتلین

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR)

جاوا

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GAME_ROTATION_VECTOR);

از حسگر بردار چرخش ژئومغناطیسی استفاده کنید

حسگر بردار چرخش ژئومغناطیسی مشابه حسگر بردار چرخش است، اما از ژیروسکوپ استفاده نمی‌کند. دقت این حسگر کمتر از حسگر بردار چرخش معمولی است، اما مصرف برق آن کاهش می‌یابد. فقط در صورتی از این حسگر استفاده کنید که می‌خواهید اطلاعات چرخش را در پس‌زمینه و بدون استفاده زیاد از باتری جمع‌آوری کنید. این حسگر زمانی بیشترین کاربرد را دارد که همراه با دسته‌بندی استفاده شود.

کد زیر نحوه دریافت نمونه‌ای از حسگر بردار چرخش ژئومغناطیسی پیش‌فرض را نشان می‌دهد:

کاتلین

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR)

جاوا

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_GEOMAGNETIC_ROTATION_VECTOR);

محاسبه جهت دستگاه

با محاسبه جهت یک دستگاه، می‌توانید موقعیت دستگاه را نسبت به چارچوب مرجع زمین (به‌طور خاص، قطب شمال مغناطیسی) رصد کنید. کد زیر نحوه محاسبه جهت یک دستگاه را به شما نشان می‌دهد:

کاتلین

private lateinit var sensorManager: SensorManager
...
// Rotation matrix based on current readings from accelerometer and magnetometer.
val rotationMatrix = FloatArray(9)
SensorManager.getRotationMatrix(rotationMatrix, null, accelerometerReading, magnetometerReading)

// Express the updated rotation matrix as three orientation angles.
val orientationAngles = FloatArray(3)
SensorManager.getOrientation(rotationMatrix, orientationAngles)

جاوا

private SensorManager sensorManager;
...
// Rotation matrix based on current readings from accelerometer and magnetometer.
final float[] rotationMatrix = new float[9];
SensorManager.getRotationMatrix(rotationMatrix, null,
    accelerometerReading, magnetometerReading);

// Express the updated rotation matrix as three orientation angles.
final float[] orientationAngles = new float[3];
SensorManager.getOrientation(rotationMatrix, orientationAngles);

این سیستم با استفاده از حسگر میدان ژئومغناطیسی دستگاه در ترکیب با شتاب‌سنج دستگاه، زوایای جهت‌گیری را محاسبه می‌کند. با استفاده از این دو حسگر سخت‌افزاری، سیستم داده‌هایی را برای سه زاویه جهت‌گیری زیر ارائه می‌دهد:

  • آزیموت (درجه چرخش حول محور -z). این زاویه بین جهت قطب‌نمای فعلی دستگاه و شمال مغناطیسی است. اگر لبه بالایی دستگاه رو به شمال مغناطیسی باشد، آزیموت ۰ درجه است؛ اگر لبه بالایی رو به جنوب باشد، آزیموت ۱۸۰ درجه است. به طور مشابه، اگر لبه بالایی رو به شرق باشد، آزیموت ۹۰ درجه است و اگر لبه بالایی رو به غرب باشد، آزیموت ۲۷۰ درجه است.
  • گام (درجه چرخش حول محور x). این زاویه بین یک صفحه موازی با صفحه دستگاه و یک صفحه موازی با زمین است. اگر دستگاه را موازی با زمین نگه دارید به طوری که لبه پایینی آن به شما نزدیک‌تر باشد و لبه بالایی دستگاه را به سمت زمین کج کنید، زاویه گام مثبت می‌شود. کج کردن در جهت مخالف - دور کردن لبه بالایی دستگاه از زمین - باعث می‌شود زاویه گام منفی شود. محدوده مقادیر از ۹۰- درجه تا ۹۰ درجه است.
  • چرخش (درجه چرخش حول محور y). این زاویه بین یک صفحه عمود بر صفحه دستگاه و یک صفحه عمود بر زمین است. اگر دستگاه را موازی با زمین نگه دارید و لبه پایینی آن را به سمت خود نزدیک کنید و لبه سمت چپ دستگاه را به سمت زمین کج کنید، زاویه چرخش مثبت می‌شود. کج کردن در جهت مخالف - حرکت لبه سمت راست دستگاه به سمت زمین - باعث می‌شود زاویه چرخش منفی شود. محدوده مقادیر از ۱۸۰- درجه تا ۱۸۰ درجه است.

توجه: تعریف رول سنسور تغییر کرده است تا منعکس کننده اکثریت قریب به اتفاق پیاده‌سازی‌ها در اکوسیستم حسگرهای جغرافیایی باشد.

توجه داشته باشید که این زوایا در سیستم مختصاتی متفاوت از سیستم مختصات مورد استفاده در هوانوردی (برای انحراف، پیچ و غلتش) کار می‌کنند. در سیستم هوانوردی، محور x در امتداد ضلع طولی هواپیما، از دم تا دماغه، قرار دارد.

حسگر جهت‌یابی، داده‌های خود را با پردازش داده‌های خام حسگر از شتاب‌سنج و حسگر میدان ژئومغناطیسی به دست می‌آورد. به دلیل پردازش سنگین، دقت و صحت حسگر جهت‌یابی کاهش می‌یابد. به طور خاص، این حسگر تنها زمانی قابل اعتماد است که زاویه چرخش ۰ باشد. در نتیجه، حسگر جهت‌یابی در اندروید ۲.۲ (سطح API ۸) و نوع حسگر جهت‌یابی در اندروید ۴.۴W (سطح API ۲۰) منسوخ شدند. به جای استفاده از داده‌های خام حسگر جهت‌یابی، توصیه می‌کنیم از روش getRotationMatrix() همراه با روش getOrientation() برای محاسبه مقادیر جهت‌گیری، همانطور که در نمونه کد زیر نشان داده شده است، استفاده کنید. به عنوان بخشی از این فرآیند، می‌توانید از روش remapCoordinateSystem() برای ترجمه مقادیر جهت‌گیری به چارچوب مرجع برنامه خود استفاده کنید.

کاتلین

class SensorActivity : Activity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private val accelerometerReading = FloatArray(3)
    private val magnetometerReading = FloatArray(3)

    private val rotationMatrix = FloatArray(9)
    private val orientationAngles = FloatArray(3)

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
        // You must implement this callback in your code.
    }

    override fun onResume() {
        super.onResume()

        // Get updates from the accelerometer and magnetometer at a constant rate.
        // To make batch operations more efficient and reduce power consumption,
        // provide support for delaying updates to the application.
        //
        // In this example, the sensor reporting delay is small enough such that
        // the application receives an update before the system checks the sensor
        // readings again.
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)?.also { accelerometer ->
            sensorManager.registerListener(
                    this,
                    accelerometer,
                    SensorManager.SENSOR_DELAY_NORMAL,
                    SensorManager.SENSOR_DELAY_UI
            )
        }
        sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)?.also { magneticField ->
            sensorManager.registerListener(
                    this,
                    magneticField,
                    SensorManager.SENSOR_DELAY_NORMAL,
                    SensorManager.SENSOR_DELAY_UI
            )
        }
    }

    override fun onPause() {
        super.onPause()

        // Don't receive any more updates from either sensor.
        sensorManager.unregisterListener(this)
    }

    // Get readings from accelerometer and magnetometer. To simplify calculations,
    // consider storing these readings as unit vectors.
    override fun onSensorChanged(event: SensorEvent) {
        if (event.sensor.type == Sensor.TYPE_ACCELEROMETER) {
            System.arraycopy(event.values, 0, accelerometerReading, 0, accelerometerReading.size)
        } else if (event.sensor.type == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, magnetometerReading, 0, magnetometerReading.size)
        }
    }

    // Compute the three orientation angles based on the most recent readings from
    // the device's accelerometer and magnetometer.
    fun updateOrientationAngles() {
        // Update rotation matrix, which is needed to update orientation angles.
        SensorManager.getRotationMatrix(
                rotationMatrix,
                null,
                accelerometerReading,
                magnetometerReading
        )

        // "rotationMatrix" now has up-to-date information.

        SensorManager.getOrientation(rotationMatrix, orientationAngles)

        // "orientationAngles" now has up-to-date information.
    }
}

جاوا

public class SensorActivity extends Activity implements SensorEventListener {

    private SensorManager sensorManager;
    private final float[] accelerometerReading = new float[3];
    private final float[] magnetometerReading = new float[3];

    private final float[] rotationMatrix = new float[9];
    private final float[] orientationAngles = new float[3];

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
    }

    @Override
    public void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
        // You must implement this callback in your code.
    }

    @Override
    protected void onResume() {
        super.onResume();

        // Get updates from the accelerometer and magnetometer at a constant rate.
        // To make batch operations more efficient and reduce power consumption,
        // provide support for delaying updates to the application.
        //
        // In this example, the sensor reporting delay is small enough such that
        // the application receives an update before the system checks the sensor
        // readings again.
        Sensor accelerometer = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
        if (accelerometer != null) {
            sensorManager.registerListener(this, accelerometer,
                SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        }
        Sensor magneticField = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);
        if (magneticField != null) {
            sensorManager.registerListener(this, magneticField,
                SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();

        // Don't receive any more updates from either sensor.
        sensorManager.unregisterListener(this);
    }

    // Get readings from accelerometer and magnetometer. To simplify calculations,
    // consider storing these readings as unit vectors.
    @Override
    public void onSensorChanged(SensorEvent event) {
        if (event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
          System.arraycopy(event.values, 0, accelerometerReading,
              0, accelerometerReading.length);
        } else if (event.sensor.getType() == Sensor.TYPE_MAGNETIC_FIELD) {
            System.arraycopy(event.values, 0, magnetometerReading,
                0, magnetometerReading.length);
        }
    }

    // Compute the three orientation angles based on the most recent readings from
    // the device's accelerometer and magnetometer.
    public void updateOrientationAngles() {
        // Update rotation matrix, which is needed to update orientation angles.
        SensorManager.getRotationMatrix(rotationMatrix, null,
            accelerometerReading, magnetometerReading);

        // "rotationMatrix" now has up-to-date information.

        SensorManager.getOrientation(rotationMatrix, orientationAngles);

        // "orientationAngles" now has up-to-date information.
    }
}

معمولاً نیازی به انجام هیچ پردازش داده یا فیلتر کردن زوایای جهت‌گیری خام دستگاه ندارید، به جز تبدیل سیستم مختصات حسگر به چارچوب مرجع کاربردتان.

استفاده از حسگر میدان مغناطیسی زمین

حسگر میدان ژئومغناطیسی به شما امکان می‌دهد تغییرات میدان مغناطیسی زمین را رصد کنید. کد زیر نحوه دریافت نمونه‌ای از حسگر میدان ژئومغناطیسی پیش‌فرض را نشان می‌دهد:

کاتلین

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD)

جاوا

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD);

توجه: اگر برنامه شما اندروید ۱۲ (سطح API 31) یا بالاتر را هدف قرار می‌دهد، این حسگر محدودیت سرعت دارد.

این حسگر داده‌های خام شدت میدان (برحسب میکروتسلا) را برای هر یک از سه محور مختصات ارائه می‌دهد. معمولاً نیازی به استفاده مستقیم از این حسگر نیست. در عوض، می‌توانید از حسگر بردار چرخش برای تعیین حرکت چرخشی خام استفاده کنید یا می‌توانید از شتاب‌سنج و حسگر میدان ژئومغناطیسی به همراه متد getRotationMatrix() برای به دست آوردن ماتریس چرخش و ماتریس شیب استفاده کنید. سپس می‌توانید از این ماتریس‌ها با متدهای getOrientation() و getInclination() برای به دست آوردن داده‌های آزیموت و شیب ژئومغناطیسی استفاده کنید.

توجه: هنگام آزمایش برنامه، می‌توانید با تکان دادن دستگاه به شکل عدد ۸، دقت حسگر را بهبود بخشید.

از مغناطیس‌سنج کالیبره نشده استفاده کنید

مغناطیس‌سنج کالیبره نشده مشابه حسگر میدان ژئومغناطیسی است، با این تفاوت که هیچ کالیبراسیون آهن سخت برای میدان مغناطیسی اعمال نمی‌شود. کالیبراسیون کارخانه‌ای و جبران دما همچنان برای میدان مغناطیسی اعمال می‌شوند. مغناطیس‌سنج کالیبره نشده برای مدیریت تخمین‌های آهن سخت بد مفید است. به طور کلی، geomagneticsensor_event.values[0] نزدیک به uncalibrated_magnetometer_event.values[0] - uncalibrated_magnetometer_event.values[3] خواهد بود. یعنی،

calibrated_x ~= uncalibrated_x - bias_estimate_x

توجه: حسگرهای کالیبره نشده نتایج خام بیشتری ارائه می‌دهند و ممکن است شامل مقداری بایاس باشند، اما اندازه‌گیری‌های آنها شامل پرش‌های کمتری از اصلاحات اعمال شده از طریق کالیبراسیون است. برخی از برنامه‌ها ممکن است این نتایج کالیبره نشده را به عنوان نتایج روان‌تر و قابل اعتمادتر ترجیح دهند. به عنوان مثال، اگر یک برنامه در تلاش است تا ادغام حسگر خود را انجام دهد، اعمال کالیبراسیون می‌تواند در واقع نتایج را تحریف کند.

علاوه بر میدان مغناطیسی، مغناطیس‌سنج کالیبره نشده، بایاس آهن سخت تخمینی را نیز در هر محور ارائه می‌دهد. کد زیر نحوه دریافت نمونه‌ای از مغناطیس‌سنج کالیبره نشده پیش‌فرض را به شما نشان می‌دهد:

کاتلین

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED)

جاوا

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD_UNCALIBRATED);

استفاده از حسگر مجاورتی

حسگر مجاورت به شما امکان می‌دهد فاصله یک جسم از یک دستگاه را تعیین کنید. کد زیر نحوه دریافت نمونه‌ای از حسگر مجاورت پیش‌فرض را نشان می‌دهد:

کاتلین

private lateinit var sensorManager: SensorManager
private var sensor: Sensor? = null
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)

جاوا

private SensorManager sensorManager;
private Sensor sensor;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
sensor = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);

حسگر مجاورت معمولاً برای تعیین فاصله سر فرد از صورت دستگاه گوشی استفاده می‌شود (برای مثال، وقتی کاربر در حال برقراری یا دریافت تماس تلفنی است). اکثر حسگرهای مجاورت، فاصله مطلق را بر حسب سانتی‌متر برمی‌گردانند، اما برخی فقط مقادیر نزدیک و دور را برمی‌گردانند.

توجه: در برخی از مدل‌های دستگاه، حسگر مجاورت در زیر صفحه نمایش قرار دارد که در صورت فعال بودن هنگام روشن بودن صفحه نمایش، می‌تواند باعث شود یک نقطه چشمک‌زن روی صفحه نمایش ظاهر شود.

کد زیر نحوه استفاده از حسگر مجاورتی را به شما نشان می‌دهد:

کاتلین

class SensorActivity : Activity(), SensorEventListener {

    private lateinit var sensorManager: SensorManager
    private var proximity: Sensor? = null

    public override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main)

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY)
    }

    override fun onAccuracyChanged(sensor: Sensor, accuracy: Int) {
        // Do something here if sensor accuracy changes.
    }

    override fun onSensorChanged(event: SensorEvent) {
        val distance = event.values[0]
        // Do something with this sensor data.
    }

    override fun onResume() {
        // Register a listener for the sensor.
        super.onResume()

        proximity?.also { proximity ->
            sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}

جاوا

public class SensorActivity extends Activity implements SensorEventListener {
    private SensorManager sensorManager;
    private Sensor proximity;

    @Override
    public final void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        // Get an instance of the sensor service, and use that to get an instance of
        // a particular sensor.
        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        proximity = sensorManager.getDefaultSensor(Sensor.TYPE_PROXIMITY);
    }

    @Override
    public final void onAccuracyChanged(Sensor sensor, int accuracy) {
        // Do something here if sensor accuracy changes.
    }

    @Override
    public final void onSensorChanged(SensorEvent event) {
        float distance = event.values[0];
        // Do something with this sensor data.
    }

    @Override
    protected void onResume() {
        // Register a listener for the sensor.
        super.onResume();
        sensorManager.registerListener(this, proximity, SensorManager.SENSOR_DELAY_NORMAL);
      }

    @Override
    protected void onPause() {
        // Be sure to unregister the sensor when the activity pauses.
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

نکته: برخی از حسگرهای مجاورتی مقادیر دودویی را برمی‌گردانند که نشان‌دهنده‌ی «نزدیک» یا «دور» هستند. در این حالت، حسگر معمولاً حداکثر مقدار برد خود را در حالت دور و مقدار کمتری را در حالت نزدیک گزارش می‌دهد. معمولاً مقدار دور مقداری > 5 سانتی‌متر است، اما این مقدار می‌تواند از حسگری به حسگر دیگر متفاوت باشد. می‌توانید حداکثر برد یک حسگر را با استفاده از متد getMaximumRange() تعیین کنید.

شما هم باید بخوانید