অবস্থান সেন্সর

অ্যান্ড্রয়েড প্ল্যাটফর্মে দুটি সেন্সর রয়েছে যা একটি ডিভাইসের অবস্থান নির্ধারণ করতে সাহায্য করে: ভূ-চৌম্বকীয় ক্ষেত্র সেন্সর এবং অ্যাক্সেলেরোমিটার। অ্যান্ড্রয়েড প্ল্যাটফর্মে আরও একটি সেন্সর রয়েছে যা দিয়ে বোঝা যায়, ডিভাইসটির মুখ কোনো বস্তুর কতটা কাছে আছে (যা প্রক্সিমিটি সেন্সর নামে পরিচিত)। ভূ-চৌম্বকীয় ক্ষেত্র সেন্সর এবং প্রক্সিমিটি সেন্সর হার্ডওয়্যার-ভিত্তিক। বেশিরভাগ হ্যান্ডসেট এবং ট্যাবলেট নির্মাতা তাদের ডিভাইসে একটি ভূ-চৌম্বকীয় ক্ষেত্র সেন্সর অন্তর্ভুক্ত করে। একইভাবে, হ্যান্ডসেট নির্মাতারা সাধারণত একটি প্রক্সিমিটি সেন্সর যুক্ত করে এটি বোঝার জন্য যে, হ্যান্ডসেটটি কখন ব্যবহারকারীর মুখের কাছে ধরা হচ্ছে (উদাহরণস্বরূপ, ফোন কলের সময়)। একটি ডিভাইসের অভিমুখ নির্ধারণের জন্য, আপনি ডিভাইসটির অ্যাক্সেলেরোমিটার এবং ভূ-চৌম্বকীয় ক্ষেত্র সেন্সর থেকে প্রাপ্ত রিডিং ব্যবহার করতে পারেন।

দ্রষ্টব্য: অ্যান্ড্রয়েড ২.২ (এপিআই লেভেল ৮)-এ ওরিয়েন্টেশন সেন্সর এবং অ্যান্ড্রয়েড ৪.৪ডব্লিউ (এপিআই লেভেল ২০)-এ ওরিয়েন্টেশন সেন্সর টাইপটি বাতিল করা হয়েছে।

পৃথিবীর সাপেক্ষে কোনো ডিভাইসের ভৌত অবস্থান নির্ণয় করার জন্য পজিশন সেন্সরগুলো উপযোগী। উদাহরণস্বরূপ, চৌম্বক উত্তর মেরুর সাপেক্ষে কোনো ডিভাইসের অবস্থান নির্ণয় করতে আপনি অ্যাক্সেলেরোমিটারের সাথে ভূ-চৌম্বক ক্ষেত্র সেন্সর ব্যবহার করতে পারেন। এছাড়াও, আপনার অ্যাপ্লিকেশনের সাপেক্ষে কোনো ডিভাইসের অভিমুখ নির্ণয় করতেও আপনি এই সেন্সরগুলো ব্যবহার করতে পারেন। ডিভাইসের নড়াচড়া বা গতি, যেমন—ঝাঁকুনি, কাত হওয়া বা ধাক্কা পর্যবেক্ষণ করার জন্য সাধারণত পজিশন সেন্সর ব্যবহার করা হয় না (আরও তথ্যের জন্য, মোশন সেন্সর দেখুন)।

