এক নজরে সেন্সর

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

Android প্ল্যাটফর্মে তিন ধরনের সেন্সর কাজ করে:

  • মোশন সেন্সর

    এই সেন্সরগুলি তিনটি অক্ষ বরাবর ত্বরণ বল এবং ঘূর্ণন বল পরিমাপ করে। এই বিভাগে অ্যাকসিলরোমিটার, গ্র্যাভিটি সেন্সর, জাইরোস্কোপ ও রোটেশনাল ভেক্টর সেন্সর অন্তর্ভুক্ত।

  • পরিবেশ সংক্রান্ত সেন্সর

    এইসব সেন্সর পরিবেশের বিভিন্ন প্যারামিটার পরিমাপ করে, যেমন অ্যাম্বিয়েন্ট এয়ার টেম্পারেচার ও প্রেসার, ইলুমিনেশন ও আর্দ্রতা। এই বিভাগে ব্যারোমিটার, ফটোমিটার ও থার্মোমিটার অন্তর্ভুক্ত।

  • পজিশন সেন্সর

    এইসব সেন্সর ডিভাইসের ফিজিক্যাল পজিশন পরিমাপ করে। এই বিভাগে ওরিয়েন্টেশন সেন্সর ও ম্যাগনেটোমিটার অন্তর্ভুক্ত।

আপনি ডিভাইসে উপলভ্য সেন্সর অ্যাক্সেস করতে এবং Android সেন্সর ফ্রেমওয়ার্ক ব্যবহার করে র সেন্সর ডেটা পেতে পারেন। সেন্সর ফ্রেমওয়ার্ক বিভিন্ন ক্লাস ও ইন্টারফেস প্রদান করে যা আপনাকে সেন্সর সম্পর্কিত বিভিন্ন ধরনের টাস্ক সম্পূর্ণ করতে সাহায্য করে। যেমন, আপনি নিম্নলিখিত কাজগুলি করতে সেন্সর ফ্রেমওয়ার্ক ব্যবহার করতে পারেন:

  • কোনও ডিভাইসে কোন কোন সেন্সর উপলভ্য আছে তা নির্ধারণ করুন।
  • কোনও স্বতন্ত্র সেন্সরের ক্ষমতা নির্ধারণ করুন, যেমন এর সর্বাধিক রেঞ্জ, প্রস্তুতকারক, পাওয়ার প্রয়োজনীয়তা এবং রেজোলিউশন।
  • র-সেন্সর ডেটা সংগ্রহ করুন এবং যে ন্যূনতম রেটে আপনি সেন্সর ডেটা সংগ্রহ করেন তা নির্ধারণ করুন।
  • সেন্সর ইভেন্ট লিসনার রেজিস্টার ও আনরেজিস্টার করুন যা সেন্সর পরিবর্তন মনিটর করে।

এই বিষয় থেকে Android প্ল্যাটফর্মে উপলভ্য সেন্সর সম্পর্কে এক নজরে জানতে পারবেন। এছাড়াও এটি সেন্সর ফ্রেমওয়ার্কের একটি ভূমিকা প্রদান করে।

সেন্সর সম্পর্কে প্রাথমিক তথ্য

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

Android-পরিচালিত কিছু ডিভাইসে সব ধরনের সেন্সর থাকে। যেমন, বেশিরভাগ হ্যান্ডসেট ডিভাইস ও ট্যাবলেটে অ্যাকসিলরোমিটার ও ম্যাগনেটোমিটার থাকে, কিন্তু খুব কম ডিভাইসে ব্যারোমিটার বা থার্মোমিটার থাকে। এছাড়াও, কোনও ডিভাইসে নির্দিষ্ট ধরনের একাধিক সেন্সর থাকতে পারে। যেমন, একটি ডিভাইসে দুটি গ্র্যাভিটি সেন্সর থাকতে পারে, যার প্রতিটির আলাদা রেঞ্জ থাকে।

টেবিল ১. Android প্ল্যাটফর্মে কাজ করে এমন সেন্সরের ধরন।

