অ্যালার্ম শিডিউল করা

অ্যালার্ম (AlarmManager ক্লাসের উপর ভিত্তি করে) আপনাকে আপনার অ্যাপ্লিকেশনের লাইফটাইমের বাইরে সময়-ভিত্তিক অপারেশন পারফর্ম করার উপায় প্রদান করে। যেমন, আপনি কোনও দীর্ঘ-চলমান অপারেশন শুরু করার জন্য অ্যালার্ম ব্যবহার করতে পারেন, যেমন আবহাওয়ার পূর্বাভাস ডাউনলোড করার জন্য দিনে একবার পরিষেবা শুরু করা।

অ্যালার্মের এইসব বৈশিষ্ট্য আছে:

  • এগুলি আপনাকে সেট করা সময় এবং/অথবা বিরতিতে ইনটেন্ট ফায়ার করতে দেয়।

  • আপনি সম্প্রচার রিসিভারের সাথে এগুলি ব্যবহার করে জব বা WorkRequests শিডিউল করতে পারেন যাতে অন্যান্য অপারেশন করা যায়।

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

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

অনির্দিষ্ট অ্যালার্ম সেট করুন

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

ডেভেলপাররা নিম্নলিখিত API গ্যারান্টির সুবিধা নিয়ে, অনির্দিষ্ট অ্যালার্ম ডেলিভারির সময় কাস্টমাইজ করতে পারেন।

নির্দিষ্ট সময়ের পরে অ্যালার্ম বাজায়

আপনার অ্যাপ set(), setInexactRepeating(), বা setAndAllowWhileIdle() কল করলে, প্রদান করা ট্রিগার সময়ের আগে অ্যালার্ম কখনও বন্ধ হয় না।

Android ১২ (API লেভেল ৩১) এবং তার পরবর্তী ভার্সনে, সিস্টেম ট্রিগার করার সময়ের এক ঘণ্টার মধ্যে অ্যালার্ম বাজায়, যদি না ব্যাটারি সেভার বা ডোজ-এর মতো কোনও ব্যাটারি-সেভিং সংক্রান্ত বিধিনিষেধ কার্যকর থাকে।

নির্দিষ্ট সময়সীমার মধ্যে অ্যালার্ম ডেলিভার করা

আপনার অ্যাপ setWindow() কল করলে, অ্যালার্ম কখনই প্রদত্ত ট্রিগার সময়ের আগে বন্ধ হয় না। ব্যাটারি সাশ্রয় সংক্রান্ত কোনও বিধিনিষেধ কার্যকর না থাকলে, নির্দিষ্ট ট্রিগার টাইম থেকে শুরু করে নির্দিষ্ট সময়সীমার মধ্যে অ্যালার্ম ডেলিভার করা হয়।

আপনার অ্যাপ Android ১২ বা তার পরবর্তী ভার্সনকে টার্গেট করলে, সিস্টেম টাইম-উইন্ডো করা ইন-একজ্যাক্ট অ্যালার্মের ইনভোকেশন অন্তত ১০ মিনিট দেরি করতে পারে। এই কারণে, 600000-এর নিচে windowLengthMillis প্যারামিটারের ভ্যালু সাধারণত 600000-এ ক্লিপ করা হয়। সিস্টেমটি ছোট উইন্ডোকে জায়গা দিতে পারে, বিশেষ করে যদি অ্যালার্মটি অদূর ভবিষ্যতে ট্রিগার করার জন্য শিডিউল করা হয়।

মোটামুটি নিয়মিত বিরতিতে রিপিট হওয়া অ্যালার্ম ডেলিভার করা

আপনার অ্যাপ setInexactRepeating() কল করলে, সিস্টেম একাধিক অ্যালার্ম চালু করে:

  1. প্রথম অ্যালার্মটি নির্দিষ্ট ট্রিগার টাইম থেকে শুরু করে নির্দিষ্ট টাইম উইন্ডোর মধ্যে বেজে ওঠে।
  2. সাধারণত নির্দিষ্ট সময়সীমা পেরিয়ে যাওয়ার পরে পরবর্তী অ্যালার্ম বন্ধ হয়ে যায়। অ্যালার্মের পরপর দুটি ইনভোকেশনের মধ্যে সময়ের পার্থক্য আলাদা হতে পারে।

এক্স্যাক্ট অ্যালার্ম সেট করুন

সিস্টেম ভবিষ্যতে একটি নির্দিষ্ট মুহূর্তে একটি এক্স্যাক্ট অ্যালার্ম চালু করে।