ভূ-চৌম্বক ক্ষেত্র সেন্সর এবং অ্যাক্সেলেরোমিটার প্রতিটি SensorEvent জন্য সেন্সর মানের বহুমাত্রিক অ্যারে প্রদান করে। উদাহরণস্বরূপ, ভূ-চৌম্বক ক্ষেত্র সেন্সর একটি একক সেন্সর ইভেন্টের সময় তিনটি স্থানাঙ্ক অক্ষের প্রতিটির জন্য ভূ-চৌম্বক ক্ষেত্রের শক্তির মান প্রদান করে। একইভাবে, অ্যাক্সেলেরোমিটার সেন্সর একটি সেন্সর ইভেন্টের সময় ডিভাইসের উপর প্রযুক্ত ত্বরণ পরিমাপ করে। সেন্সরগুলো যে স্থানাঙ্ক ব্যবস্থা ব্যবহার করে সে সম্পর্কে আরও তথ্যের জন্য, সেন্সর স্থানাঙ্ক ব্যবস্থা দেখুন। প্রক্সিমিটি সেন্সর প্রতিটি সেন্সর ইভেন্টের জন্য একটি একক মান প্রদান করে। সারণি ১-এ অ্যান্ড্রয়েড প্ল্যাটফর্মে সমর্থিত পজিশন সেন্সরগুলোর সারসংক্ষেপ দেওয়া হয়েছে।

সারণি ১. অ্যান্ড্রয়েড প্ল্যাটফর্মে সমর্থিত অবস্থান সেন্সরসমূহ।

সেন্সর সেন্সর ইভেন্ট ডেটা বর্ণনা পরিমাপের একক
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] এক্স অক্ষ বরাবর ভূ-চৌম্বক ক্ষেত্রের প্রাবল্য। μT
SensorEvent.values[1] y অক্ষ বরাবর ভূ-চৌম্বক ক্ষেত্রের প্রাবল্য।
SensorEvent.values[2] z অক্ষ বরাবর ভূ-চৌম্বক ক্ষেত্রের প্রাবল্য।
TYPE_MAGNETIC_FIELD_UNCALIBRATED SensorEvent.values[0] এক্স-অক্ষ বরাবর ভূ-চৌম্বক ক্ষেত্রের প্রাবল্য (হার্ড আয়রন ক্যালিব্রেশন ছাড়া)। μT
SensorEvent.values[1] y অক্ষ বরাবর ভূ-চৌম্বক ক্ষেত্রের প্রাবল্য (হার্ড আয়রন ক্যালিব্রেশন ছাড়া)।
SensorEvent.values[2] z অক্ষ বরাবর ভূ-চৌম্বক ক্ষেত্রের প্রাবল্য (হার্ড আয়রন ক্যালিব্রেশন ছাড়া)।
SensorEvent.values[3] এক্স-অক্ষ বরাবর আয়রন বায়াসের অনুমান।
SensorEvent.values[4] y অক্ষ বরাবর আয়রন বায়াসের অনুমান।
SensorEvent.values[5] z অক্ষ বরাবর আয়রন বায়াসের অনুমান।
TYPE_ORIENTATION SensorEvent.values[0] অ্যাজিমুথ (z-অক্ষের চারপাশের কোণ)। ডিগ্রি
SensorEvent.values[1] পিচ (এক্স-অক্ষের চারপাশের কোণ)।
SensorEvent.values[2] ঘূর্ণন (y-অক্ষ বরাবর কোণ)।
TYPE_PROXIMITY SensorEvent.values[0] বস্তু থেকে দূরত্ব। সেমি

এই সেন্সরটি অ্যান্ড্রয়েড ২.২ (এপিআই লেভেল ৮)-এ এবং এই সেন্সর টাইপটি অ্যান্ড্রয়েড ৪.৪ডাব্লিউ (এপিআই লেভেল ২০)-এ বাতিল করা হয়েছে। সেন্সর ফ্রেমওয়ার্ক ডিভাইসের ওরিয়েন্টেশন জানার জন্য বিকল্প পদ্ধতি প্রদান করে, যা "ডিভাইসের ওরিয়েন্টেশন গণনা করুন" অংশে আলোচনা করা হয়েছে।

কিছু প্রক্সিমিটি সেন্সর কাছে ও দূর বোঝাতে শুধুমাত্র বাইনারি মান প্রদান করে।

গেম রোটেশন ভেক্টর সেন্সর ব্যবহার করুন