সেন্সর ধরন বর্ণনা সাধারণ ব্যবহার
TYPE_ACCELEROMETER হার্ডওয়্যার m/s2-এ ত্বরণ বল পরিমাপ করে যা তিনটি ফিজিক্যাল অক্ষ (x, y, এবং z)-এ ডিভাইসে প্রয়োগ করা হয়, যার মধ্যে মাধ্যাকর্ষণ বলও অন্তর্ভুক্ত। মোশন ডিটেকশন (ঝাঁকানো, কাত করা ইত্যাদি)।
TYPE_AMBIENT_TEMPERATURE হার্ডওয়্যার ডিগ্রি সেলসিয়াসে (°C) ঘরের অ্যাম্বিয়েন্ট তাপমাত্রা পরিমাপ করে। নিচে নোট দেখুন। বাতাসের তাপমাত্রা মনিটর করা।
TYPE_GRAVITY সফ্টওয়্যার বা হার্ডওয়্যার m/s2-এ মাধ্যাকর্ষণ বল পরিমাপ করে যা তিনটি ফিজিক্যাল অক্ষ (x, y, z) জুড়ে ডিভাইসে প্রয়োগ করা হয়। মোশন ডিটেকশন (ঝাঁকানো, কাত করা ইত্যাদি)।
TYPE_GYROSCOPE হার্ডওয়্যার তিনটি ফিজিক্যাল অক্ষের (x, y, এবং z) প্রতিটির চারপাশে rad/s-এ ডিভাইসের ঘূর্ণনের হার পরিমাপ করে। ঘোরানো শনাক্তকরণ (স্পিন, টার্ন ইত্যাদি)।
TYPE_LIGHT হার্ডওয়্যার lx-এ অ্যাম্বিয়েন্ট লাইটের লেভেল (ইলুমিনেশন) পরিমাপ করে। স্ক্রিনের উজ্জ্বলতা কন্ট্রোল করা।
TYPE_LINEAR_ACCELERATION সফ্টওয়্যার বা হার্ডওয়্যার m/s2-এ অ্যাক্সিলারেশন ফোর্স পরিমাপ করে যা মাধ্যাকর্ষণ বল বাদ দিয়ে তিনটি ফিজিক্যাল অক্ষ (x, y, এবং z) বরাবর ডিভাইসে প্রয়োগ করা হয়। একটি অক্ষ বরাবর ত্বরণ মনিটর করা।
TYPE_MAGNETIC_FIELD হার্ডওয়্যার μT-তে তিনটি ফিজিক্যাল অক্ষের (x, y, z) জন্য অ্যাম্বিয়েন্ট জিওম্যাগনেটিক ফিল্ড পরিমাপ করে। কম্পাস তৈরি করা হচ্ছে।
TYPE_ORIENTATION সফ্টওয়্যার তিনটি ফিজিক্যাল অক্ষ (x, y, z) বরাবর ডিভাইসটি কত ডিগ্রি ঘুরছে তা পরিমাপ করে। API লেভেল ৩ থেকে আপনি কোনও ডিভাইসের জন্য ইনক্লিনেশন ম্যাট্রিক্স ও রোটেশন ম্যাট্রিক্স পেতে পারেন। এর জন্য আপনাকে getRotationMatrix() পদ্ধতির সাথে গ্র্যাভিটি সেন্সর ও জিওম্যাগনেটিক ফিল্ড সেন্সর ব্যবহার করতে হবে। ডিভাইসের অবস্থান নির্ধারণ করা হচ্ছে।
TYPE_PRESSURE হার্ডওয়্যার hPa বা mbar-এ পরিবেষ্টিত বায়ুর চাপ পরিমাপ করে। এয়ার প্রেসারের পরিবর্তন মনিটর করা।
TYPE_PROXIMITY হার্ডওয়্যার কোনও ডিভাইসের ভিউ স্ক্রিনের সাপেক্ষে কোনও অবজেক্টের প্রক্সিমিটি সেন্টিমিটারে পরিমাপ করে। এই সেন্সর সাধারণত কোনও হ্যান্ডসেট কোনও ব্যক্তির কানের কাছে ধরা আছে কিনা তা নির্ধারণ করতে ব্যবহৃত হয়। কল চলাকালীন ফোনের পজিশন।
TYPE_RELATIVE_HUMIDITY হার্ডওয়্যার আপেক্ষিক পরিবেশের আর্দ্রতা শতাংশে (%) পরিমাপ করে। শিশিরাঙ্ক, পরম এবং আপেক্ষিক আর্দ্রতা মনিটর করা হচ্ছে।
TYPE_ROTATION_VECTOR সফ্টওয়্যার বা হার্ডওয়্যার ডিভাইসের রোটেশন ভেক্টরের তিনটি এলিমেন্ট প্রদান করে ডিভাইসের ওরিয়েন্টেশন পরিমাপ করে। মোশন ডিটেকশন ও রোটেশন ডিটেকশন।
TYPE_TEMPERATURE হার্ডওয়্যার ডিগ্রি সেলসিয়াসে (°C) ডিভাইসের তাপমাত্রা পরিমাপ করে। এই সেন্সর বিভিন্ন ডিভাইসে আলাদাভাবে কাজ করে এবং API লেভেল ১৪-এ এই সেন্সর TYPE_AMBIENT_TEMPERATURE সেন্সর দিয়ে পরিবর্তন করা হয়েছে তাপমাত্রা মনিটর করা।

Sensor Framework

আপনি Android সেন্সর ফ্রেমওয়ার্ক ব্যবহার করে এইসব সেন্সর অ্যাক্সেস করতে এবং র-সেন্সর ডেটা পেতে পারবেন। সেন্সর ফ্রেমওয়ার্ক হল android.hardware প্যাকেজের অংশ এবং এতে নিম্নলিখিত ক্লাস ও ইন্টারফেস অন্তর্ভুক্ত থাকে:

SensorManager
আপনি এই ক্লাস ব্যবহার করে সেন্সর পরিষেবার ইনস্ট্যান্স তৈরি করতে পারবেন। এই ক্লাস সেন্সর অ্যাক্সেস ও তালিকাভুক্ত করা, সেন্সর ইভেন্ট লিসেনার রেজিস্টার ও আনরেজিস্টার করা এবং ওরিয়েন্টেশন সংক্রান্ত তথ্য পাওয়ার জন্য বিভিন্ন পদ্ধতি প্রদান করে। এই ক্লাসটি বেশ কয়েকটি সেন্সর কনস্ট্যান্টও প্রদান করে যা সেন্সরের নির্ভুলতা রিপোর্ট করতে, ডেটা অধিগ্রহণের হার সেট করতে এবং সেন্সর ক্যালিব্রেট করতে ব্যবহৃত হয়।
Sensor
নির্দিষ্ট সেন্সরের ইনস্ট্যান্স তৈরি করতে আপনি এই ক্লাস ব্যবহার করতে পারবেন। এই ক্লাস বিভিন্ন পদ্ধতি প্রদান করে যা আপনাকে সেন্সরের ক্ষমতা নির্ধারণ করতে দেয়।
SensorEvent
সিস্টেম এই ক্লাস ব্যবহার করে সেন্সর ইভেন্ট অবজেক্ট তৈরি করে, যা সেন্সর ইভেন্ট সম্পর্কে তথ্য প্রদান করে। সেন্সর ইভেন্ট অবজেক্টে নিম্নলিখিত তথ্য অন্তর্ভুক্ত থাকে: র সেন্সর ডেটা, যে ধরনের সেন্সর ইভেন্টটি তৈরি করেছে, ডেটার নির্ভুলতা এবং ইভেন্টের টাইমস্ট্যাম্প।
SensorEventListener
আপনি এই ইন্টারফেস ব্যবহার করে দুটি কলব্যাক পদ্ধতি তৈরি করতে পারবেন যা সেন্সর ভ্যালু বা সেন্সর অ্যাকুরেসি পরিবর্তন হলে বিজ্ঞপ্তি (সেন্সর ইভেন্ট) পায়।

সাধারণত কোনও অ্যাপ্লিকেশনে আপনি দুটি প্রাথমিক টাস্ক সম্পূর্ণ করতে এইসব সেন্সর-সম্পর্কিত API ব্যবহার করেন:

  • সেন্সর ও সেন্সরের কার্যকারিতা শনাক্ত করা

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

  • সেন্সর ইভেন্ট মনিটর করুন

    সেন্সর ইভেন্ট মনিটর করার মাধ্যমে আপনি র সেন্সর ডেটা পান। প্রতিবার সেন্সর ইভেন্ট ঘটে সেন্সর যে প্যারামিটার পরিমাপ করছে তাতে পরিবর্তন শনাক্ত করে। একটি সেন্সর ইভেন্ট আপনাকে চারটি তথ্য প্রদান করে: যে সেন্সর ইভেন্টটি ট্রিগার করেছে তার নাম, ইভেন্টের টাইমস্ট্যাম্প, ইভেন্টের নির্ভুলতা এবং ইভেন্টটি ট্রিগার করা র-সেন্সর ডেটা।