বেশিরভাগ অ্যাপ অনির্দিষ্ট অ্যালার্ম ব্যবহার করে টাস্ক ও ইভেন্ট শিডিউল করতে পারে যাতে একাধিক সাধারণ ব্যবহারের ক্ষেত্র সম্পূর্ণ করা যায়। আপনার অ্যাপের মূল কার্যকারিতা যদি সুনির্দিষ্ট-সময়ের অ্যালার্মের উপর নির্ভর করে—যেমন অ্যালার্ম ক্লক অ্যাপ বা ক্যালেন্ডার অ্যাপ—তাহলে এর পরিবর্তে এক্স্যাক্ট অ্যালার্ম ব্যবহার করা যেতে পারে।

এমন ব্যবহারের ক্ষেত্র যেখানে এক্স্যাক্ট অ্যালার্মের প্রয়োজন নাও হতে পারে

নিচের তালিকায় এমন সাধারণ ওয়ার্কফ্লো দেখানো হয়েছে যেগুলির জন্য এক্স্যাক্ট অ্যালার্মের প্রয়োজন নাও হতে পারে:

আপনার অ্যাপের লাইফটাইম চলাকালীন টাইমিং অপারেশন শিডিউল করা
Handler ক্লাসে টাইমিং অপারেশন ম্যানেজ করার জন্য বেশ কিছু ভালো পদ্ধতি রয়েছে, যেমন আপনার অ্যাপ চালু থাকাকালীন প্রতি n সেকেন্ডে কিছু কাজ করা: postAtTime() এবং postDelayed()। মনে রাখবেন যে এইসব API সিস্টেম আপটাইম-এর উপর নির্ভর করে এবং রিয়েল টাইম-এর উপর নয়।
শিডিউল করা ব্যাকগ্রাউন্ড কাজ, যেমন আপনার অ্যাপ আপডেট করা এবং লগ আপলোড করা
WorkManager সময়ের উপর নির্ভর করে এমন পর্যায়ক্রমিক কাজ শিডিউল করার সুবিধা প্রদান করে। আপনি কাজের জন্য গ্র্যানুলার রানটাইম নির্ধারণ করতে পুনরাবৃত্তির ব্যবধান এবং flexInterval (ন্যূনতম ১৫ মিনিট) প্রদান করতে পারেন।
ব্যবহারকারীর নির্দিষ্ট করা অ্যাকশন যা নির্দিষ্ট সময় পরে হওয়া উচিত (এমনকি সিস্টেম আইডল অবস্থায় থাকলেও)
অনির্দিষ্ট অ্যালার্ম ব্যবহার করুন। বিশেষত, setAndAllowWhileIdle() নম্বরে কল করুন।
ব্যবহারকারীর নির্দিষ্ট করা অ্যাকশন যা নির্দিষ্ট সময়ের পরে হওয়া উচিত
অ্যালার্মের জন্য আনুমানিক সময় ব্যবহার করুন। বিশেষত, set() নম্বরে কল করুন।
ব্যবহারকারীর নির্দিষ্ট করা অ্যাকশন যা নির্দিষ্ট সময়সীমার মধ্যে হতে পারে
অনির্দিষ্ট অ্যালার্ম ব্যবহার করুন। বিশেষত, setWindow() নম্বরে কল করুন। মনে রাখবেন, আপনার অ্যাপ Android 12 বা তার পরবর্তী ভার্সনকে টার্গেট করলে, অনুমোদিত উইন্ডোর সবচেয়ে কম দৈর্ঘ্য হল ১০ মিনিট।

এক্স্যাক্ট অ্যালার্ম সেট করার উপায়

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

setExact()

ভবিষ্যতে প্রায় সঠিক সময়ে অ্যালার্ম চালু করুন, যতক্ষণ না অন্যান্য ব্যাটারি-সেভিং ব্যবস্থা কার্যকর হচ্ছে।

আপনার অ্যাপের কাজ ব্যবহারকারীর জন্য সময়-সংবেদনশীল না হলে, এক্স্যাক্ট অ্যালার্ম সেট করতে এই পদ্ধতি ব্যবহার করুন।

setExactAndAllowWhileIdle()

ব্যাটারি-সেভিং ব্যবস্থা কার্যকর থাকলেও, ভবিষ্যতে প্রায় সঠিক সময়ে অ্যালার্ম চালু করুন।

setAlarmClock()

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

সিস্টেম রিসোর্স কনজাম্পশন

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

