অডিও গ্লাসের জন্য ফিজিক্যাল ইনপুট রাউটিং সম্পর্কে বোঝা

প্রযোজ্য XR ডিভাইস
এই নির্দেশিকা আপনাকে এই ধরনের XR ডিভাইসের জন্য অভিজ্ঞতা তৈরি করতে সাহায্য করে।
অডিও গ্লাস

অডিও গ্লাসে, সিস্টেম ভিজ্যুয়াল ডিসপ্লে ফোকাসের পরিবর্তে ব্যবহারকারীর সচেতনতার উপর ভিত্তি করে ফিজিক্যাল ইনপুট (যেমন টাচপ্যাড জেসচার বা বোতাম প্রেস) রুট করে। যেহেতু ব্যবহারকারীরা ইউজার ইন্টারফেস দেখতে পান না, তাই সিস্টেম ফিজিক্যাল ইনপুটকে প্রোজেক্ট করা অ্যাক্টিভিটিতে রুট করে, যে অ্যাপ অভিজ্ঞতা ব্যবহারকারী অনুভব করছেন বা সক্রিয়ভাবে ইন্টার‍্যাক্ট করছেন।

সিস্টেম কীভাবে ব্যবহারকারীর সচেতনতা নির্ধারণ করে

নিম্নলিখিত ডেটা স্ট্রিমের মধ্যে কোনটি অ্যাক্টিভ আছে তা মনিটর করার মাধ্যমে সিস্টেম ব্যবহারকারীর সচেতনতা নির্ধারণ করে:

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

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

কনকারেন্সি ও ইনপুট ফোকাস

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

  • আপনার অ্যাপের প্রোজেক্ট করা অ্যাক্টিভিটি আবার শুরু বা বন্ধ করা।
  • ফোরগ্রাউন্ডে থাকা প্রোজেক্ট করা অ্যাক্টিভিটিতে ফিজিক্যাল ইনপুট রাউট করা হচ্ছে।

এই পদ্ধতি ব্যবহারকারীর অভিজ্ঞতাকে সামঞ্জস্যপূর্ণ রাখতে সাহায্য করে।

সিস্টেমকে আপনার প্রোজেক্ট করা অ্যাক্টিভিটি আবার চালু করতে দিন

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

সিস্টেম যাতে আপনার অ্যাক্টিভিটি আবার চালু করতে পারে তা নিশ্চিত করতে:

  1. পেন্ডিং ইনটেন্ট তৈরি করা: আপনার টার্গেট প্রোজেক্ট করা অ্যাক্টিভিটির দিকে পয়েন্ট করে একটি নির্দিষ্ট Intent তৈরি করুন। PendingIntent-এ ইনটেন্ট র‍্যাপ করুন এবং সুরক্ষিত ও অনুমানযোগ্য লঞ্চ আচরণ বজায় রাখতে FLAG_UPDATE_CURRENT বা FLAG_IMMUTABLE সেট করুন:

    // Build an explicit Intent pointing to this projected activity and wrap it in a
    // PendingIntent so the system can relaunch it and route physical input to it.
    private val pendingIntent: PendingIntent by lazy {
        val intent = Intent(this, ProjectedInputFocusActivity::class.java)
    
        PendingIntent.getActivity(
            this,
            0,
            intent,
            PendingIntent.FLAG_UPDATE_CURRENT or PendingIntent.FLAG_IMMUTABLE
        )
    }

  2. ইনপুট রিসিভার রেজিস্টার করুন: ProjectedActivityCompat-এর একটি ইনস্ট্যান্স পান এবং আপনার PendingIntent-কে setActivityAsInputReceiver-এ পাস করে নির্দিষ্ট ইনপুট রিসিভার হিসেবে রেজিস্টার করুন।

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
    
        lifecycleScope.launch {
            // Create or obtain the ProjectedActivityCompat instance
            val projectedActivity = ProjectedActivityCompat.create(this@ProjectedInputFocusActivity)
    
            // Register the PendingIntent as the designated input receiver
            projectedActivity.setActivityAsInputReceiver(pendingIntent)
        }

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

    override fun onDestroy() {
        super.onDestroy()
        lifecycleScope.launch {
            val projectedActivity = ProjectedActivityCompat.create(this@ProjectedInputFocusActivity)
            projectedActivity.clearActivityAsInputReceiver()
        }
    }

কনকারেন্সি স্টেট জুড়ে ইনপুট ফোকাস কীভাবে শিফট হয় তা বুঝুন

কোন অ্যাপ ইনপুট ফোকাস পাবে তা নির্ধারণ করতে, সিস্টেম অ্যাক্টিভ ডেটা স্ট্রিম মূল্যায়ন করে এবং এই কনকারেন্সি অবস্থার উপর ভিত্তি করে ইনপুট রুট করে:

কনকারেন্সি স্ট্যাটাস পরিবেশগত প্রসঙ্গ সিস্টেমের আচরণ ও ইনপুট ফোকাস উদাহরণ

