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

চিত্র ১-এ যেমন দেখানো হয়েছে, যখন টকব্যাক চালু থাকে, তখন ডি-প্যাড ইভেন্টগুলো ডেভেলপার দ্বারা সংজ্ঞায়িত ডি-প্যাড হ্যান্ডলারে পাঠানো হয় না। এর পরিবর্তে, অ্যাক্সেসিবিলিটি সার্ভিসগুলো কী ইভেন্টগুলো গ্রহণ করে, যাতে তারা অ্যাক্সেসিবিলিটি ফোকাস সরাতে পারে। যেহেতু কাস্টম অ্যান্ড্রয়েড কম্পোনেন্টগুলো ডিফল্টভাবে স্ক্রিনে তাদের অবস্থান সম্পর্কে অ্যাক্সেসিবিলিটি সার্ভিসগুলোর কাছে কোনো তথ্য প্রকাশ করে না, তাই অ্যাক্সেসিবিলিটি সার্ভিসগুলো সেগুলোকে হাইলাইট করার জন্য অ্যাক্সেসিবিলিটি ফোকাস সরাতে পারে না।
অন্যান্য অ্যাক্সেসিবিলিটি পরিষেবাগুলোও একইভাবে প্রভাবিত হয়: সুইচ অ্যাক্সেস ব্যবহার করার সময় ডি-প্যাড ইভেন্টগুলোও ব্যবহৃত হতে পারে।
যেহেতু ডি-প্যাড ইভেন্টগুলো অ্যাক্সেসিবিলিটি সার্ভিসে পাঠানো হয়, এবং সেই সার্ভিসটি জানে না যে একটি কাস্টম ভিউতে UI কম্পোনেন্টগুলো কোথায় আছে, তাই আপনার অ্যাপে কী ইভেন্টগুলো সঠিকভাবে ফরোয়ার্ড করার জন্য আপনাকে অবশ্যই AccessibilityNodeInfo ইমপ্লিমেন্ট করতে হবে।
প্রবেশগম্যতা পরিষেবাগুলিতে তথ্য প্রকাশ করুন
কাস্টম ভিউগুলির অবস্থান এবং বিবরণ সম্পর্কে অ্যাক্সেসিবিলিটি পরিষেবাগুলিকে পর্যাপ্ত তথ্য সরবরাহ করতে, প্রতিটি কম্পোনেন্টের বিবরণ প্রকাশ করার জন্য AccessibilityNodeInfo প্রয়োগ করুন। ভিউগুলির যৌক্তিক সম্পর্ক নির্ধারণ করতে, যাতে অ্যাক্সেসিবিলিটি পরিষেবাগুলি ফোকাস পরিচালনা করতে পারে, ExploreByTouchHelper প্রয়োগ করুন এবং কাস্টম ভিউগুলির জন্য ViewCompat.setAccessibilityDelegate(View, AccessibilityDelegateCompat) ব্যবহার করে এটি সেট করুন।
ExploreByTouchHelper ইমপ্লিমেন্ট করার সময়, এর চারটি অ্যাবস্ট্রাক্ট মেথড ওভাররাইড করুন:
কোটলিন
// Return the virtual view ID whose view is covered by the input point (x, y).
protected fun getVirtualViewAt(x: Float, y: Float): Int
// Fill the virtual view ID list into the input parameter virtualViewIds.
protected fun getVisibleVirtualViews(virtualViewIds: List<Int>)
// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected fun onPopulateNodeForVirtualView(virtualViewId: Int, @NonNull node: AccessibilityNodeInfoCompat)
// Set the accessibility handling when perform action.
protected fun onPerformActionForVirtualView(virtualViewId: Int, action: Int, @Nullable arguments: Bundle): Boolean
জাভা
// Return the virtual view ID whose view is covered by the input point (x, y).
protected int getVirtualViewAt(float x, float y)
// Fill the virtual view ID list into the input parameter virtualViewIds.
protected void getVisibleVirtualViews(List<Integer> virtualViewIds)
// For the view whose virtualViewId is the input virtualViewId, populate the
// accessibility node information into the AccessibilityNodeInfoCompat parameter.
protected void onPopulateNodeForVirtualView(int virtualViewId, @NonNull AccessibilityNodeInfoCompat node)
// Set the accessibility handling when perform action.
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, @Nullable Bundle arguments)
আরও বিস্তারিত জানতে, Google I/O 2013 - Enabling Blind and Low-Vision Accessibility on Android দেখুন অথবা অ্যাক্সেসিবিলিটি ইভেন্টগুলি পপুলেট করা সম্পর্কে আরও পড়ুন।
সর্বোত্তম অনুশীলন
আবশ্যক:
AccessibilityNodeInfo.getBoundsInScreen()অবশ্যই কম্পোনেন্টটির অবস্থান নির্ধারণ করবে।আবশ্যক:
AccessibilityNodeInfo.setVisibleToUser()অবশ্যই কম্পোনেন্টটির দৃশ্যমানতা প্রতিফলিত করবে।আবশ্যক: Talkback-এর ঘোষণার জন্য
AccessibilityNodeInfo.getContentDescription()অবশ্যই বিষয়বস্তুর বিবরণ উল্লেখ করতে হবে।AccessibilityNodeInfo.setClassName()নির্দিষ্ট করুন, যাতে সার্ভিসগুলো কম্পোনেন্টের ধরন শনাক্ত করতে পারে।performAction()প্রয়োগ করার সময়, একটি সংশ্লিষ্টAccessibilityEventব্যবহার করে অ্যাকশনটি প্রতিফলিত করুন।ACTION_CLICKমতো আরও অ্যাকশন টাইপ প্রয়োগ করতে,performAction()এ সংশ্লিষ্ট লজিক ব্যবহার করেAccessibilityNodeInfo.addAction(ACTION_CLICK)কল করুন।প্রযোজ্য ক্ষেত্রে,
setFocusable(),setClickable(),setScrollable()এবং অনুরূপ মেথডগুলোর জন্য কম্পোনেন্টের অবস্থা প্রতিফলিত করুন।অ্যাক্সেসিবিলিটি সার্ভিসগুলো আপনার কম্পোনেন্টগুলোর সাথে আরও ভালোভাবে কীভাবে কাজ করতে পারে, তা শনাক্ত করতে
AccessibilityNodeInfoএর ডকুমেন্টেশন পর্যালোচনা করুন।
নমুনা
কাস্টম ভিউ ব্যবহার করে অ্যাপে অ্যাক্সেসিবিলিটি সাপোর্ট যোগ করার সেরা পদ্ধতিগুলো জানতে অ্যান্ড্রয়েড টিভির জন্য কাস্টম ভিউ অ্যাক্সেসিবিলিটি স্যাম্পলটি দেখুন।