সেন্সর উপলভ্যতা

ডিভাইস অনুযায়ী সেন্সরের উপলভ্যতা আলাদা আলাদা হয়, এমনকি Android ভার্সন অনুযায়ীও এটি আলাদা হতে পারে। এর কারণ হল, প্ল্যাটফর্মের একাধিক রিলিজের সময় Android সেন্সর পরিচয় করানো হয়েছে। যেমন, Android 1.5 (API লেভেল ৩)-এ অনেক সেন্সর চালু করা হয়েছিল, কিন্তু কিছু সেন্সর Android 2.3 (API লেভেল ৯)-এর আগে প্রয়োগ করা হয়নি এবং ব্যবহারের জন্য উপলভ্য ছিল না। একইভাবে, Android 2.3 (API লেভেল ৯) এবং Android 4.0 (API লেভেল ১৪)-এ বেশ কিছু সেন্সর চালু করা হয়েছে। দুটি সেন্সর বাতিল করা হয়েছে এবং তার পরিবর্তে নতুন ও আরও ভালো সেন্সর যোগ করা হয়েছে।

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

সারণী ২. প্ল্যাটফর্ম অনুযায়ী সেন্সরের উপলভ্যতা।

সেন্সর Android 4.0
(API লেভেল ১৪)
Android 2.3
(API লেভেল 9)
Android 2.2
(API লেভেল ৮)
Android 1.5
(API লেভেল ৩)
TYPE_ACCELEROMETER হ্যাঁ হ্যাঁ হ্যাঁ হ্যাঁ
TYPE_AMBIENT_TEMPERATURE হ্যাঁ প্রযোজ্য নয় প্রযোজ্য নয় প্রযোজ্য নয়
TYPE_GRAVITY হ্যাঁ হ্যাঁ প্রযোজ্য নয় প্রযোজ্য নয়
TYPE_GYROSCOPE হ্যাঁ হ্যাঁ প্রযোজ্য নয়১ প্রযোজ্য নয়১
TYPE_LIGHT হ্যাঁ হ্যাঁ হ্যাঁ হ্যাঁ
TYPE_LINEAR_ACCELERATION হ্যাঁ হ্যাঁ প্রযোজ্য নয় প্রযোজ্য নয়
TYPE_MAGNETIC_FIELD হ্যাঁ হ্যাঁ হ্যাঁ হ্যাঁ
TYPE_ORIENTATION হ্যাঁ২ হ্যাঁ২ হ্যাঁ২ হ্যাঁ
TYPE_PRESSURE হ্যাঁ হ্যাঁ প্রযোজ্য নয়১ প্রযোজ্য নয়১
TYPE_PROXIMITY হ্যাঁ হ্যাঁ হ্যাঁ হ্যাঁ
TYPE_RELATIVE_HUMIDITY হ্যাঁ প্রযোজ্য নয় প্রযোজ্য নয় প্রযোজ্য নয়
TYPE_ROTATION_VECTOR হ্যাঁ হ্যাঁ প্রযোজ্য নয় প্রযোজ্য নয়
TYPE_TEMPERATURE হ্যাঁ২ হ্যাঁ হ্যাঁ হ্যাঁ

১ এই ধরনের সেন্সর Android 1.5 (API লেভেল ৩)-এ যোগ করা হয়েছিল, কিন্তু Android 2.3 (API লেভেল ৯)-এর আগে এটি ব্যবহার করা যেত না।

২ এই সেন্সর উপলভ্য আছে, তবে এটি বন্ধ করে দেওয়া হয়েছে।

সেন্সর এবং সেন্সরের ক্ষমতা শনাক্ত করা

Android সেন্সর ফ্রেমওয়ার্ক বিভিন্ন পদ্ধতি প্রদান করে যার সাহায্যে রানটাইমে ডিভাইসে কোন কোন সেন্সর আছে তা সহজেই নির্ধারণ করা যায়। এছাড়াও, API এমন পদ্ধতি প্রদান করে যার মাধ্যমে আপনি প্রতিটি সেন্সরের ক্ষমতা নির্ধারণ করতে পারবেন, যেমন এর সর্বাধিক রেঞ্জ, রেজোলিউশন এবং পাওয়ারের প্রয়োজনীয়তা।

কোনও ডিভাইসে থাকা সেন্সর শনাক্ত করতে, আপনাকে প্রথমে সেন্সর পরিষেবার রেফারেন্স পেতে হবে। এটি করতে, আপনি getSystemService() পদ্ধতি কল করে এবং SENSOR_SERVICE আর্গুমেন্ট পাস করে SensorManager ক্লাসের একটি ইনস্ট্যান্স তৈরি করেন। যেমন:

Kotlin

private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

জাভা

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);

এরপর, getSensorList() পদ্ধতি কল করে এবং TYPE_ALL কনস্ট্যান্ট ব্যবহার করে আপনি ডিভাইসের প্রতিটি সেন্সরের তালিকা পেতে পারেন। যেমন:

Kotlin

val deviceSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_ALL)

জাভা

List<Sensor> deviceSensors = sensorManager.getSensorList(Sensor.TYPE_ALL);

আপনি যদি কোনও নির্দিষ্ট ধরনের সব সেন্সরের তালিকা তৈরি করতে চান, তাহলে TYPE_ALL-এর পরিবর্তে অন্য কনস্ট্যান্ট ব্যবহার করতে পারেন, যেমন TYPE_GYROSCOPE, TYPE_LINEAR_ACCELERATION অথবা TYPE_GRAVITY।

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

Kotlin

private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null) {
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

জাভা

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_MAGNETIC_FIELD) != null){
    // Success! There's a magnetometer.
} else {
    // Failure! No magnetometer.
}

