পাঠ ৪২ · ৫৭-এর মধ্যে · মডিউল ১০
Home / Courses / Mobile App Development / ক্যামেরা ও মিডিয়া

ক্যামেরা ও মিডিয়া অ্যাক্সেস

Camera and media access
৮ মিনিট পড়া মধ্যম · Intermediate Python কোডসহ সম্পূর্ণ বাংলায়

এই পাঠে যা শিখবেন

  • ক্যামেরা-ধারণ পারমিশন ও মিডিয়া-লাইব্রেরি পারমিশনের পার্থক্য
  • L41-এর পারমিশন গেট প্যাটার্ন একটি concrete "ছবি তোলা" অ্যাকশনে কীভাবে প্রয়োগ করতে হয়
  • not_requested অবস্থায় একটি অ্যাকশন কীভাবে নিজে থেকে একটি রিকোয়েস্ট ধাপ ট্রিগার করতে পারে
  • তিনটি ভিন্ন পারমিশন-অবস্থায় একই ফাংশনের তিনটি ভিন্ন, প্রকৃতভাবে গণনাকৃত আউটপুট

১ · ক্যামেরা বনাম মিডিয়া লাইব্রেরি পারমিশন

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

iOS-এ মিডিয়া লাইব্রেরি পারমিশনের আরও একটি সূক্ষ্ম স্তর আছে — "সীমিত অ্যাক্সেস" (ইউজার শুধু নির্দিষ্ট কিছু ছবি বেছে দেয়, পুরো লাইব্রেরি নয়) বনাম "সম্পূর্ণ অ্যাক্সেস"। এই পাঠে আমরা মূল তিন-স্টেট মডেলেই থাকবো — L41-এর not_requested/granted/denied — কারণ মূল গেটিং যুক্তিটি অভিন্ন।

২ · L41-এর গেট দিয়ে একটি সত্যিকারের "ছবি তোলা" অ্যাকশন

নিচের কোডে take_photo ফাংশনটি L41-এর ঠিক একই নীতি মেনে চলে — কল হওয়ার মুহূর্তে permissions["camera"]-এর প্রকৃত মান পড়ে। নতুনত্ব হলো — যদি স্ট্যাটাস not_requested হয়, ফাংশনটি নিজে থেকেই একটি রিকোয়েস্ট ধাপ ট্রিগার করে (বাস্তব অ্যাপে যেমন "ছবি তুলুন" বাটনে চাপলে ঠিক তখনই OS-এর পারমিশন ডায়ালগ পপ-আপ হয়)।

Python
# L41-এর পারমিশন গেট পুনরায় ব্যবহার করে একটি concrete take_photo() অ্যাকশন

def request_permission(permissions, name, outcome):
    """outcome ডিটারমিনিস্টিকভাবে দেওয়া হয় -- real OS পারমিশন ডায়ালগের ফলাফল সিমুলেট করতে"""
    if outcome not in ("granted", "denied"):
        raise ValueError(f"অবৈধ outcome: {outcome}")
    permissions[name] = outcome
    print(f"  [request] camera -> {outcome}")
    return outcome

def take_photo(permissions, auto_request_outcome=None):
    """camera পারমিশনের প্রকৃত স্ট্যাটাস কল হওয়ার মুহূর্তে চেক করে -- not_requested হলে প্রথমে রিকোয়েস্ট ট্রিগার করে"""
    status = permissions["camera"]
    if status == "not_requested":
        print("  [take_photo] camera permission not_requested -- প্রথমে OS পারমিশন ডায়ালগ দেখানো হচ্ছে")
        status = request_permission(permissions, "camera", auto_request_outcome)
    if status == "granted":
        print(f"  [take_photo] সফল -- ছবি তোলা হলো (IMG_0001.jpg), camera permission: {status}")
        return True
    else:
        print(f"  [take_photo] ব্লকড -- ছবি তোলা যায়নি, camera permission: {status}")
        return False

print("== দৃশ্য ১: not_requested -- এখনো পারমিশন চাওয়া হয়নি ==")
scenario1 = {"camera": "not_requested"}
take_photo(scenario1, auto_request_outcome="granted")

print("\n== দৃশ্য ২: denied -- ইউজার আগেই পারমিশন প্রত্যাখ্যান করেছে ==")
scenario2 = {"camera": "denied"}
take_photo(scenario2)

print("\n== দৃশ্য ৩: granted -- ইউজার আগেই পারমিশন দিয়ে রেখেছে ==")
scenario3 = {"camera": "granted"}
take_photo(scenario3)

    
দৃশ্য ১-এ লক্ষ্য করুন take_photo নিজেই request_permission কল করে, তারপর নতুন স্ট্যাটাস দিয়ে সিদ্ধান্ত নেয় — একটি কলের মধ্যেই "রিকোয়েস্ট" ও "গেট চেক" দুটো ধাপ ঘটে। দৃশ্য ২ ও ৩-এ যেহেতু স্ট্যাটাস ইতিমধ্যেই not_requested নয়, কোনো নতুন রিকোয়েস্ট ট্রিগার হয় না — সরাসরি বর্তমান স্ট্যাটাস অনুযায়ী ব্লকড বা সফল হয়।
মূল কথা · Key takeaway

একটি concrete ডিভাইস-ফিচার অ্যাকশন সবসময় তিনটি সম্ভাব্য পথ হ্যান্ডেল করে — এখনো না চাওয়া (রিকোয়েস্ট ট্রিগার করো), প্রত্যাখ্যাত (স্পষ্ট কারণসহ ব্লক করো), এবং অনুমোদিত (কাজ করো)। এই একই কাঠামো L43-এ লোকেশন অ্যাকশনের জন্য এবং L44-এ বায়োমেট্রিক গেটের জন্য আবার ব্যবহৃত হবে।