সম্ভব হলে, আপনাকে ইনএক্স্যাক্ট অ্যালার্ম তৈরি করার জন্য বিশেষভাবে সাজেস্ট করা হচ্ছে। আরও বেশি সময় ধরে কাজ করতে, আপনার অ্যালার্মের BroadcastReceiver থেকে WorkManager বা JobScheduler ব্যবহার করে এটি শিডিউল করুন। ডিভাইস Doze মোডে থাকাকালীন কাজ করতে, setAndAllowWhileIdle() ব্যবহার করে একটি আনুমানিক অ্যালার্ম তৈরি করুন এবং অ্যালার্ম থেকে একটি কাজ শুরু করুন।

এক্স্যাক্ট অ্যালার্মের জন্য উপযুক্ত অনুমতি ঘোষণা করুন

আপনার অ্যাপ Android 12 বা এর পরের যেকোনও ভার্সনকে টার্গেট করলে, আপনাকে "অ্যালার্ম ও রিমাইন্ডার" বিশেষ অ্যাপ অ্যাক্সেস পেতে হবে। এটি করতে, আপনার অ্যাপের ম্যানিফেস্ট ফাইলে SCHEDULE_EXACT_ALARM অনুমতি ঘোষণা করুন, যেমনটি নিম্নলিখিত কোড স্নিপেটে দেখানো হয়েছে:

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

আপনার অ্যাপ Android 13 (API লেভেল 33) বা তার পরবর্তী যেকোনও ভার্সনকে টার্গেট করলে, আপনার কাছে SCHEDULE_EXACT_ALARM অথবা USE_EXACT_ALARM অনুমতি ঘোষণা করার বিকল্প থাকবে।

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

SCHEDULE_EXACT_ALARM এবং USE_EXACT_ALARM, দুটি অনুমতিই একই ধরনের ক্ষমতার ইঙ্গিত দিলেও, এগুলি আলাদাভাবে মঞ্জুর করা হয় এবং বিভিন্ন ব্যবহারের ক্ষেত্রে সহায়তা করে। আপনার অ্যাপে এক্স্যাক্ট অ্যালার্ম ব্যবহার করা উচিত এবং SCHEDULE_EXACT_ALARM বা USE_EXACT_ALARM অনুমতি ঘোষণা করা উচিত, শুধুমাত্র যদি আপনার অ্যাপে ব্যবহারকারী নিজে ইন্টার‌্যাক্ট করতে পারেন এমন ফাংশনের জন্য নির্দিষ্ট-সময়ের অ্যাকশন প্রয়োজন হয়।

USE_EXACT_ALARM

SCHEDULE_EXACT_ALARM

  • ব্যবহারকারী অনুমতি দিয়েছেন
  • ব্যবহারের আরও বেশি ক্ষেত্র
  • অ্যাপকে কনফার্ম করতে হবে যে অনুমতি প্রত্যাহার করা হয়নি

Android 13 (API লেভেল 33) এবং তার পরবর্তী ভার্সনকে টার্গেট করা অ্যাপের নতুন ইনস্টলেশনের ক্ষেত্রে SCHEDULE_EXACT_ALARM অনুমতি আগে থেকে মঞ্জুর করা হয় না। কোনও ব্যবহারকারী ব্যাক-আপ ও রিস্টোর অপারেশনের মাধ্যমে Android 14 অপারেটিং সিস্টেমের ডিভাইসে অ্যাপ ডেটা ট্রান্সফার করলে, নতুন ডিভাইসে SCHEDULE_EXACT_ALARM অনুমতি বাতিল করা হবে। তবে, আগে থেকে থাকা কোনও অ্যাপের কাছে এই অনুমতি থাকলে, ডিভাইস Android 14-এ আপগ্রেড করার সময় এটি আগে থেকেই মঞ্জুর করা থাকবে।

মনে রাখবেন: এক্স্যাক্ট অ্যালার্ম যদি OnAlarmListener অবজেক্ট ব্যবহার করে সেট করা হয়, যেমন setExact API-এর সাথে, তাহলে SCHEDULE_EXACT_ALARM অনুমতি প্রয়োজন হয় না।

SCHEDULE_EXACT_ALARM অনুমতি ব্যবহার করা হচ্ছে

USE_EXACT_ALARM-এর মতো নয়, SCHEDULE_EXACT_ALARM-এর অনুমতি অবশ্যই ব্যবহারকারীকে দিতে হবে। ব্যবহারকারী ও সিস্টেম, দুজনেই SCHEDULE_EXACT_ALARM-এর অনুমতি তুলে নিতে পারে।