মনে রাখবেন: Android-এর জন্য ডিভাইস প্রস্তুতকারকদের তাদের Android-চালিত ডিভাইসে কোনও নির্দিষ্ট ধরনের সেন্সর তৈরি করার প্রয়োজন হয় না, তাই ডিভাইসে বিভিন্ন ধরনের সেন্সর কনফিগারেশন থাকতে পারে।

ডিভাইসে থাকা সেন্সরগুলির তালিকা তৈরি করার পাশাপাশি, আপনি প্রতিটি সেন্সরের ক্ষমতা এবং বৈশিষ্ট্য নির্ধারণ করতে Sensor ক্লাসের পাবলিক পদ্ধতিগুলি ব্যবহার করতে পারেন। কোনও ডিভাইসে কোন সেন্সর বা সেন্সরের ক্ষমতা উপলভ্য আছে তার উপর ভিত্তি করে আপনার অ্যাপ্লিকেশনটি আলাদাভাবে আচরণ করুক, আপনি যদি তা চান তাহলে এটি উপযোগী। যেমন, আপনি getResolution() এবং getMaximumRange() পদ্ধতি ব্যবহার করে সেন্সরের রেজোলিউশন এবং পরিমাপের সর্বাধিক রেঞ্জ পেতে পারেন। এছাড়াও, আপনি getPower() পদ্ধতি ব্যবহার করে সেন্সরের পাওয়ার সংক্রান্ত প্রয়োজনীয়তা জানতে পারবেন।

আপনি যদি বিভিন্ন প্রস্তুতকারকের সেন্সর বা সেন্সরের বিভিন্ন ভার্সনের জন্য আপনার অ্যাপ্লিকেশন অপ্টিমাইজ করতে চান, তাহলে দুটি পাবলিক পদ্ধতি বিশেষভাবে কার্যকর। যেমন, আপনার অ্যাপ্লিকেশন যদি ব্যবহারকারীর জেসচার যেমন, কাত করা এবং ঝাঁকানো মনিটর করতে চায়, তাহলে আপনি নতুন ডিভাইসের জন্য ডেটা ফিল্টারিং নিয়ম এবং অপ্টিমাইজেশনের একটি সেট তৈরি করতে পারেন যেগুলিতে নির্দিষ্ট ভেন্ডরের গ্র্যাভিটি সেন্সর আছে এবং অন্য একটি ডেটা ফিল্টারিং নিয়ম এবং অপ্টিমাইজেশনের সেট তৈরি করতে পারেন যেগুলিতে গ্র্যাভিটি সেন্সর নেই এবং শুধুমাত্র অ্যাক্সিলারোমিটার আছে। নিম্নলিখিত কোড স্যাম্পেল থেকে আপনি জানতে পারবেন যে কীভাবে getVendor() এবং getVersion() পদ্ধতি ব্যবহার করে এটি করতে পারবেন। এই স্যাম্পেলে, আমরা এমন একটি গ্র্যাভিটি সেন্সর খুঁজছি যা Google LLC-কে ভেন্ডর হিসেবে তালিকাভুক্ত করে এবং যার ভার্সন নম্বর হল ৩। ডিভাইসে সেই নির্দিষ্ট সেন্সর না থাকলে, আমরা অ্যাক্সেলেরোমিটার ব্যবহার করার চেষ্টা করি।

Kotlin

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

...

sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null) {
    val gravSensors: List<Sensor> = sensorManager.getSensorList(Sensor.TYPE_GRAVITY)
    // Use the version 3 gravity sensor.
    mSensor = gravSensors.firstOrNull { it.vendor.contains("Google LLC") && it.version == 3 }
}
if (mSensor == null) {
    // Use the accelerometer.
    mSensor = if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null) {
        sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER)
    } else {
        // Sorry, there are no accelerometers on your device.
        // You can't play this game.
        null
    }
}

জাভা

private SensorManager sensorManager;
private Sensor mSensor;

...

sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mSensor = null;

if (sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY) != null){
    List<Sensor> gravSensors = sensorManager.getSensorList(Sensor.TYPE_GRAVITY);
    for(int i=0; i<gravSensors.size(); i++) {
        if ((gravSensors.get(i).getVendor().contains("Google LLC")) &&
           (gravSensors.get(i).getVersion() == 3)){
            // Use the version 3 gravity sensor.
            mSensor = gravSensors.get(i);
        }
    }
}
if (mSensor == null){
    // Use the accelerometer.
    if (sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER) != null){
        mSensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
    } else{
        // Sorry, there are no accelerometers on your device.
        // You can't play this game.
    }
}

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

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

সতর্কতা: কোনও সেন্সরের ডেটা অ্যাকুইজিশনের সর্বোচ্চ রেট এবং সেন্সর ফ্রেমওয়ার্ক যে রেটে আপনার অ্যাপ্লিকেশনে সেন্সর ডেটা ডেলিভার করে, সেই দুটি রেট এক নাও হতে পারে। সেন্সর ফ্রেমওয়ার্ক সেন্সর ইভেন্টের মাধ্যমে ডেটা রিপোর্ট করে এবং আপনার অ্যাপ্লিকেশন যে রেটে সেন্সর ইভেন্ট পায় তা বিভিন্ন ফ্যাক্টরের দ্বারা প্রভাবিত হয়। আরও তথ্যের জন্য, সেন্সর ইভেন্ট মনিটর করা দেখুন।

সেন্সর ইভেন্ট মনিটর করা

র-সেন্সর ডেটা মনিটর করতে আপনাকে দুটি কলব্যাক পদ্ধতি প্রয়োগ করতে হবে যা SensorEventListener ইন্টারফেসের মাধ্যমে প্রকাশ করা হয়: onAccuracyChanged() এবং onSensorChanged()। নিম্নলিখিত ঘটনা ঘটলে Android সিস্টেম এইসব মেথড কল করে:

  • সেন্সরের অ্যাকুরেসি পরিবর্তন হয়।

    এই ক্ষেত্রে সিস্টেম onAccuracyChanged() পদ্ধতিকে কল করে, যা আপনাকে পরিবর্তিত Sensor অবজেক্টের রেফারেন্স এবং সেন্সরের নতুন অ্যাকুরেসি প্রদান করে। চারটি স্ট্যাটাস কনস্ট্যান্টের একটির মাধ্যমে নির্ভুলতা দেখানো হয়: SENSOR_STATUS_ACCURACY_LOW, SENSOR_STATUS_ACCURACY_MEDIUM, SENSOR_STATUS_ACCURACY_HIGH, অথবা SENSOR_STATUS_UNRELIABLE।

  • একটি সেন্সর নতুন ভ্যালু রিপোর্ট করে।

    এই ক্ষেত্রে সিস্টেম onSensorChanged() পদ্ধতিকে কল করে, যা আপনাকে একটি SensorEvent অবজেক্ট প্রদান করে। একটি SensorEvent অবজেক্টে নতুন সেন্সর ডেটা সম্পর্কে তথ্য থাকে, যার মধ্যে রয়েছে: ডেটার নির্ভুলতা, ডেটা তৈরি করা সেন্সর, ডেটা তৈরি হওয়ার টাইমস্ট্যাম্প এবং সেন্সর দ্বারা রেকর্ড করা নতুন ডেটা।