ভাবনার প্রশ্ন

প্রতিটি প্রশ্ন নিজে কিছুক্ষণ ভাবুন — তারপর "→ উত্তর" চাপুন।

প্র ০১ একটি অ্যাপের ক্যামেরা পারমিশন থাকলেই কি সে ইউজারের পুরনো গ্যালারির ছবি দেখতে পারবে?

না। ক্যামেরা পারমিশন শুধু নতুন ছবি/ভিডিও ধারণ করার অনুমতি দেয়। ইউজারের বিদ্যমান গ্যালারি পড়তে আলাদা মিডিয়া-লাইব্রেরি পারমিশন প্রয়োজন — এই দুটো OS-লেভেলে সম্পূর্ণ স্বতন্ত্র, তাই একটি অ্যাপের দুটো ভিন্ন PERMISSIONS এন্ট্রি থাকবে, যেমন "camera" ও "media_library"।

প্র ০২ কোড সেলের দৃশ্য ১-এ auto_request_outcome="granted" না দিয়ে "denied" দিলে আউটপুট কেমন হতো?

request_permission কল হয়ে status-কে "denied"-এ সেট করতো, তারপর if status == "granted" মিথ্যা হওয়ায় দৃশ্য ১-ও দৃশ্য ২-এর মতোই ব্লকড বার্তা প্রিন্ট করতো — পার্থক্য শুধু এটুকু যে দৃশ্য ১-এ প্রথমে "[request]" লাইনটি দেখা যেতো, কারণ শুরুতে স্ট্যাটাস not_requested ছিল।

প্র ০৩ ইউজার ছবি তোলার বাটনে ট্যাপ করার আগেই যদি ব্যাকগ্রাউন্ডে অ্যাপ ক্যামেরা পারমিশন চেয়ে বসে, তাহলে কী সমস্যা হতে পারে?

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

অনুশীলন

  1. চিন্তা করুন: ভিডিও ধারণের জন্য ক্যামেরা পারমিশনের পাশাপাশি সাধারণত মাইক্রোফোন পারমিশনও দরকার হয় (সাউন্ড রেকর্ড করতে)। যদি ক্যামেরা granted কিন্তু মাইক্রোফোন denied হয়, একটি ভালো ডিজাইনড অ্যাপ কীভাবে আচরণ করা উচিত বলে আপনার মনে হয়?

    সম্ভবত অ্যাপটি নিঃশব্দ (mute) ভিডিও ধারণের বিকল্প দিতে পারে, অথবা ভিডিও অপশনটি ব্লক রেখে ইউজারকে স্পষ্টভাবে জানাতে পারে যে সাউন্ডসহ ভিডিওর জন্য মাইক্রোফোন পারমিশন প্রয়োজন — দুটো পারমিশনকে একসাথে "সব-অথবা-কিছুই" ধরে নেওয়া উচিত নয়, প্রতিটি স্বাধীনভাবে চেক করা উচিত, ঠিক যেমন কোড সেলে permissions["camera"] স্বতন্ত্রভাবে চেক হয়েছে।

  2. পরীক্ষা করুন: উপরের কোড সেলে একটি চতুর্থ দৃশ্য যোগ করুন — scenario4 = {"camera": "not_requested"} তৈরি করে take_photo(scenario4, auto_request_outcome="denied") কল করুন এবং দেখুন এটি দৃশ্য ১ থেকে কীভাবে ভিন্ন আউটপুট দেয়।

    দৃশ্য ৪-এও প্রথমে "[take_photo] ... প্রথমে OS পারমিশন ডায়ালগ দেখানো হচ্ছে" এবং "[request] camera -> denied" লাইন প্রিন্ট হবে (ঠিক দৃশ্য ১-এর মতোই রিকোয়েস্ট ট্রিগার হয়), কিন্তু যেহেতু এবার outcome "denied", শেষে status == "granted" মিথ্যা হওয়ায় ব্লকড বার্তা প্রিন্ট হবে — দেখাচ্ছে "রিকোয়েস্ট ট্রিগার হওয়া" আর "রিকোয়েস্ট মঞ্জুর হওয়া" দুটো আলাদা জিনিস।

আরও পড়ুন · ABCL TECH-এ আপনার পরবর্তী পদক্ষেপ

  • কোর্সের সম্পূর্ণ সিলেবাস দেখুন ৫৭টি পাঠ অ্যাপ লাইফসাইকেল, মোবাইল UI/UX, MVVM/MVI আর্কিটেকচার, নেটিভ বনাম ক্রস-প্ল্যাটফর্ম, নেভিগেশন, স্টেট ম্যানেজমেন্ট, লোকাল স্টোরেজ, ডিভাইস ফিচার ও ডিপ্লয়মেন্ট — বাকি পাঠগুলো শীঘ্রই যুক্ত হবে।
  • Full-Stack Web Frameworks কোর্স সহোদর কোর্স ওয়েবে <input type="file"> বা getUserMedia() দিয়ে সীমিত, ব্রাউজার-স্যান্ডবক্সড মিডিয়া অ্যাক্সেস মেলে — মোবাইলে নেটিভ ক্যামেরা/গ্যালারি API-তে 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 — সব এক জায়গায়।
আগের পাঠ
পারমিশন মডেল — রানটাইম পারমিশন