Android Floating Widget
Floating Widget আমরা মোটামুটি সবাই ব্যবহার করছি । যা আমরা Messenger Chat Head নামে জানি। সম্পূর্ণটাও যদিও চ্যাট হেডের মত বানাতে পারি নাই তারপর ও চেষ্টা করছি, যতটুকু সম্ভব করলাম আরকি। এখনো গ্রোগ্রামিং এর লাইনে বাচ্চা, কেবল হাতে খড়ি দিচ্ছি। তাই ভাবলাম এই কোড টুকু নোট করে রাখি সাথে একটু সবার সাথে শেয়ার ও করে রাখি।
তা কথা না বাড়িয়ে কাজে লেগে পরি। ফ্লোটিং উইজেট (Widget-“উইজেট”, according to Google Translate) এর প্রাকটিসের জন্যে আমরা নিজের স্ক্রিনশর্ট এর মত একটি এপ বানাবো।
আমাদের এই এপটি বানাতে যা যা লাগবে তা হলো -
1. Activity
2. Service
3. Widget Layout (xml)
যেহেতু আমাদের এপটি ব্যাকগ্রাউন্ড থেকে কেটে দিলেও আমাদের এপ চলবে তাই আমরা এখানে service ব্যবহার করবো। তাই আমরা একটি Blank Project Create করার পর একটি Service ও বানিয়ে ফেলব, আমি যার নাম দিলাম “Floating_Widget_Service.java” । MainActivity তে আমাদের একটি ছোট্ট কাজ করে নিতে হবে যা হলো আমাদের একটি Overlay পার্মিশন নিতে হবে । তার জন্যে আমরা নিচের কোড টুকু লিখে ফেলবো।
চাইলে onActivityResult দিয়ে পার্মিশনটে চেক ও করে নিতে পারেন। এটা অবশ্যই ভালো অভ্যাস ।
পারমিশনের জন্যে আরো একটি কাজ করতে হবে। যা হলো Manifest.xml এ রেজিস্টার করে নিতে হবে
এবার আসবো আসল খেলায়। সবাই রেডি তো ? 😎 ভালো মত প্যান্টের বেল্ট টাইট করে Activity Class থেকে Floating_Widget_Service.java তে ঝাপ দেন।
আচ্ছা আচ্ছা ওয়েট, ঝাপ একটু পরে দিয়েন । সার্ভিস ক্লাসে ঝাপ দেয়ার আগে Widget এর লেয়াউট টা ডিজাইন করে নেই নাকি ?
আমার লেআউট এভাবে ডিজাইন করলাম (বাচ্চা মানুষ কম পারি 👶👶), আপনে আপনার পছন্দ মত করে দিয়েন।
লেআউট ২ টি ইমেজ ভিউ যার একটি আমরা ব্যবহার করবো Widget টি বন্ধ করতে।
হা এবার সময় এসে গেছে, এবার সার্ভিস ক্লাসে ঝাপ দিন। 🔥🔥
এবারে আমরা Service class এর onCreate() এর মধ্যে WindowManager এবং LayoutParams সাহায্যে আমাদের ফ্লোটিং উইজেট কে ঠিকঠাক করবো। যেহেতু widget.xml সম্পূর্ণটাই একটি ভিউ তাই আমরা View class এর মধ্যে উইজেটের ভিউকে আগে inflate করে নিব
private View view;
WindowManager windowManager;
WindowManager.LayoutParams layoutParams;view = LayoutInflater.from(this).inflate(R.layout.widget,null);
এখন একটু কাহীনি আছে, সেটা হলো Android Version । এটা আমার কাছে প্রচুর বিরতকর। দেখাযায় একেক ভার্সসে একটা ফিচার সাপোর্ট করে অন্য ভার্সনে সেটা সাপোর্ট করে না। (সার্ভিস নিয়ে কথা নাই বললাম 🥺) তাই এখানে layoutParams এ Oreo (Android O) version থেকে তার উপরের ভার্সন গুলায় “TYPE_APPLICATION_OVERLAY” প্যারামিটার পাস করবো, আর তার নিচের ভার্সন গুলায় “TYPE_PHONE” প্যারামিটার পাস করবো। বাকি সব সেম রেখে নিচের ছবিটা খেয়াল করুন।
আমার এখানে Programmatically Layout সেট করলাম এখন আমরা Layout Positioning এ ফোকাস করবো আমরা উইজাড লেয়াউট এর X-axis & Y-axis 0 (zero) দিবো এতে এপটি একদম Center পজিশনে আসবে । এক্ষেত্রে আপনি গ্রাভিটিও সেট করে দিতে পারেন
layoutParams.gravity = Gravity.CENTER;
এখন শেষ কাজ, আমরা নোটিফিকেশন ম্যানেজার থেকে যেমন getSystemService ব্যবহার করি তেমনি WindowManager এও আমরা getSystemService ব্যবহার করবো এবং এর পর পরই আমরা আমাদের ভিউ এবং লেয়াউট উইন্ডো ম্যানেজারে এড করে দিব
এখন আমাদের এপ বিল্ড ও রান হওয়ার জন্যে প্রস্তুত। এখন এপ রান করলে অনেকটা এমন ভিউ পাবো-
বাহ এখন আমরা আমাদের ফ্লোটিং উইন্ডো দেখতে পারছি । আমরা যদি আমাদের এপ বন্ধ করে দেই তবুও আমরা আমাদের ফ্লোটিং উইন্ডো দেখতে পারবো । কিন্তু এখনেও কিছু বিষয় আছে।
প্রথমত, আমরা আমাদের এপটা মেসেঞ্জার এপের মত মুভ করাতে পারছি না,
দ্বিতীয়ত, ফ্লোটিং উইন্ডো বন্ধ করতে পারছি না
তৃতীয়ত, অনেকের ক্ষেত্রে দেখা যেতে পারে এপ বন্ধ করার কিছুক্ষন পর ফ্লোটিং উইন্ডো বন্ধ হয়ে যাচ্ছে কিংবা ফ্লোটিং উইজাড রিস্টার্ট নিচ্ছে।
এখন আমরা একটি একটি করে সব গুলোর সমাধান করবো :)
প্রথমে আমরা দ্বিতীয়ত , সমস্যার সমাধান করবো। এর জন্যে নিচের কোড টুকু লিখলেই সমস্যার সমাধান হয়ে যাবে
এখন আসি তৃতীয় সমস্যায়, এখানে এপ বার বার রিস্টার্ট হবার কারণ হলো সার্ভিস। যেমনটা আগে বলছিলাম, দিন দিন Android Version যত আপডেট হচ্ছে এন্ড্রয়েডের কম্পোনেন্ট গুলো তত কমপ্লিকেটেড হচ্ছে আর ঝামেলা বাড়াচ্ছে। এপ যখন ব্যাকগ্রাউন্ডে রাখা হয় তখন Oreo বা তার থেকে উপরের ভার্সন গুলায় একটা সময় পর সার্ভিস বন্ধ হয়ে যায়। এক্ষেত্রে সেগুলো তে Foreground Servce রান করাতে হবে তাহলেই সমস্যার সমাধান। আপাতত আমি অত ঝামেলায় না গিয়ে ফ্লোটিং উইন্ডো রিস্টার্ট এড়াতে একটি মেথড কল করব যা হলো “onStartCommand” এবং এর রিটার্ন হিসেবে দিবো “START_STICKY” —
এই গেল দুইটা সমস্যা, এবার আমরা প্রথম সমস্যার দিকে ধাবিত হবো, বাট আমি তার ওতো বর্ণনা দিতে পাবো না। এটার মেইন কাহীনি হলে ACTION_DOWN হলে ফ্লোটিং উইজাড কোথায় আছে তার Axis নেয়া এবং ফ্লোটিং উইজাড মুভ করলে Window Manager এ নতুন Axis Update করা।
কোড সব ঠিক ঠাক ভাবে করলে এপ খুব সুন্দর ভাবে চলবে, পুরো প্রোজেকট গিটহাবে আছে দেখে নিতে পারেন
https://github.com/saadh393/Floating_Widget
কেউ যদি আরো সুন্দর বা আরো ইম্প্রুভ করতে পারেন প্লিজ জানাবেন