লাইট সেন্সর থেকে ডেটা মনিটর করার জন্য কীভাবে onSensorChanged() পদ্ধতি ব্যবহার করতে হয় তা নিম্নলিখিত কোড থেকে জানা যায়। এই উদাহরণে TextView-এ র' সেন্সর ডেটা দেখানো হয়েছে যা main.xml ফাইলে sensor_data হিসেবে উল্লেখ করা হয়েছে।

Kotlin

class SensorActivity : Activity(), SensorEventListener {
    private lateinit var sensorManager: SensorManager
    private var mLight: Sensor? = null

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

        sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT)
    }

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

    override fun onSensorChanged(event: SensorEvent) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        val lux = event.values[0]
        // Do something with this sensor value.
    }

    override fun onResume() {
        super.onResume()
        mLight?.also { light ->
            sensorManager.registerListener(this, light, SensorManager.SENSOR_DELAY_NORMAL)
        }
    }

    override fun onPause() {
        super.onPause()
        sensorManager.unregisterListener(this)
    }
}

জাভা

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

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

        sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
        mLight = sensorManager.getDefaultSensor(Sensor.TYPE_LIGHT);
    }

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

    @Override
    public final void onSensorChanged(SensorEvent event) {
        // The light sensor returns a single value.
        // Many sensors return 3 values, one for each axis.
        float lux = event.values[0];
        // Do something with this sensor value.
    }

    @Override
    protected void onResume() {
        super.onResume();
        sensorManager.registerListener(this, mLight, SensorManager.SENSOR_DELAY_NORMAL);
    }

    @Override
    protected void onPause() {
        super.onPause();
        sensorManager.unregisterListener(this);
    }
}

এই উদাহরণে, registerListener() মেথড কল করার সময় ডিফল্ট ডেটা বিলম্ব (SENSOR_DELAY_NORMAL) নির্দিষ্ট করা হয়েছে। ডেটা বিলম্ব (বা স্যাম্পলিং রেট) সেই ব্যবধানকে নিয়ন্ত্রণ করে যেখানে সেন্সর ইভেন্টগুলি onSensorChanged() কলব্যাক পদ্ধতির মাধ্যমে আপনার অ্যাপ্লিকেশনে পাঠানো হয়। ডিফল্ট ডেটা বিলম্ব সাধারণ স্ক্রিন ওরিয়েন্টেশন পরিবর্তনগুলি নিরীক্ষণের জন্য উপযুক্ত এবং ২০০,০০০ মাইক্রোসেকেন্ডের বিলম্ব ব্যবহার করে। আপনি অন্যান্য ডেটা বিলম্বের সময় নির্দিষ্ট করতে পারেন, যেমন SENSOR_DELAY_GAME (২০,০০০ মাইক্রোসেকেন্ড বিলম্ব), SENSOR_DELAY_UI (৬০,০০০ মাইক্রোসেকেন্ড বিলম্ব) অথবা SENSOR_DELAY_FASTEST (০ মাইক্রোসেকেন্ড বিলম্ব)। Android 3.0 (API লেভেল 11) থেকে আপনি ডিলেকে অ্যাবসোলিউট ভ্যালু (মাইক্রোসেকেন্ডে) হিসেবেও উল্লেখ করতে পারবেন।

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

সেন্সর ফ্রেমওয়ার্ক আপনার অ্যাপ্লিকেশনে যে রেটে সেন্সর ইভেন্ট পাঠাচ্ছে তা নির্ধারণ করার কোনও পাবলিক পদ্ধতি নেই; তবে, আপনি একাধিক ইভেন্ট জুড়ে স্যাম্পলিং রেট গণনা করতে প্রতিটি সেন্সর ইভেন্টের সাথে যুক্ত টাইমস্ট্যাম্প ব্যবহার করতে পারেন। একবার সেট করার পরে আপনাকে স্যাম্পলিং রেট (দেরি) পরিবর্তন করতে হবে না। কোনও কারণে আপনাকে বিলম্বের সময় পরিবর্তন করতে হলে, আপনাকে সেন্সর লিসেনার আনরেজিস্টার করে আবার রেজিস্টার করতে হবে।

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

বিভিন্ন সেন্সর কনফিগারেশন ম্যানেজ করা

Android ডিভাইসের জন্য কোনও স্ট্যান্ডার্ড সেন্সর কনফিগারেশন নির্দিষ্ট করে না, যার অর্থ হল ডিভাইস প্রস্তুতকারকরা তাদের Android-চালিত ডিভাইসে যেকোনও সেন্সর কনফিগারেশন অন্তর্ভুক্ত করতে পারে। এর ফলে, ডিভাইসে বিভিন্ন ধরনের কনফিগারেশনে অনেক ধরনের সেন্সর অন্তর্ভুক্ত থাকতে পারে। আপনার অ্যাপ্লিকেশন যদি কোনও নির্দিষ্ট ধরনের সেন্সরের উপর নির্ভর করে, তাহলে আপনাকে নিশ্চিত করতে হবে যে ডিভাইসে সেন্সরটি আছে যাতে আপনার অ্যাপ সফলভাবে চলতে পারে।

কোনও ডিভাইসে নির্দিষ্ট সেন্সর আছে কিনা তা নিশ্চিত করার জন্য আপনার কাছে দুটি বিকল্প আছে:

  • রানটাইমে সেন্সর শনাক্ত করুন এবং উপযুক্ত হিসাবে অ্যাপ্লিকেশন ফিচার চালু বা বন্ধ করুন।
  • নির্দিষ্ট সেন্সর কনফিগারেশন সহ ডিভাইস টার্গেট করতে Google Play ফিল্টার ব্যবহার করুন।