আপনার অ্যাপকে অনুমতি দেওয়া হয়েছে কিনা তা চেক করতে, এক্স্যাক্ট অ্যালার্ম সেট করার চেষ্টা করার আগে canScheduleExactAlarms() কল করুন। আপনার অ্যাপের জন্য SCHEDULE_EXACT_ALARM অনুমতি তুলে নেওয়া হলে, আপনার অ্যাপ বন্ধ হয়ে যায় এবং ভবিষ্যতে সব এক্স্যাক্ট অ্যালার্ম বাতিল হয়ে যায়। এর অর্থ হল, canScheduleExactAlarms()-এর মাধ্যমে রিটার্ন করা ভ্যালু আপনার অ্যাপের সম্পূর্ণ লাইফসাইকেলের জন্য বৈধ থাকে।

আপনার অ্যাপকে SCHEDULE_EXACT_ALARMS অনুমতি দেওয়া হলে, সিস্টেম এটিকে ACTION_SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED ব্রডকাস্ট পাঠায়। আপনার অ্যাপে ব্রডকাস্ট রিসিভার প্রয়োগ করতে হবে যা নিম্নলিখিত কাজগুলি করে:

  1. আপনার অ্যাপে এখনও বিশেষ অ্যাপ অ্যাক্সেস আছে কিনা তা কনফার্ম করে। এটি করতে, canScheduleExactAlarms() নম্বরে কল করুন। এই চেক আপনার অ্যাপকে এমন পরিস্থিতি থেকে রক্ষা করে যেখানে ব্যবহারকারী আপনার অ্যাপকে অনুমতি দেন, তারপর প্রায় সাথে সাথেই তা প্রত্যাহার করে নেন।
  2. আপনার অ্যাপের বর্তমান অবস্থার উপর ভিত্তি করে, অ্যাপের প্রয়োজন এমন যেকোনও এক্স্যাক্ট অ্যালার্ম রিশিডিউল করে। এই লজিকটি আপনার অ্যাপের মতোই হতে হবে, যখন এটি ACTION_BOOT_COMPLETED ব্রডকাস্ট রিসিভ করে।

ব্যবহারকারীদের SCHEDULE_EXACT_ALARM অনুমতি দিতে বলুন

এই বিকল্পকে 'অ্যালার্ম এবং রিমাইন্ডার সেট করার অনুমতি দিন' বলা হয়
ছবি ১. সিস্টেম সেটিংসে "অ্যালার্ম ও রিমাইন্ডার" বিশেষ অ্যাপ অ্যাক্সেস পৃষ্ঠা, যেখানে ব্যবহারকারীরা আপনার অ্যাপকে এক্স্যাক্ট অ্যালার্ম সেট করার অনুমতি দিতে পারেন।

প্রয়োজন হলে, আপনি ব্যবহারকারীদের সিস্টেম সেটিংসের অ্যালার্ম ও রিমাইন্ডার স্ক্রিনে পাঠাতে পারেন, যেমনটি ছবি ১-এ দেখানো হয়েছে। এটি করতে, নিম্নলিখিত ধাপগুলি সম্পূর্ণ করুন:

  1. আপনার অ্যাপের UI-তে, ব্যবহারকারীকে ব্যাখ্যা করুন যে কেন আপনার অ্যাপকে এক্স্যাক্ট অ্যালার্ম শিডিউল করতে হবে।
  2. এমন একটি ইনটেন্ট ইনভোক করুন যাতে ACTION_REQUEST_SCHEDULE_EXACT_ALARM ইনটেন্ট অ্যাকশন অন্তর্ভুক্ত থাকে।

রিপিট করা অ্যালার্ম সেট করুন

পুনরাবৃত্ত অ্যালার্ম সিস্টেমকে আপনার অ্যাপকে একটি পুনরাবৃত্তিতে বিজ্ঞপ্তি দেওয়ার অনুমতি দেয় সময়সূচী।

খারাপভাবে ডিজাইন করা অ্যালার্মের কারণে ব্যাটারি দ্রুত শেষ হয়ে যেতে পারে এবং সার্ভারের উপর অতিরিক্ত চাপ সৃষ্টি হতে পারে। এই কারণে, Android 4.4 (API লেভেল ১৯) এবং তার পরবর্তী ভার্সনে, সব রিপিট করা অ্যালার্ম হল ইনএক্স্যাক্ট অ্যালার্ম।