একসাথে নয়

একটি স্ট্যান্ডঅ্যালোন প্রোজেক্টেড অ্যাক্টিভিটি চালু আছে; ব্যাকগ্রাউন্ডে কোনও মিডিয়া সেশন চলছে না।

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

ব্যবহারকারী ওয়ার্কআউট ট্র্যাকিং অ্যাপ চালান। এমনকি নীরবতার মুহূর্তের সময়ও, টাচপ্যাড ইনপুট সরাসরি ফিটনেস অ্যাপে রুট করে।

সেমি-কনকারেন্ট

প্রোজেক্ট করা অ্যাক্টিভিটি চালু আছে, কিন্তু ব্যাকগ্রাউন্ড মিডিয়া সেশন পজ করা অবস্থায় আছে।

অ্যাপের অ্যাক্টিভ রিডআউটের মধ্যে নীরবতার সময়কালে ইনপুট ফোকাস ডিফল্ট হিসেবে পজ করা মিডিয়া কন্ট্রোলে সেট করা থাকে।

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

একই সময়ে

ডুয়াল প্লেব্যাক চালু আছে (যেমন, আপনার অ্যাপের অডিও ঘোষণা ব্যাকগ্রাউন্ড মিউজিককে বাধা দেয় বা বন্ধ করে দেয়)।

অডিও ফোকাস ইনপুট ফোকাসের সমান।

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

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

সিস্টেম টাইমিং সেফগার্ড

ব্যবহারকারীদের জন্য ভুলবশত ইনপুট বা অপ্রত্যাশিত আচরণ প্রতিরোধ করতে সাহায্য করার জন্য সিস্টেম নিম্নলিখিত সুরক্ষা প্রদান করে:

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

অনুশীলনে ইনপুট ফোকাস ট্রানজিশন

কনকারেন্সি স্টেট জুড়ে ইনপুট ফোকাস ট্রানজিশন কীভাবে হয় তা বুঝতে, এক এক করে নির্দেশিকা প্রদানকারী নেভিগেশন অ্যাপের জন্য নিম্নলিখিত উদাহরণগুলি বিবেচনা করুন:

পরিস্থিতি ক: নন-কনকারেন্ট (ইনঅ্যাক্টিভ মিডিয়া)

এই পরিস্থিতিতে, সিস্টেম নেভিগেশন অ্যাপে ইনপুট পাঠায়, যা পুরো যাত্রা জুড়ে ব্যবহারকারীকে সচেতন রাখে।

ছবি ১. এই নন-কনকারেন্ট পরিস্থিতিতে নেভিগেশন অ্যাপের জন্য ইনপুট ফোকাস কীভাবে রুট করা হবে।
  1. ব্যবহারকারী ব্যাকগ্রাউন্ড মিউজিক না চালিয়ে নেভিগেশন চালু করেন।
  2. নেভিগেশন অ্যাপ অডিও গ্লাসে তার প্রোজেক্ট করা অ্যাক্টিভিটি লঞ্চ করে।
  3. কোনও মিডিয়া সেশন অ্যাক্টিভ না থাকার কারণে, নেভিগেশন অ্যাপ পুরো যাত্রা জুড়ে টাচপ্যাড ইনপুট ফোকাস বজায় রাখে।
  4. ব্যবহারকারীর অ্যাকশন: অ্যাক্টিভ রিডআউট চলাকালীন ট্যাপ করলে নির্দেশিকা মিউট হয়ে যেতে পারে। নীরবতার সময় ট্যাপ করলে শেষ নির্দেশটি আবার বলা হতে পারে।

পরিস্থিতি খ: সেমি-কনকারেন্ট (পজ করা মিডিয়া)

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

ছবি ২. এই সেমি-কনকারেন্ট পরিস্থিতিতে নেভিগেশন অ্যাপের জন্য ইনপুট ফোকাস কীভাবে রুট করা হবে।
  1. ব্যাকগ্রাউন্ড মিউজিক পজ করা থাকাকালীন ব্যবহারকারী নেভিগেশন চালু করেন।
  2. রিডআউটের মধ্যে সাইলেন্ট পিরিয়ড চলাকালীন, ইনপুট ফোকাস ডিফল্ট হিসেবে মিডিয়া কন্ট্রোলে সেট করা থাকে।
  3. নেভিগেশন অ্যাপ যখন "৫০০ ফুট পরে, বাঁদিকে ঘুরুন" বলে, তখন এটি ইনপুট ফোকাস পায়।
  4. ব্যবহারকারীর অ্যাকশন: রিডআউট চলাকালীন ট্যাপ করলে নির্দেশিকা মিউট হয়ে যেতে পারে। নীরবতার সময় ট্যাপ করলে মিউজিক প্লেব্যাক আবার চালু হয়।

পরিস্থিতি গ: কনকারেন্ট (অ্যাক্টিভ মিডিয়া)

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

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