প্রতিটি বিকল্প নিম্নলিখিত বিভাগে আলোচনা করা হয়েছে।

রানটাইমে সেন্সর শনাক্ত করা

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

Kotlin

private lateinit var sensorManager: SensorManager
...
sensorManager = getSystemService(Context.SENSOR_SERVICE) as SensorManager

if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null) {
    // Success! There's a pressure sensor.
} else {
    // Failure! No pressure sensor.
}

জাভা

private SensorManager sensorManager;
...
sensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
if (sensorManager.getDefaultSensor(Sensor.TYPE_PRESSURE) != null){
    // Success! There's a pressure sensor.
} else {
    // Failure! No pressure sensor.
}

নির্দিষ্ট সেন্সর কনফিগারেশন টার্গেট করতে Google Play ফিল্টার ব্যবহার করা

আপনি Google Play-তে আপনার অ্যাপ্লিকেশন প্রকাশ করলে, আপনার অ্যাপ্লিকেশনের জন্য উপযুক্ত সেন্সর কনফিগারেশন নেই এমন ডিভাইস থেকে আপনার অ্যাপ্লিকেশন ফিল্টার করতে আপনার ম্যানিফেস্ট ফাইলে <uses-feature> এলিমেন্ট ব্যবহার করতে পারেন। <uses-feature> এলিমেন্টে একাধিক হার্ডওয়্যার ডেসক্রিপ্টর থাকে যা আপনাকে নির্দিষ্ট সেন্সরের উপস্থিতির ভিত্তিতে অ্যাপ্লিকেশন ফিল্টার করতে দেয়। আপনি যেসব সেন্সর তালিকাভুক্ত করতে পারবেন তার মধ্যে রয়েছে: অ্যাকসিলরোমিটার, ব্যারোমিটার, কম্পাস (জিওম্যাগনেটিক ফিল্ড), জাইরোস্কোপ, লাইট ও প্রক্সিমিটি। নিম্নলিখিতটি একটি উদাহরণ ম্যানিফেস্ট এন্ট্রি যা অ্যাক্সিলোমিটার নেই এমন অ্যাপগুলিকে ফিল্টার করে:

<uses-feature android:name="android.hardware.sensor.accelerometer"
              android:required="true" />

আপনি যদি এই এলিমেন্ট এবং ডেসক্রিপ্টর আপনার অ্যাপ্লিকেশনের ম্যানিফেস্টে যোগ করেন, তাহলে ব্যবহারকারীরা Google Play-তে আপনার অ্যাপ্লিকেশন তখনই দেখতে পাবেন যদি তাদের ডিভাইসে অ্যাক্সিলোমিটার থাকে।

আপনার অ্যাপ্লিকেশন সম্পূর্ণভাবে কোনও নির্দিষ্ট সেন্সরের উপর নির্ভর করলে, তবেই আপনার ডেসক্রিপ্টর android:required="true"-এ সেট করা উচিত। আপনার অ্যাপ্লিকেশন যদি কোনও কার্যকারিতার জন্য সেন্সর ব্যবহার করে, কিন্তু তবুও সেন্সর ছাড়াই চলে, তাহলে আপনার <uses-feature> এলিমেন্টে সেন্সরটি তালিকাভুক্ত করা উচিত, তবে ডেসক্রিপ্টরটি android:required="false"-এ সেট করুন। এটি নিশ্চিত করতে সাহায্য করে যে ডিভাইসে নির্দিষ্ট সেন্সর না থাকলেও আপনার অ্যাপ ইনস্টল করা যাবে। এটিও একটি প্রোজেক্ট ম্যানেজমেন্টের পেশাদার পদ্ধতি যা আপনার অ্যাপ্লিকেশন ব্যবহার করে এমন ফিচার ট্র্যাক করতে সাহায্য করে। মনে রাখবেন, আপনার অ্যাপ্লিকেশন যদি কোনও নির্দিষ্ট সেন্সর ব্যবহার করে, কিন্তু সেন্সর ছাড়াই চলে, তাহলে রানটাইমে আপনার সেন্সর শনাক্ত করা উচিত এবং উপযুক্ত হিসেবে অ্যাপ্লিকেশন ফিচার বন্ধ বা চালু করা উচিত।

সেন্সর কোঅর্ডিনেট সিস্টেম

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

ছবি ১. Sensor API-এর মাধ্যমে ব্যবহার করা কোঅর্ডিনেট সিস্টেম (ডিভাইসের সাপেক্ষে)।

এই কোঅর্ডিনেট সিস্টেম সম্পর্কে বোঝার জন্য সবচেয়ে গুরুত্বপূর্ণ পয়েন্ট হল যে ডিভাইসের স্ক্রিন ওরিয়েন্টেশন পরিবর্তন হলে অক্ষগুলি অদলবদল হয় না—অর্থাৎ, ডিভাইসটি সরানোর সাথে সাথে সেন্সরের কোঅর্ডিনেট সিস্টেম কখনই পরিবর্তিত হয় না। এই আচরণ OpenGL কোঅর্ডিনেট সিস্টেমের আচরণের মতোই।

আরেকটি বিষয় হল, আপনার অ্যাপ্লিকেশনকে কখনই ধরে নিলে চলবে না যে ডিভাইসের স্বাভাবিক (ডিফল্ট) ওরিয়েন্টেশন হল পোর্ট্রেট। অনেক ট্যাবলেট ডিভাইসের জন্য স্বাভাবিক ওরিয়েন্টেশন হল ল্যান্ডস্কেপ। এবং সেন্সর কোঅর্ডিনেট সিস্টেম সবসময় ডিভাইসের স্বাভাবিক ওরিয়েন্টেশনের উপর ভিত্তি করে কাজ করে।

সবশেষে, আপনার অ্যাপ্লিকেশন যদি অন-স্ক্রিন ডিসপ্লের সাথে সেন্সর ডেটা ম্যাচ করে, তাহলে স্ক্রিন রোটেশন নির্ধারণ করতে আপনাকে getRotation() পদ্ধতি ব্যবহার করতে হবে এবং তারপর স্ক্রিন কোঅর্ডিনেটে সেন্সর কোঅর্ডিনেট ম্যাপ করতে remapCoordinateSystem() পদ্ধতি ব্যবহার করতে হবে। আপনার ম্যানিফেস্টে শুধুমাত্র পোর্ট্রেট ডিসপ্লে উল্লেখ করা থাকলেও আপনাকে এটি করতে হবে।