রিপিট করা অ্যালার্মের নিম্নলিখিত বৈশিষ্ট্য আছে:

  • অ্যালার্মের ধরন। আরও আলোচনার জন্য, অ্যালার্মের ধরন বেছে নিন দেখুন।

  • ট্রিগার টাইম। আপনার উল্লেখ করা ট্রিগারের সময় যদি আগে হয়ে গিয়ে থাকে, তাহলে অ্যালার্ম তৎক্ষণাৎ ট্রিগার হয়।

  • অ্যালার্মের ইন্টারভ্যাল। যেমন, দিনে একবার, প্রতি ঘণ্টায় বা প্রতি ৫ মিনিটে।

  • অ্যালার্ম ট্রিগার হলে পেন্ডিং ইনটেন্ট ফায়ার হয়। আপনি যখন একই পেন্ডিং ইনটেন্ট ব্যবহার করে দ্বিতীয় অ্যালার্ম সেট করেন, তখন এটি আসল অ্যালার্মকে সরিয়ে দেয়।

PendingIntent() বাতিল করতে, FLAG_NO_CREATE পাস করুন PendingIntent.getService()-এ যাতে ইনটেন্টের ইনস্ট্যান্স পাওয়া যায় (যদি থাকে), তারপর সেই ইনটেন্ট পাস করুন AlarmManager.cancel()-এ

Kotlin

val alarmManager =
    context.getSystemService(Context.ALARM_SERVICE) as? AlarmManager
val pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE)
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent)
}

জাভা

AlarmManager alarmManager =
    (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
PendingIntent pendingIntent =
    PendingIntent.getService(context, requestId, intent,
                                PendingIntent.FLAG_NO_CREATE);
if (pendingIntent != null && alarmManager != null) {
  alarmManager.cancel(pendingIntent);
}

অ্যালার্মের ধরন বেছে নিন

রিপিট করা অ্যালার্ম ব্যবহার করার সময় প্রথমে যে বিষয়টি বিবেচনা করতে হবে তা হল, এটি কী ধরনের হওয়া উচিত।

অ্যালার্মের জন্য সাধারণত দুই ধরনের ঘড়ি ব্যবহার করা হয়: "অতিবাহিত রিয়েল টাইম" এবং "রিয়েল টাইম ক্লক" (RTC)। Elapsed real time "time since system boot" রেফারেন্স হিসেবে ব্যবহার করে এবং real time clock UTC (wall clock) সময় ব্যবহার করে। এর অর্থ হল, অতিবাহিত রিয়েল টাইম, সময়ের অতিবাহিত হওয়ার উপর ভিত্তি করে অ্যালার্ম সেট করার জন্য উপযুক্ত (যেমন, এমন অ্যালার্ম যা প্রতি ৩০ সেকেন্ডে বেজে ওঠে) কারণ এটি টাইম জোন বা লোকাল দ্বারা প্রভাবিত হয় না। রিয়েল টাইম ক্লক টাইপ সেইসব অ্যালার্মের জন্য বেশি উপযুক্ত যেগুলি বর্তমান লোকেলের উপর নির্ভর করে।

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

আপনি যদি কোনও নির্দিষ্ট ব্যবধানে (যেমন, প্রতি আধ ঘণ্টা অন্তর) অ্যালার্ম বাজাতে চান, তাহলে রিয়েল টাইম টাইপ ব্যবহার করুন। সাধারণত, এটিই আরও ভালো বিকল্প।

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

এখানে প্রকারের তালিকা দেওয়া হল:

  • ELAPSED_REALTIME: ডিভাইস বুট করার পর থেকে অতিবাহিত সময়ের উপর ভিত্তি করে পেন্ডিং ইনটেন্ট ফায়ার করে, তবে ডিভাইস চালু করে না। ডিভাইস স্লিপ মোডে থাকাকালীন সময়ও অতিবাহিত সময়ের মধ্যে অন্তর্ভুক্ত থাকে।

  • ELAPSED_REALTIME_WAKEUP: ডিভাইস বুট হওয়ার পর থেকে নির্দিষ্ট সময় অতিবাহিত হওয়ার পরে ডিভাইসকে জাগিয়ে তোলে এবং পেন্ডিং ইনটেন্টকে ফায়ার করে।

  • RTC: নির্দিষ্ট সময়ে পেন্ডিং ইনটেন্ট ফায়ার করে কিন্তু ডিভাইস চালু করে না।

  • RTC_WAKEUP: নির্দিষ্ট সময়ে পেন্ডিং ইনটেন্ট ফায়ার করার জন্য ডিভাইসকে জাগিয়ে তোলে।

অতিক্রান্ত রিয়েল-টাইম অ্যালার্মের উদাহরণ

ELAPSED_REALTIME_WAKEUP ব্যবহার করার কিছু উদাহরণ এখানে দেওয়া হল

৩০ মিনিটের মধ্যে অ্যালার্ম বাজানোর জন্য ডিভাইস চালু করুন এবং তারপরে প্রতি ৩০ মিনিট অন্তর:

Kotlin

// Hopefully your alarm will have a lower frequency than this!
alarmMgr?.setInexactRepeating(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR,
        alarmIntent
)

জাভা

// Hopefully your alarm will have a lower frequency than this!
alarmMgr.setInexactRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + AlarmManager.INTERVAL_HALF_HOUR,
        AlarmManager.INTERVAL_HALF_HOUR, alarmIntent);