গেম রোটেশন ভেক্টর সেন্সরটি রোটেশন ভেক্টর সেন্সরের অনুরূপ, তবে এটি ভূ-চৌম্বক ক্ষেত্র ব্যবহার করে না। তাই এর 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-অক্ষটি বিমানের দীর্ঘ পাশ বরাবর, লেজ থেকে নাক পর্যন্ত বিস্তৃত থাকে।

ওরিয়েন্টেশন সেন্সরটি অ্যাক্সেলেরোমিটার এবং ভূ-চৌম্বকীয় ক্ষেত্র সেন্সর থেকে প্রাপ্ত কাঁচা ডেটা প্রসেস করে তার নিজস্ব ডেটা সংগ্রহ করে। এই ব্যাপক প্রসেসিংয়ের কারণে ওরিয়েন্টেশন সেন্সরের নির্ভুলতা এবং সূক্ষ্মতা কমে যায়। বিশেষত, এই সেন্সরটি কেবল তখনই নির্ভরযোগ্য যখন রোল অ্যাঙ্গেল ০ হয়। ফলস্বরূপ, অ্যান্ড্রয়েড ২.২ (এপিআই লেভেল ৮)-এ ওরিয়েন্টেশন সেন্সরটি ডেপ্রিকেটেড করা হয়েছিল এবং অ্যান্ড্রয়েড ৪.৪ডব্লিউ (এপিআই লেভেল ২০)-এ ওরিয়েন্টেশন সেন্সর টাইপটি ডেপ্রিকেটেড করা হয়েছিল। ওরিয়েন্টেশন সেন্সর থেকে প্রাপ্ত কাঁচা ডেটা ব্যবহার করার পরিবর্তে, আমরা আপনাকে ওরিয়েন্টেশন মান গণনা করার জন্য getOrientation() মেথডের সাথে getRotationMatrix() মেথডটি ব্যবহার করার পরামর্শ দিই, যেমনটি নিম্নলিখিত কোড স্যাম্পলে দেখানো হয়েছে। এই প্রক্রিয়ার অংশ হিসাবে, আপনি আপনার অ্যাপ্লিকেশনের ফ্রেম অফ রেফারেন্সে ওরিয়েন্টেশন মানগুলো অনুবাদ করতে 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);

দ্রষ্টব্য: আপনার অ্যাপটি যদি অ্যান্ড্রয়েড ১২ (এপিআই লেভেল ৩১) বা তার উচ্চতর সংস্করণকে টার্গেট করে, তাহলে এই সেন্সরটি রেট-লিমিটেড হবে

এই সেন্সরটি তিনটি স্থানাঙ্ক অক্ষের প্রতিটির জন্য কাঁচা ক্ষেত্র শক্তির ডেটা (μT এককে) প্রদান করে। সাধারণত, আপনার এই সেন্সরটি সরাসরি ব্যবহার করার প্রয়োজন হয় না। এর পরিবর্তে, আপনি কাঁচা ঘূর্ণন গতি নির্ধারণ করতে রোটেশন ভেক্টর সেন্সর ব্যবহার করতে পারেন অথবা রোটেশন ম্যাট্রিক্স এবং ইনক্লিনেশন ম্যাট্রিক্স পেতে 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);
    }
}

দ্রষ্টব্য: কিছু প্রক্সিমিটি সেন্সর বাইনারি মান প্রদান করে যা 'কাছে' বা 'দূরে' বোঝায়। এক্ষেত্রে, সেন্সরটি সাধারণত দূরের অবস্থায় তার সর্বোচ্চ রেঞ্জের মান এবং কাছের অবস্থায় একটি কম মান রিপোর্ট করে। সাধারণত, দূরের মানটি ৫ সেন্টিমিটারের বেশি হয়, কিন্তু এটি সেন্সরভেদে ভিন্ন হতে পারে। আপনি getMaximumRange() মেথডটি ব্যবহার করে একটি সেন্সরের সর্বোচ্চ রেঞ্জ নির্ধারণ করতে পারেন।

আপনারও পড়া উচিত