মনে রাখবেন: কিছু সেন্সর ও পদ্ধতি এমন একটি কোঅর্ডিনেট সিস্টেম ব্যবহার করে যা পৃথিবীর ফ্রেম অফ রেফারেন্সের (ডিভাইসের ফ্রেম অফ রেফারেন্সের বিপরীতে) সাথে সম্পর্কিত। এইসব সেন্সর ও পদ্ধতি এমন ডেটা রিটার্ন করে যা পৃথিবীর সাপেক্ষে ডিভাইসের গতি বা ডিভাইসের অবস্থান দেখায়। আরও তথ্যের জন্য, getOrientation() পদ্ধতি, getRotationMatrix() পদ্ধতি, ওরিয়েন্টেশন সেন্সর এবং রোটেশন ভেক্টর সেন্সর দেখুন।

সেন্সর রেট-লিমিটিং

ব্যবহারকারীদের সম্ভাব্য সংবেদনশীল তথ্য সুরক্ষিত রাখতে, আপনার অ্যাপ Android 12 (API লেভেল 31) বা তার পরবর্তী ভার্সনকে টার্গেট করলে, সিস্টেম নির্দিষ্ট মোশন সেন্সর এবং পজিশন সেন্সর থেকে ডেটার রিফ্রেশ রেটের উপর একটি সীমা আরোপ করে। এই ডেটায় ডিভাইসের অ্যাকসিলরোমিটার, জাইরোস্কোপ এবং জিওম্যাগনেটিক ফিল্ড সেন্সর দ্বারা রেকর্ড করা ভ্যালু অন্তর্ভুক্ত থাকে।

আপনি কীভাবে সেন্সর ডেটা অ্যাক্সেস করেন তার উপর রিফ্রেশ রেটের সীমা নির্ভর করে:

  • আপনি যদি সেন্সর ইভেন্ট মনিটর করতে registerListener() মেথড কল করেন, তাহলে সেন্সর স্যাম্পলিং রেট ২০০ Hz-এ সীমিত করা হয়। এটি registerListener() মেথডের সব ওভারলোড করা ভেরিয়েন্টের ক্ষেত্রে প্রযোজ্য।
  • আপনি যদি SensorDirectChannel ক্লাস ব্যবহার করেন, তাহলে সেন্সর স্যাম্পলিং রেট RATE_NORMAL-এ সীমিত থাকে, যা সাধারণত ৫০ Hz-এর কাছাকাছি।

আপনার অ্যাপকে যদি আরও বেশি রেটে মোশন সেন্সর ডেটা সংগ্রহ করতে হয়, তাহলে আপনাকে অবশ্যই HIGH_SAMPLING_RATE_SENSORS অনুমতি ঘোষণা করতে হবে, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে। অন্যথায়, আপনার অ্যাপ যদি এই অনুমতি ঘোষণা না করে আরও বেশি রেটে মোশন সেন্সর ডেটা সংগ্রহ করার চেষ্টা করে, তাহলে SecurityException হয়।

AndroidManifest.xml

<manifest ...>
    <uses-permission android:name="android.permission.HIGH_SAMPLING_RATE_SENSORS"/>
    <application ...>
        ...
    </application>
</manifest>

সেন্সর অ্যাক্সেস ও ব্যবহার করার পেশাদার পদ্ধতি

আপনার সেন্সর প্রয়োগের ডিজাইন করার সময়, এই বিভাগে আলোচনা করা নির্দেশিকাগুলি অনুসরণ করতে ভুলবেন না। সেন্সর অ্যাক্সেস করতে এবং সেন্সর ডেটা পেতে সেন্সর ফ্রেমওয়ার্ক ব্যবহার করছেন এমন যেকোনও ব্যক্তির জন্য এই নির্দেশিকাগুলি হল সাজেস্ট করা পেশাদার পদ্ধতি।

শুধুমাত্র ফোরগ্রাউন্ডে সেন্সর ডেটা সংগ্রহ করুন

Android 9 (API লেভেল ২৮) বা তার পরবর্তী যেকোনও ভার্সনে চলা ডিভাইসে, ব্যাকগ্রাউন্ডে চলা অ্যাপের ক্ষেত্রে নিম্নলিখিত বিধিনিষেধ প্রযোজ্য:

  • যেসব সেন্সর ক্রমাগত রিপোর্টিং মোড ব্যবহার করে, যেমন অ্যাকসিলরোমিটার ও জাইরোস্কোপ, সেগুলি ইভেন্ট রিসিভ করে না।
  • যেসব সেন্সর পরিবর্তন-হলে বা এক-শট রিপোর্টিং মোড ব্যবহার করে সেগুলি ইভেন্ট রিসিভ করে না।

এইসব বিধিনিষেধের কারণে, আপনার অ্যাপ ফোরগ্রাউন্ডে থাকলে অথবা ফোরগ্রাউন্ড সার্ভিস-এর অংশ হিসেবে সেন্সর ইভেন্ট শনাক্ত করা সবচেয়ে ভালো।

সেন্সর লিসেনার আনরেজিস্টার করুন

সেন্সর ব্যবহার করা হয়ে গেলে বা সেন্সর অ্যাক্টিভিটি পজ করা হলে, সেন্সরের লিসেনার আনরেজিস্টার করতে ভুলবেন না। কোনও সেন্সর লিসেনার রেজিস্টার করা থাকলে এবং তার অ্যাক্টিভিটি পজ করা থাকলে, সেন্সরটি ডেটা সংগ্রহ করা এবং ব্যাটারি রিসোর্স ব্যবহার করা চালিয়ে যাবে, যতক্ষণ না আপনি সেন্সরটি আনরেজিস্টার করছেন। নিচের কোড থেকে জানা যায় যে কীভাবে onPause() পদ্ধতি ব্যবহার করে লিসেনারকে আনরেজিস্টার করতে হয়:

Kotlin

private lateinit var sensorManager: SensorManager
...
override fun onPause() {
    super.onPause()
    sensorManager.unregisterListener(this)
}