এক মিনিটের মধ্যে একবারের জন্য (রিপিট হবে না) অ্যালার্ম বাজাতে ডিভাইস চালু করুন:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

alarmMgr?.set(
        AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() + 60 * 1000,
        alarmIntent
)

জাভা

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

alarmMgr.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
        SystemClock.elapsedRealtime() +
        60 * 1000, alarmIntent);

রিয়েল-টাইম ক্লক অ্যালার্মের উদাহরণ

RTC_WAKEUP ব্যবহার করার কিছু উদাহরণ এখানে দেওয়া হল।

আনুমানিক দুপুর ২:০০ টায় অ্যালার্ম বাজানোর জন্য ডিভাইস চালু করুন এবং প্রতিদিন একই সময়ে একবার রিপিট করুন:

Kotlin

// Set the alarm to start at approximately 2:00 p.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 14)
}

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr?.setInexactRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        AlarmManager.INTERVAL_DAY,
        alarmIntent
)

জাভা

// Set the alarm to start at approximately 2:00 p.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 14);

// With setInexactRepeating(), you have to use one of the AlarmManager interval
// constants--in this case, AlarmManager.INTERVAL_DAY.
alarmMgr.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        AlarmManager.INTERVAL_DAY, alarmIntent);

সকাল ৮:৩০-এ অ্যালার্ম বাজানোর জন্য ডিভাইস চালু করুন এবং তারপরে প্রতি ২০ মিনিট অন্তর:

Kotlin

private var alarmMgr: AlarmManager? = null
private lateinit var alarmIntent: PendingIntent
...
alarmMgr = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager
alarmIntent = Intent(context, AlarmReceiver::class.java).let { intent ->
    PendingIntent.getBroadcast(context, 0, intent, 0)
}

// Set the alarm to start at 8:30 a.m.
val calendar: Calendar = Calendar.getInstance().apply {
    timeInMillis = System.currentTimeMillis()
    set(Calendar.HOUR_OF_DAY, 8)
    set(Calendar.MINUTE, 30)
}

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr?.setRepeating(
        AlarmManager.RTC_WAKEUP,
        calendar.timeInMillis,
        1000 * 60 * 20,
        alarmIntent
)

জাভা

private AlarmManager alarmMgr;
private PendingIntent alarmIntent;
...
alarmMgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
Intent intent = new Intent(context, AlarmReceiver.class);
alarmIntent = PendingIntent.getBroadcast(context, 0, intent, 0);

// Set the alarm to start at 8:30 a.m.
Calendar calendar = Calendar.getInstance();
calendar.setTimeInMillis(System.currentTimeMillis());
calendar.set(Calendar.HOUR_OF_DAY, 8);
calendar.set(Calendar.MINUTE, 30);

// setRepeating() lets you specify a precise custom interval--in this case,
// 20 minutes.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),
        1000 * 60 * 20, alarmIntent);

আপনার অ্যালার্ম কতটা নিখুঁত হতে হবে তা ঠিক করুন

আগে যেমন বলা হয়েছে, অ্যালার্ম তৈরি করার প্রথম ধাপ হল অ্যালার্মের ধরন বেছে নেওয়া। আরেকটি পার্থক্য হল, আপনার অ্যালার্ম কতটা নিখুঁত হতে হবে। বেশিরভাগ অ্যাপের জন্য, setInexactRepeating() সঠিক বিকল্প। আপনি এই পদ্ধতি ব্যবহার করলে, Android একাধিক আনুমানিক পুনরাবৃত্তিমূলক অ্যালার্ম সিঙ্ক করে এবং একই সময়ে সেগুলি ট্রিগার করে। এটি ব্যাটারির চার্জ কম খরচ করে।

