পারমিশন মডেল — রানটাইম পারমিশন
এই পাঠে যা শিখবেন
- রানটাইম পারমিশন কী এবং install-time পারমিশনের চেয়ে কেন এটি ভালো ডিজাইন
- একটি পারমিশনের তিনটি স্টেট এবং তাদের মধ্যে বৈধ ট্রানজিশন
- একটি সত্যিকারের পারমিশন স্টেট মেশিন এবং একটি অ্যাকশন-গেটিং ফাংশন যা কল করার মুহূর্তে সত্যিকারের স্ট্যাটাস চেক করে
- কেন "একবার গ্রান্ট পেয়েছি" ধরে নেওয়া একটি ভুল ডিজাইন প্যাটার্ন
১ · রানটাইম পারমিশন কী ও কেন
রানটাইম পারমিশনRuntime Permissionএমন একটি অনুমতি ব্যবস্থা যেখানে স্পর্শকাতর ডিভাইস ফিচার (ক্যামেরা, লোকেশন, মাইক্রোফোন, কন্টাক্টস) ব্যবহারের অনুমতি অ্যাপ চলাকালীন, ঠিক যখন প্রয়োজন তখন চাওয়া হয় — ইনস্টলের সময় একসাথে সব চাওয়া হয় না। আধুনিক Android (API 23+) ও iOS — দুটোই এই মডেল অনুসরণ করে। এটি ইউজারকে প্রেক্ষাপট দেয় — যখন কেউ "ছবি তুলুন" বাটনে চাপে, তখনই ক্যামেরা পারমিশন চাওয়া হলে ইউজার বুঝতে পারে ঠিক কেন এই অনুমতি দরকার, অ্যাপ খোলার মুহূর্তেই একগাদা অপ্রাসঙ্গিক পারমিশন চাওয়ার চেয়ে এটি অনেক বেশি স্বচ্ছ।
কিন্তু এর মানে হলো — একটি অ্যাপ কখনোই নিশ্চিতভাবে ধরে নিতে পারে না যে কোনো পারমিশন "থাকবেই"। ইউজার প্রত্যাখ্যান করতে পারে, পরে সেটিংস থেকে পারমিশন কেড়ে নিতে পারে, অথবা একেবারেই কখনো জিজ্ঞাসা করা হয়নি এমন অবস্থায় থাকতে পারে। তাই প্রতিটি স্পর্শকাতর অ্যাকশনের আগে সত্যিকারের বর্তমান স্ট্যাটাস — অনুমান নয় — যাচাই করা আবশ্যক।
২ · তিনটি স্টেট ও তাদের ট্রানজিশন
denied থেকেও ইউজার সেটিংসে গিয়ে অনুমতি দিলে অ্যাপ আবার request_permission কল করে granted-এ যেতে পারে।অ্যাপ এখনো এই পারমিশন চায়নি — কোনো স্পর্শকাতর অ্যাকশন এখনো চলার সুযোগ নেই।
ইউজার স্পষ্টভাবে অনুমতি দিয়েছে — সংশ্লিষ্ট অ্যাকশন এখন চলতে পারবে, যতক্ষণ না ইউজার সেটিংস থেকে তা কেড়ে নেয়।
ইউজার প্রত্যাখ্যান করেছে — সংশ্লিষ্ট অ্যাকশন ব্লকড থাকবে, তবে ইউজার সেটিংস থেকে পুনরায় অনুমতি দিলে পুনরায়
request_permission কল করে বদলানো সম্ভব।৩ · একটি সত্যিকারের পারমিশন স্টেট মেশিন
নিচের কোডে একটি সত্যিকারের ডিকশনারি প্রতিটি পারমিশনের স্ট্যাটাস ধরে রাখে। request_permission
ফাংশনে outcome ডিটারমিনিস্টিকভাবে দেওয়া হয় (real OS ডায়ালগে ইউজার কী চাপলো তা সিমুলেট করতে) —
র্যান্ডম নয়, যাতে ফলাফল প্রতিবার একই ও পুনরুৎপাদনযোগ্য হয়। use_flashlight ফাংশনটি — আমাদের
"স্পর্শকাতর অ্যাকশন" — প্রতিবার কল হওয়ার মুহূর্তেই PERMISSIONS ডিকশনারি থেকে সত্যিকারের বর্তমান
স্ট্যাটাস পড়ে, কখনো আগে থেকে অনুমান করে না।
# একটি সত্যিকারের পারমিশন স্টেট মেশিন
# প্রতিটি পারমিশনের প্রকৃত স্ট্যাটাস ট্র্যাক করে -- ধরে নেয় না
PERMISSIONS = {
"camera": "not_requested",
"location": "not_requested",
"microphone": "not_requested",
}
def request_permission(name, outcome):
"""outcome ডিটারমিনিস্টিকভাবে দেওয়া হয় (real OS ডায়ালগের ফলাফল সিমুলেট করতে) -- র্যান্ডম নয়"""
if outcome not in ("granted", "denied"):
raise ValueError(f"অবৈধ outcome: {outcome}")
PERMISSIONS[name] = outcome
print(f"[request] {name:12s} -> {outcome}")
return outcome
def use_flashlight(reason):
"""একটি সত্যিকারের গেটেড অ্যাকশন -- কল হওয়ার মুহূর্তেই camera পারমিশনের প্রকৃত স্ট্যাটাস চেক করে"""
status = PERMISSIONS["camera"]
if status == "granted":
print(f"[action] ফ্ল্যাশলাইট চালু হলো ({reason}) -- camera permission: {status}")
return True
else:
print(f"[action] ব্লকড -- ফ্ল্যাশলাইট চালু করা যায়নি ({reason}), camera permission: {status}")
return False
print("== ধাপ ১: এখনো পারমিশন চাওয়া হয়নি ==")
use_flashlight("ইউজার টর্চ বাটনে ট্যাপ করলো")
print("\n== ধাপ ২: পারমিশন চাওয়া হলো, ইউজার প্রত্যাখ্যান করলো ==")
request_permission("camera", "denied")
use_flashlight("ইউজার আবার টর্চ বাটনে ট্যাপ করলো")
print("\n== ধাপ ৩: ইউজার সেটিংসে গিয়ে অনুমতি দিলো, অ্যাপ আবার request করলো ==")
request_permission("camera", "granted")
use_flashlight("ইউজার আবার টর্চ বাটনে ট্যাপ করলো")
print(f"\nচূড়ান্ত PERMISSIONS ডিকশনারি: {PERMISSIONS}")
use_flashlight কখনো নিজে থেকে PERMISSIONS["camera"] = "granted" সেট করে
না — শুধু request_permission-ই স্টেট বদলাতে পারে। এই বিভাজন গুরুত্বপূর্ণ — একটি অ্যাকশন ফাংশন
কখনো নিজেই নিজের অনুমতি দিয়ে দেবে না, শুধু OS-এর (এখানে সিমুলেটেড) সিদ্ধান্ত পড়বে।
একটি পারমিশন-গেটেড অ্যাকশন কখনো "পারমিশন আছে ধরে নেওয়া" যায় না — প্রতিবার কল হওয়ার মুহূর্তে সত্যিকারের
স্ট্যাটাস ডিকশনারি থেকে পড়তে হবে। এই তিন-স্টেট PERMISSIONS প্যাটার্নটিই এই মডিউলের পরের দুই পাঠে
(ক্যামেরা, লোকেশন) হুবহু পুনরায় ব্যবহৃত হবে — শুধু গেটেড অ্যাকশনটাই বদলাবে।
ভাবনার প্রশ্ন
প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।
প্র ০১ ইনস্টল-টাইমে সব পারমিশন একসাথে চাওয়ার বদলে রানটাইমে, ঠিক প্রয়োজনের মুহূর্তে চাওয়ার সুবিধা কী?
ইউজার প্রেক্ষাপট পায় — "ছবি তুলুন" বাটনে চাপার ঠিক পরে ক্যামেরা পারমিশন চাওয়া হলে বোঝা যায় কেন এটি দরকার। এটি গ্রান্ট রেট বাড়ায় এবং অপ্রয়োজনীয় পারমিশন এড়িয়ে ইউজারের আস্থা বজায় রাখে — একগাদা পারমিশন ইনস্টলের সময় একসাথে দেখলে ইউজার সন্দিহান হয়ে অ্যাপই ইনস্টল না করার সিদ্ধান্ত নিতে পারে।
প্র ০২
কোড সেলে use_flashlight কেন PERMISSIONS["camera"] সরাসরি বদলায় না?
কারণ একটি অ্যাকশন ফাংশনের কাজ পারমিশন পরিবর্তন করা নয়, শুধু তা পড়া ও তদনুযায়ী আচরণ করা। স্টেট বদলানোর
একমাত্র বৈধ পথ request_permission — যা real OS-এর পারমিশন ডায়ালগের ফলাফল প্রতিনিধিত্ব করে।
এই বিভাজন ছাড়া যেকোনো ফাংশন নিজেই নিজেকে অনুমতি দিয়ে দিতে পারতো, যা সত্যিকারের OS-এ কখনো সম্ভব নয়।
প্র ০৩
not_requested আর denied — দুটো স্টেটেই তো অ্যাকশন ব্লকড হয়, তাহলে দুটো
আলাদা স্টেট রাখার দরকার কী?
UX-এর জন্য গুরুত্বপূর্ণ পার্থক্য — not_requested অবস্থায় অ্যাপ সরাসরি OS-এর পারমিশন ডায়ালগ
দেখাতে পারে, কিন্তু denied অবস্থায় (বিশেষত ইউজার একবার প্রত্যাখ্যান করার পর) অনেক প্ল্যাটফর্ম
আর সরাসরি ডায়ালগ দেখায় না — অ্যাপকে ইউজারকে সেটিংসে পাঠাতে হয়। তাই দুটো আলাদা স্টেট ধরে রাখলে অ্যাপ সঠিক
পরবর্তী পদক্ষেপ (ডায়ালগ দেখানো বনাম সেটিংসে পাঠানো) ঠিক করতে পারে।
অনুশীলন
-
চিন্তা করুন: ধরুন একটি অ্যাপ প্রথমবার চালু হওয়ার সময়ই লোকেশন, ক্যামেরা, মাইক্রোফোন,
কন্টাক্টস — এই চারটি পারমিশনই একসাথে চেয়ে বসে, অ্যাপের কোনো ফিচার তখনো ব্যবহার হয়নি। এতে ইউজারের প্রতিক্রিয়া
কেমন হতে পারে বলে আপনার মনে হয়?
প্রেক্ষাপটবিহীন হওয়ায় ইউজার সন্দিহান হতে পারে ("এই অ্যাপের লোকেশন কেন দরকার, আমি তো এখনো কিছুই করিনি") এবং সহজেই সবগুলো প্রত্যাখ্যান করে দিতে পারে — এমনকি যেগুলো পরে সত্যিই দরকার হতো সেগুলোও। এটিই রানটাইম পারমিশনের মূল নকশা-নীতি ভঙ্গ করে — "ঠিক প্রয়োজনের মুহূর্তে চাও"।
-
পরীক্ষা করুন: উপরের কোড সেলে একটি নতুন লাইন যোগ করুন যেখানে ধাপ ৩-এর পরে
request_permission("camera", "denied")আবার কল করা হয় (ইউজার সেটিংস থেকে পুনরায় পারমিশন কেড়ে নিলো), তারপরuse_flashlight("তৃতীয়বার ট্যাপ")কল করে দেখুন এটি এখন কী প্রিন্ট করে।request_permission("camera", "denied")কল হওয়া মাত্রPERMISSIONS["camera"]আবার"denied"-এ ফিরে যাবে, এবং পরেরuse_flashlightকলেstatus == "granted"মিথ্যা হওয়ায় আবার ব্লকড বার্তা প্রিন্ট হবে — দেখাচ্ছে পারমিশন যেকোনো সময় দুই দিকেই বদলাতে পারে, তাই অ্যাপ কখনো একটি পুরনো "granted" ফলাফল ক্যাশ করে রাখতে পারে না।
আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ
- কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাপ লাইফসাইকেল, মোবাইল UI/UX, MVVM/MVI আর্কিটেকচার, নেটিভ বনাম ক্রস-প্ল্যাটফর্ম, নেভিগেশন, স্টেট ম্যানেজমেন্ট, লোকাল স্টোরেজ, ডিভাইস ফিচার ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
- Full-Stack Web Frameworks কোর্স সহোদর কোর্স ওয়েবে ব্রাউজার নিজেই বেশিরভাগ পারমিশন (ক্যামেরা, লোকেশন) হ্যান্ডেল করে সীমিত পরিসরে — মোবাইলে OS-লেভেল রানটাইম পারমিশন মডেল অনেক বেশি গ্রানুলার ও কড়া।
- সব Courses দেখুন ABCL TECH C, C++, Python, Java, JavaScript, DSA, DBMS, Discrete Mathematics, System Design, Cybersecurity, Cloud Computing & DevOps, Computer Networks, Operating Systems, Computer Architecture, Programming Languages & Compiler Design, Software Engineering & Git, Theory of Computation, Engineering Economics, Full-Stack Web Frameworks ও Mobile App Development — সব এক জায়গায়।