জাভা

private SensorManager sensorManager;
...
@Override
protected void onPause() {
    super.onPause();
    sensorManager.unregisterListener(this);
}

আরও তথ্যের জন্য, unregisterListener(SensorEventListener) দেখুন।

Android Emulator-এর মাধ্যমে পরীক্ষা করা

Android এমুলেটরে ভার্চুয়াল সেন্সর কন্ট্রোলের একটি সেট থাকে যা আপনাকে অ্যাকসিলরোমিটার, অ্যাম্বিয়েন্ট তাপমাত্রা, ম্যাগনেটোমিটার, প্রক্সিমিটি, আলো এবং আরও অনেক কিছুর মতো সেন্সর পরীক্ষা করার অনুমতি দেয়।

এমুলেটরটি এমন একটি Android ডিভাইসের সাথে কানেকশন ব্যবহার করে যা SdkControllerSensor অ্যাপ চালাচ্ছে। মনে রাখবেন যে এই অ্যাপটি শুধুমাত্র Android 4.0 (API লেভেল 14) বা তার পরবর্তী যেকোনও ভার্সনে চলা ডিভাইসে উপলভ্য। (ডিভাইসটি Android 4.0-এ চললে, এতে অবশ্যই সংশোধন 2 ইনস্টল করা থাকতে হবে।) SdkControllerSensor অ্যাপ ডিভাইসের সেন্সরে হওয়া পরিবর্তন মনিটর করে এবং এমুলেটরে তা ট্রান্সমিট করে। তারপর, আপনার ডিভাইসের সেন্সর থেকে পাওয়া নতুন ভ্যালুর ভিত্তিতে এমুলেটরটি ট্রান্সফর্ম করা হয়।

আপনি নিম্নলিখিত লোকেশনে SdkControllerSensor অ্যাপের সোর্স কোড দেখতে পারবেন:

$ your-android-sdk-directory/tools/apps/SdkController

আপনার ডিভাইস ও এমুলেটরের মধ্যে ডেটা ট্রান্সফার করতে, এইসব ধাপ অনুসরণ করুন:

  1. আপনার ডিভাইসে USB ডিবাগিং চালু করা আছে কিনা তা চেক করুন।
  2. USB কেবেল ব্যবহার করে আপনার ডেভেলপমেন্ট মেশিনের সাথে ডিভাইস কানেক্ট করুন।
  3. আপনার ডিভাইসে SdkControllerSensor অ্যাপ চালু করুন।
  4. অ্যাপে, আপনি যে সেন্সর এমুলেট করতে চান সেটি বেছে নিন।
  5. নিম্নলিখিত adb কমান্ড রান করুন:

  6. $ adb forward tcp:1968 tcp:1968
    
  7. ইমুলেটর চালু করুন। এখন আপনার ডিভাইস সরানোর মাধ্যমে এমুলেটরে ট্রান্সফর্মেশন প্রয়োগ করতে পারবেন।

মনে রাখবেন: আপনার ফিজিক্যাল ডিভাইসে আপনি যে মুভমেন্ট করেন তা যদি এমুলেটরকে ট্রান্সফর্ম না করে, তাহলে ৫ নম্বর ধাপ থেকে adb কমান্ড আবার রান করার চেষ্টা করুন।

আরও তথ্যের জন্য, Android এমুলেটর নির্দেশিকা দেখুন।

onSensorChanged() পদ্ধতি ব্লক করবেন না

সেন্সর ডেটা দ্রুত পরিবর্তিত হতে পারে, যার অর্থ হল সিস্টেমটি প্রায়শই onSensorChanged(SensorEvent) মেথড কল করতে পারে। পেশাদার পদ্ধতি হিসেবে, onSensorChanged(SensorEvent) পদ্ধতির মধ্যে আপনার যতটা সম্ভব কম কাজ করা উচিত যাতে আপনি এটি ব্লক না করেন। আপনার অ্যাপ্লিকেশনে যদি কোনও ডেটা ফিল্টার করা বা সেন্সর ডেটা কমানোর প্রয়োজন হয়, তাহলে আপনাকে onSensorChanged(SensorEvent) মেথডের বাইরে সেই কাজ করতে হবে।

বাতিল করা পদ্ধতি বা সেন্সরের ধরন ব্যবহার করা এড়িয়ে চলুন

বেশ কিছু পদ্ধতি ও কনস্ট্যান্ট অবচিত করা হয়েছে। বিশেষ করে, TYPE_ORIENTATION সেন্সরের ধরন বন্ধ করে দেওয়া হয়েছে। ওরিয়েন্টেশন ডেটা পেতে, আপনাকে পরিবর্তে getOrientation() পদ্ধতি ব্যবহার করতে হবে। একইভাবে, TYPE_TEMPERATURE সেন্সরের ধরন বন্ধ করে দেওয়া হয়েছে। Android 4.0 ভার্সনে রান করা ডিভাইসে আপনাকে TYPE_AMBIENT_TEMPERATURE সেন্সর টাইপ ব্যবহার করতে হবে।

ব্যবহার করার আগে সেন্সর যাচাই করুন

কোনও ডিভাইস থেকে ডেটা নেওয়ার চেষ্টা করার আগে সবসময় যাচাই করে নিন যে ডিভাইসে সেন্সর আছে কিনা। কোনও সেন্সর প্রায়শই ব্যবহার করা হয় বলে সেটি আছে বলে ধরে নেবেন না। ডিভাইস প্রস্তুতকারকদের তাদের ডিভাইসে কোনও নির্দিষ্ট সেন্সর প্রদান করার প্রয়োজন নেই।

সেন্সর ডিলে সাবধানে বেছে নিন

registerListener() পদ্ধতির মাধ্যমে সেন্সর রেজিস্টার করার সময়, আপনার অ্যাপ্লিকেশন বা ব্যবহারের ক্ষেত্রে উপযুক্ত ডেলিভারি রেট বেছে নিতে ভুলবেন না। সেন্সর খুব বেশি রেটে ডেটা প্রদান করতে পারে। সিস্টেমকে অতিরিক্ত ডেটা পাঠানোর অনুমতি দিলে, যা আপনার প্রয়োজন নেই, তা সিস্টেম রিসোর্স নষ্ট করে এবং ব্যাটারির চার্জ ব্যবহার করে।