সম্ভব হলে এক্স্যাক্ট অ্যালার্ম ব্যবহার করা এড়িয়ে চলুন। তবে, যেসব অ্যাপের ক্ষেত্রে সময়ের বাধ্যবাধকতা আছে, সেগুলির জন্য আপনি setRepeating()-এ কল করে এক্স্যাক্ট অ্যালার্ম সেট করতে পারেন।

setInexactRepeating()-এর মাধ্যমে, আপনি setRepeating()-এর মতো কাস্টম ইন্টারভ্যাল নির্দিষ্ট করতে পারবেন না। আপনাকে ইন্টারভ্যাল কনস্ট্যান্টের মধ্যে থেকে কোনও একটি ব্যবহার করতে হবে, যেমন INTERVAL_FIFTEEN_MINUTES, INTERVAL_DAY, এবং আরও অনেক কিছু। সম্পূর্ণ তালিকা দেখতে AlarmManager দেখুন।

অ্যালার্ম বাতিল করুন

আপনার অ্যাপের উপর নির্ভর করে, আপনি অ্যালার্ম বাতিল করার ক্ষমতা অন্তর্ভুক্ত করতে চাইতে পারেন। অ্যালার্ম বাতিল করতে, অ্যালার্ম ম্যানেজারে cancel() কল করুন, যে PendingIntent আপনি আর ফায়ার করতে চান না, সেটি পাস করুন। যেমন:

Kotlin

// If the alarm has been set, cancel it.
alarmMgr?.cancel(alarmIntent)

জাভা

// If the alarm has been set, cancel it.
if (alarmMgr!= null) {
    alarmMgr.cancel(alarmIntent);
}

ডিভাইস রিস্টার্ট হলে অ্যালার্ম শুরু করুন

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

এখানে ধাপগুলি দেওয়া হল:

  1. আপনার অ্যাপ্লিকেশনের ম্যানিফেস্টে RECEIVE_BOOT_COMPLETED অনুমতি সেট করুন। এটি আপনার অ্যাপকে ACTION_BOOT_COMPLETED রিসিভ করার অনুমতি দেয় যা সিস্টেম বুট করা শেষ করার পরে ব্রডকাস্ট করা হয় (এটি শুধুমাত্র তখনই কাজ করে যদি ব্যবহারকারী আগে থেকেই অন্তত একবার অ্যাপটি চালু করে থাকেন):

    <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
  2. ব্রডকাস্ট পেতে BroadcastReceiver প্রয়োগ করুন:

    Kotlin

    class SampleBootReceiver : BroadcastReceiver() {
    
        override fun onReceive(context: Context, intent: Intent) {
            if (intent.action == "android.intent.action.BOOT_COMPLETED") {
                // Set the alarm here.
            }
        }
    }

    জাভা

    public class SampleBootReceiver extends BroadcastReceiver {
    
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals("android.intent.action.BOOT_COMPLETED")) {
                // Set the alarm here.
            }
        }
    }
  3. আপনার অ্যাপের ম্যানিফেস্ট ফাইলে ইনটেন্ট ফিল্টার সহ রিসিভার যোগ করুন যা ACTION_BOOT_COMPLETED অ্যাকশন ফিল্টার করে:

    <receiver android:name=".SampleBootReceiver"
            android:enabled="false">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED"></action>
        </intent-filter>
    </receiver>

    লক্ষ্য করুন যে ম্যানিফেস্টে, বুট রিসিভার android:enabled="false"-এ সেট করা আছে। এর অর্থ হল, অ্যাপ্লিকেশন স্পষ্টভাবে চালু না করলে রিসিভারকে কল করা হবে না। এটি বুট রিসিভারকে অপ্রয়োজনে কল করা থেকে আটকায়। আপনি এইভাবে রিসিভার চালু করতে পারেন (যেমন, ব্যবহারকারী অ্যালার্ম সেট করলে):

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP
    )

    জাভা

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_ENABLED,
            PackageManager.DONT_KILL_APP);

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

    Kotlin

    val receiver = ComponentName(context, SampleBootReceiver::class.java)
    
    context.packageManager.setComponentEnabledSetting(
            receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP
    )

    জাভা

    ComponentName receiver = new ComponentName(context, SampleBootReceiver.class);
    PackageManager pm = context.getPackageManager();
    
    pm.setComponentEnabledSetting(receiver,
            PackageManager.COMPONENT_ENABLED_STATE_DISABLED,
            PackageManager.DONT_KILL_APP);

ডিভাইস Doze মোডে থাকাকালীন অ্যালার্ম চালু করা

Android 6.0 (API লেভেল ২৩) ভার্সনে চলে এমন ডিভাইসে Doze মোড কাজ করে, যা ডিভাইসের ব্যাটারির আয়ু বাড়াতে সাহায্য করে। ডিভাইস ডোজ মোডে থাকলে অ্যালার্ম বাজে না ডিভাইস ডোজ মোড থেকে না বের হওয়া পর্যন্ত যেকোনও শিডিউল করা অ্যালার্ম স্থগিত করা হয়। ডিভাইস আইডল থাকলেও আপনাকে কাজ সম্পূর্ণ করতে হলে, একাধিক বিকল্প উপলভ্য:

পেশাদার পদ্ধতি

আপনার রিপিটিং অ্যালার্ম ডিজাইন করার সময় আপনার নেওয়া প্রতিটি সিদ্ধান্ত, আপনার অ্যাপ কীভাবে সিস্টেম রিসোর্স ব্যবহার (বা অপব্যবহার) করে তার উপর প্রভাব ফেলতে পারে। যেমন, ধরুন একটি জনপ্রিয় অ্যাপ সার্ভারের সাথে সিঙ্ক করে। সিঙ্ক অপারেশন ঘড়ির সময়ের উপর নির্ভর করলে এবং অ্যাপের প্রতিটি ইনস্ট্যান্স রাত ১১:০০টায় সিঙ্ক করলে, সার্ভারের উপর লোড পড়ার কারণে লেটেন্সি বেড়ে যেতে পারে অথবা "পরিষেবা বন্ধ" হয়ে যেতে পারে। অ্যালার্ম ব্যবহার করার সময় এইসব পেশাদার পদ্ধতি অনুসরণ করুন:

  • রিপিট করা অ্যালার্মের ফলে ট্রিগার হওয়া যেকোনও নেটওয়ার্ক অনুরোধে র‍্যান্ডমনেস (জিটার) যোগ করুন:

    • অ্যালার্ম ট্রিগার হলে যেকোনও লোকাল কাজ করুন। "স্থানীয় কাজ" বলতে এমন কিছু বোঝায় যা সার্ভারে কোনও প্রভাব ফেলে না বা সার্ভার থেকে ডেটা প্রয়োজন হয় না।

    • একই সাথে, নেটওয়ার্ক অনুরোধ সহ অ্যালার্ম শিডিউল করুন যাতে কিছু র‍্যান্ডম সময় অন্তর তা ফায়ার হয়।

  • আপনার অ্যালার্মের ফ্রিকোয়েন্সি ন্যূনতম রাখুন।

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

  • আপনার অ্যালার্মের ট্রিগার টাইম যতটা সুনির্দিষ্ট হওয়া উচিত তার থেকে বেশি সুনির্দিষ্ট করবেন না।

    setRepeating()-এর পরিবর্তে setInexactRepeating() ব্যবহার করুন। আপনি setInexactRepeating() ব্যবহার করলে, Android একাধিক অ্যাপ থেকে রিপিট করা অ্যালার্ম সিঙ্ক করে এবং একই সময়ে সেগুলি ট্রিগার করে। এর ফলে সিস্টেমকে যতবার ডিভাইস চালু করতে হয় তার মোট সংখ্যা কমে যায়, যার ফলে ব্যাটারি কম খরচ হয়। Android 4.4 (API লেভেল ১৯) থেকে, সব রিপিট করা অ্যালার্ম হল ইনএক্স্যাক্ট অ্যালার্ম। মনে রাখবেন যে setInexactRepeating() setRepeating()-এর চেয়ে উন্নত হলেও, অ্যাপের প্রতিটি ইনস্ট্যান্স একই সময়ে সার্ভারে হিট করলে, এটি সার্ভারকে ওভারহোয়েল্ম করতে পারে। তাই, নেটওয়ার্ক অনুরোধের জন্য, আগে আলোচনা করা হয়েছে এমনভাবে আপনার অ্যালার্মে কিছু র‍্যান্ডমনেস যোগ করুন।

  • সম্ভব হলে, ঘড়ির সময়ের উপর ভিত্তি করে অ্যালার্ম সেট করবেন না।

    নির্দিষ্ট ট্রিগার সময়ের উপর ভিত্তি করে রিপিট হওয়া অ্যালার্ম ভালভাবে স্কেল করে না। সম্ভব হলে ELAPSED_REALTIME ব্যবহার করুন। বিভিন্ন ধরনের অ্যালার্মের বিবরণ নিম্নলিখিত বিভাগে আরও বিস্তারিতভাবে দেওয়া হয়েছে।