বৈশিষ্ট্য এবং API

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

নতুন, পরিবর্তিত এবং অপসারিত API-গুলির বিস্তারিত তালিকার জন্য API diff report পড়ুন। নতুন API-গুলির বিশদ বিবরণের জন্য Android API reference দেখুন — নতুন API-গুলি সহজে চোখে পড়ার জন্য হাইলাইট করা থাকে।

প্ল্যাটফর্মের পরিবর্তন আপনার অ্যাপগুলোকে প্রভাবিত করতে পারে এমন ক্ষেত্রগুলোও পর্যালোচনা করা উচিত। আরও তথ্যের জন্য, নিম্নলিখিত পৃষ্ঠাগুলো দেখুন:

মূল কার্যকারিতা

অ্যান্ড্রয়েড ১৭-এ অ্যান্ড্রয়েডের মূল কার্যকারিতা সম্পর্কিত নিম্নলিখিত নতুন বৈশিষ্ট্যগুলো যুক্ত করা হয়েছে।

নতুন প্রোফাইলিংম্যানেজার ট্রিগার

অ্যান্ড্রয়েড ১৭, পারফরম্যান্স সংক্রান্ত সমস্যা ডিবাগ করার জন্য গভীর ডেটা সংগ্রহে সাহায্য করতে ProfilingManager বেশ কিছু নতুন সিস্টেম ট্রিগার যুক্ত করেছে।

নতুন ট্রিগারগুলো হলো:

  • TRIGGER_TYPE_COLD_START : অ্যাপ কোল্ড স্টার্টের সময় ট্রিগারটি ঘটে। এটি রেসপন্সে একটি কল স্ট্যাক স্যাম্পল এবং একটি সিস্টেম ট্রেস উভয়ই প্রদান করে।
  • TRIGGER_TYPE_OOM : যখন কোনো অ্যাপ OutOfMemoryError থ্রো করে এবং তার জবাবে একটি Java Heap Dump প্রদান করে, তখন এই ট্রিগারটি ঘটে।
  • TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE : অস্বাভাবিক ও অতিরিক্ত সিপিইউ ব্যবহারের কারণে কোনো অ্যাপ বন্ধ হয়ে গেলে এই ট্রিগারটি সক্রিয় হয় এবং এর প্রতিক্রিয়ায় একটি কল স্ট্যাকের নমুনা প্রদান করে।
  • TRIGGER_TYPE_ANOMALY : সিস্টেম পারফরম্যান্সের অস্বাভাবিকতা, যেমন অতিরিক্ত বাইন্ডার কল এবং অতিরিক্ত মেমরি ব্যবহার, শনাক্ত করুন।

সিস্টেম ট্রিগার কীভাবে সেট আপ করতে হয় তা বুঝতে, ট্রিগার-ভিত্তিক প্রোফাইলিং এবং প্রোফাইলিং ডেটা পুনরুদ্ধার ও বিশ্লেষণ করার ডকুমেন্টেশন দেখুন।

অ্যাপের অসঙ্গতির জন্য প্রোফাইলিং ট্রিগার

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

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

এই এপিআই কলব্যাকটি সিস্টেম কর্তৃক আরোপিত যেকোনো বিধিনিষেধের পূর্বে ঘটে। উদাহরণস্বরূপ, মেমরি সীমা অতিক্রম করার কারণে সিস্টেম দ্বারা অ্যাপটি বন্ধ করে দেওয়ার আগে, এটি ডেভেলপারদের ডিবাগ ডেটা সংগ্রহ করতে সাহায্য করতে পারে।

val profilingManager =
    applicationContext.getSystemService(ProfilingManager::class.java)
val triggers = ArrayList<ProfilingTrigger>()
triggers.add(ProfilingTrigger.Builder(ProfilingTrigger.TRIGGER_TYPE_ANOMALY))
val mainExecutor: Executor = Executors.newSingleThreadExecutor()
val resultCallback = Consumer<ProfilingResult> { profilingResult ->
    if (profilingResult.errorCode != ProfilingResult.ERROR_NONE) {
        // upload profile result to server for further analysis
        setupProfileUploadWorker(profilingResult.resultFilePath)
    }
    profilingManager.registerForAllProfilingResults(mainExecutor,
                                                    resultCallback)
    profilingManager.addProfilingTriggers(triggers)
}

জবডিবাগইনফো এপিআই

অ্যান্ড্রয়েড ১৭-এ নতুন JobDebugInfo API চালু করা হয়েছে, যা ডেভেলপারদের তাদের JobScheduler জবগুলো ডিবাগ করতে সাহায্য করে—যেমন জবগুলো কেন চলছে না, কতক্ষণ ধরে চলেছে এবং অন্যান্য সামগ্রিক তথ্য।

বর্ধিত JobDebugInfo API-এর প্রথম মেথডটি হলো getPendingJobReasonStats() , যা একটি জব কেন পেন্ডিং এক্সিকিউশন অবস্থায় ছিল তার কারণ এবং সেগুলোর মোট পেন্ডিং সময়কালের একটি ম্যাপ রিটার্ন করে। এই মেথডটি getPendingJobReasonsHistory() এবং getPendingJobReasons() মেথডগুলোকে একত্রিত করে একটি শিডিউল করা জব কেন প্রত্যাশিতভাবে চলছে না সে সম্পর্কে ধারণা দেয়, তবে এটি সময়কাল এবং জবের কারণ উভয়কেই একটিমাত্র মেথডে উপলব্ধ করে তথ্য সংগ্রহকে সহজ করে তোলে।

উদাহরণস্বরূপ, একটি নির্দিষ্ট jobId জন্য, মেথডটি PENDING_JOB_REASON_CONSTRAINT_CHARGING এবং 60000 ms-এর একটি সময়কাল রিটার্ন করতে পারে, যা নির্দেশ করে যে চার্জিং সীমাবদ্ধতা পূরণ না হওয়ার কারণে জবটি 60000ms ধরে পেন্ডিং ছিল।

allow-while-idle অ্যালার্মের জন্য লিসেনার সাপোর্টের মাধ্যমে ওয়েক লক হ্রাস করুন।

অ্যান্ড্রয়েড ১৭-এ AlarmManager.setExactAndAllowWhileIdle এর একটি নতুন সংস্করণ চালু করা হয়েছে, যা PendingIntent পরিবর্তে একটি OnAlarmListener গ্রহণ করে। এই নতুন কলব্যাক-ভিত্তিক পদ্ধতিটি সেইসব অ্যাপের জন্য আদর্শ, যেগুলো বর্তমানে পর্যায়ক্রমিক কাজ সম্পাদনের জন্য অবিরাম ওয়েক-লকের উপর নির্ভর করে; যেমন সকেট সংযোগ বজায় রাখা মেসেজিং অ্যাপ।

গোপনীয়তা

ব্যবহারকারীর গোপনীয়তা উন্নত করার জন্য অ্যান্ড্রয়েড ১৭-এ নিম্নলিখিত নতুন বৈশিষ্ট্যগুলো অন্তর্ভুক্ত করা হয়েছে।

এনক্রিপ্টেড ক্লায়েন্ট হ্যালো (ECH) প্ল্যাটফর্ম সমর্থন

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

প্ল্যাটফর্মটিতে এখন নেটওয়ার্কিং লাইব্রেরিগুলোর জন্য ECH বাস্তবায়নের প্রয়োজনীয় API অন্তর্ভুক্ত রয়েছে। এর মধ্যে রয়েছে DnsResolver এ ECH কনফিগারেশনযুক্ত HTTPS DNS রেকর্ড কোয়েরি করার নতুন সক্ষমতা, এবং Conscrypt-এর SSLEngines ও SSLSockets-এ নতুন মেথড, যা কোনো ডোমেইনে সংযোগ করার সময় এই কনফিগারেশনগুলো পাস করার মাধ্যমে ECH সক্রিয় করে। ডেভেলপাররা Network Security Configuration ফাইলের মধ্যে থাকা নতুন <domainEncryption> এলিমেন্টের মাধ্যমে ECH-এর পছন্দগুলো কনফিগার করতে পারেন, যেমন—সুযোগ বুঝে এটি সক্রিয় করা বা এর ব্যবহার বাধ্যতামূলক করা। এই এলিমেন্টটি বিশ্বব্যাপী বা ডোমেইন-ভিত্তিক উভয়ভাবেই প্রযোজ্য।

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

আরও তথ্যের জন্য, এনক্রিপ্টেড ক্লায়েন্ট হ্যালো ডকুমেন্টেশন দেখুন।

অ্যান্ড্রয়েড কন্টাক্টস পিকার

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

আরও তথ্যের জন্য, কন্টাক্ট পিকার ডকুমেন্টেশন দেখুন।

নিরাপত্তা

ডিভাইস ও অ্যাপের নিরাপত্তা উন্নত করতে অ্যান্ড্রয়েড ১৭ নিম্নলিখিত নতুন ফিচারগুলো যোগ করেছে।

অ্যান্ড্রয়েড অ্যাডভান্সড প্রোটেকশন মোড (AAPM)

Android 高级保护模式为 Android 用户提供了一套强大的新安全功能,标志着在保护用户(尤其是面临较高风险的用户)免遭复杂攻击方面迈出了重要一步。AAPM 是一项选择启用功能,只需进行一项配置设置即可激活。用户可以随时启用该功能,以应用一套主观的安全保护措施。

这些核心配置包括:禁止安装未知来源的应用(旁加载)、限制 USB 数据信号传输,以及强制执行 Google Play 保护机制扫描,从而显著减小设备的攻击面。 开发者可以使用 AdvancedProtectionManager API 与此功能集成,以检测模式的状态,从而使应用能够在用户选择启用此模式时自动采用强化型安全姿态或限制高风险功能。

PQC APK সাইনিং

Android 现在支持混合 APK 签名方案,以保护应用的签名身份免受利用量子计算的攻击的潜在威胁。此功能引入了一种新的 APK 签名方案,可让您将经典签名密钥(例如 RSA 或 EC)与新的后量子加密 (PQC) 算法 (ML-DSA) 配对。

这种混合方法可确保您的应用在未来免受量子攻击,同时与依赖于经典签名验证的旧版 Android 和设备保持完全的向后兼容性。

对开发者的影响

  • 使用 Play 应用签名的应用:如果您使用 Play 应用签名,可以等待 Google Play 为您提供使用 Google Play 生成的 PQC 密钥升级混合签名的选项,从而确保您的应用受到保护,而无需手动管理密钥。
  • 使用自行管理的密钥的应用:自行管理签名密钥的开发者可以利用更新后的 Android build 工具(例如 apksigner)轮换到混合身份,将 PQC 密钥与新的经典密钥相结合。(您必须创建新的经典密钥,无法重复使用旧密钥。)

সংযোগ

ডিভাইস ও অ্যাপের সংযোগ উন্নত করতে অ্যান্ড্রয়েড ১৭ নিম্নলিখিত বৈশিষ্ট্যগুলো যোগ করেছে।

সীমাবদ্ধ স্যাটেলাইট নেটওয়ার্ক

কম-ব্যান্ডউইথ স্যাটেলাইট নেটওয়ার্কগুলিতে অ্যাপগুলিকে কার্যকরভাবে কাজ করতে সক্ষম করার জন্য অপ্টিমাইজেশন বাস্তবায়ন করে।

ব্যবহারকারীর অভিজ্ঞতা এবং সিস্টেম UI

ব্যবহারকারীর অভিজ্ঞতা উন্নত করার জন্য অ্যান্ড্রয়েড ১৭-এ নিম্নলিখিত পরিবর্তনগুলো অন্তর্ভুক্ত করা হয়েছে।

নিবেদিত সহকারী ভলিউম স্ট্রিম

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

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

হস্তান্তর

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

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

হ্যান্ডঅফ সাপোর্ট প্রতিটি অ্যাক্টিভিটির জন্য আলাদাভাবে প্রয়োগ করা হয়। হ্যান্ডঅফ চালু করতে, অ্যাক্টিভিটির জন্য setHandoffEnabled() মেথডটি কল করুন। হ্যান্ডঅফের সাথে অতিরিক্ত ডেটা পাঠানোর প্রয়োজন হতে পারে, যাতে গ্রহণকারী ডিভাইসে পুনরায় তৈরি হওয়া অ্যাক্টিভিটিটি তার যথাযথ অবস্থা পুনরুদ্ধার করতে পারে। একটি HandoffActivityData অবজেক্ট রিটার্ন করার জন্য onHandoffActivityDataRequested() কলব্যাকটি ইমপ্লিমেন্ট করুন, যেটিতে এমন বিবরণ থাকে যা নির্দিষ্ট করে দেয় যে হ্যান্ডঅফ কীভাবে গ্রহণকারী ডিভাইসে অ্যাক্টিভিটিটি পরিচালনা ও পুনরায় তৈরি করবে।

লাইভ আপডেট - সিমান্টিক কালার এপিআই

অ্যান্ড্রয়েড ১৭-এর লাইভ আপডেটের মাধ্যমে সার্বজনীন অর্থবহ রঙগুলোকে সমর্থন করার জন্য সিমান্টিক কালারিং এপিআই চালু করা হয়েছে।

নিম্নলিখিত ক্লাসগুলি সিমান্টিক কালারিং সমর্থন করে:

রঙ করা

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

নিম্নলিখিত উদাহরণটি দেখায় কিভাবে একটি নোটিফিকেশনের টেক্সটে সিমান্টিক স্টাইল প্রয়োগ করতে হয়:

  val ssb = SpannableStringBuilder()
        .append("Colors: ")
        .append("NONE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_UNSPECIFIED), 0)
        .append(", ")
        .append("INFO", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_INFO), 0)
        .append(", ")
        .append("SAFE", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_SAFE), 0)
        .append(", ")
        .append("CAUTION", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_CAUTION), 0)
        .append(", ")
        .append("DANGER", Notification.createSemanticStyleAnnotation(SEMANTIC_STYLE_DANGER), 0)

    Notification.Builder(context, channelId)
          .setSmallIcon(R.drawable.ic_icon)
          .setContentTitle("Hello World!")
          .setContentText(ssb)
          .setOngoing(true)
              .setRequestPromotedOngoing(true)

অ্যান্ড্রয়েড ১৭ এর জন্য UWB ডাউনলিঙ্ক-TDoA এপিআই

ডাউনলিঙ্ক টাইম ডিফারেন্স অফ অ্যারাইভাল (DL-TDoA) রেঞ্জিং একটি ডিভাইসকে সিগন্যালের আপেক্ষিক আগমন সময় পরিমাপের মাধ্যমে একাধিক অ্যাঙ্করের সাপেক্ষে তার অবস্থান নির্ধারণ করতে সাহায্য করে।

নিম্নলিখিত কোড স্নিপেটটিতে দেখানো হয়েছে কীভাবে রেঞ্জিং ম্যানেজার ইনিশিয়ালাইজ করতে হয়, ডিভাইসের সক্ষমতা যাচাই করতে হয় এবং একটি DL-TDoA সেশন শুরু করতে হয়:

কোটলিন

class RangingApp {

    fun initDlTdoa(context: Context) {
        // Initialize the Ranging Manager
        val rangingManager = context.getSystemService(RangingManager::class.java)

        // Register for device capabilities
        val capabilitiesCallback = object : RangingManager.RangingCapabilitiesCallback {
            override fun onRangingCapabilities(capabilities: RangingCapabilities) {
                // Make sure Dl-TDoA is supported before starting the session
                if (capabilities.uwbCapabilities != null && capabilities.uwbCapabilities!!.isDlTdoaSupported) {
                    startDlTDoASession(context)
                }
            }
        }
        rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback)
    }

    fun startDlTDoASession(context: Context) {

        // Initialize the Ranging Manager
        val rangingManager = context.getSystemService(RangingManager::class.java)

        // Create session and configure parameters
        val executor = Executors.newSingleThreadExecutor()
        val rangingSession = rangingManager.createRangingSession(executor, RangingSessionCallback())
        val rangingRoundIndexes = byteArrayOf(0)
        val config: ByteArray = byteArrayOf() // OOB config data
        val params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes)

        val rangingDevice = RangingDevice.Builder().build()
        val rawTagDevice = RawRangingDevice.Builder()
            .setRangingDevice(rangingDevice)
            .setDlTdoaRangingParams(params)
            .build()

        val dtTagConfig = RawDtTagRangingConfig.Builder(rawTagDevice).build()

        val preference = RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
            .setSessionConfig(SessionConfig.Builder().build())
            .build()

        // Start the ranging session
        rangingSession.start(preference)
    }
}

private class RangingSessionCallback : RangingSession.Callback {
    override fun onDlTdoaResults(peer: RangingDevice, measurement: DlTdoaMeasurement) {
        // Process measurement results here
    }
}

জাভা

public class RangingApp {

    public void initDlTdoa(Context context) {

        // Initialize the Ranging Manager
        RangingManager rangingManager = context.getSystemService(RangingManager.class);

        // Register for device capabilities
        RangingManager.CapabilitiesCallback capabilitiesCallback = new RangingManager.RangingCapabilitiesCallback() {
            @Override
            public void onRangingCapabilities(RangingCapabilities capabilities) {
                // Make sure Dl-TDoA is supported before starting the session
                if (capabilities.getUwbCapabilities() != null && capabilities.getUwbCapabilities().isDlTdoaSupported()) {
                    startDlTDoASession(context);
                }
            }
        };
        rangingManager.registerCapabilitiesCallback(Executors.newSingleThreadExecutor(), capabilitiesCallback);
    }

    public void startDlTDoASession(Context context) {
        RangingManager rangingManager = context.getSystemService(RangingManager.class);

        // Create session and configure parameters
        Executor executor = Executors.newSingleThreadExecutor();
        RangingSession rangingSession = rangingManager.createRangingSession(executor, new RangingSessionCallback());
        byte[] rangingRoundIndexes = new byte[] {0};
        byte[] config = new byte[0]; // OOB config data
        DlTdoaRangingParams params = DlTdoaRangingParams.createFromFiraConfigPacket(config, rangingRoundIndexes);

        RangingDevice rangingDevice = new RangingDevice.Builder().build();
        RawRangingDevice rawTagDevice = new RawRangingDevice.Builder()
                .setRangingDevice(rangingDevice)
                .setDlTdoaRangingParams(params)
                .build();

        RawDtTagRangingConfig dtTagConfig = new RawDtTagRangingConfig.Builder(rawTagDevice).build();

        RangingPreference preference = new RangingPreference.Builder(DEVICE_ROLE_DT_TAG, dtTagConfig)
                .setSessionConfig(new SessionConfig.Builder().build())
                .build();

        // Start the ranging session
        rangingSession.start(preference);
    }

    private static class RangingSessionCallback implements RangingSession.Callback {

        @Override
        public void onDlTdoaResults(RangingDevice peer, DlTdoaMeasurement measurement) {
            // Process measurement results here
        }
    }
}

আউট-অফ-ব্যান্ড (OOB) কনফিগারেশন

নিম্নলিখিত কোড স্নিপেটটি Wi-Fi এবং BLE-এর জন্য DL-TDoA OOB কনফিগারেশন ডেটার একটি উদাহরণ প্রদান করে:

জাভা

// Wifi Configuration
byte[] wifiConfig = {
    (byte) 0xDD, (byte) 0x2D, (byte) 0x5A, (byte) 0x18, (byte) 0xFF, // Header
    (byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
    (byte) 0x02, (byte) 0x00, // Profile ID
    (byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
    (byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
    (byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
    (byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
    (byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
    (byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
    (byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
    (byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01  // Session ID
};

// BLE Configuration
byte[] bleConfig = {
    (byte) 0x2D, (byte) 0x16, (byte) 0xF4, (byte) 0xFF, // Header
    (byte) 0x5F, (byte) 0x19, // FiRa Sub-Element
    (byte) 0x02, (byte) 0x00, // Profile ID
    (byte) 0x06, (byte) 0x02, (byte) 0x20, (byte) 0x08, // MAC Address
    (byte) 0x14, (byte) 0x01, (byte) 0x0C, // Preamble Index
    (byte) 0x27, (byte) 0x02, (byte) 0x08, (byte) 0x07, // Vendor ID
    (byte) 0x28, (byte) 0x06, (byte) 0xCA, (byte) 0xC8, (byte) 0xA6, (byte) 0xF7, (byte) 0x6F, (byte) 0x08, // Static STS IV
    (byte) 0x08, (byte) 0x02, (byte) 0x60, (byte) 0x09, // Slot Duration
    (byte) 0x1B, (byte) 0x01, (byte) 0x0A, // Slots per RR
    (byte) 0x09, (byte) 0x04, (byte) 0xE8, (byte) 0x03, (byte) 0x00, (byte) 0x00, // Duration
    (byte) 0x9F, (byte) 0x04, (byte) 0x67, (byte) 0x45, (byte) 0x23, (byte) 0x01  // Session ID
};

যদি কোনো OOB কনফিগারেশন অনুপস্থিত থাকার কারণে আপনি তা ব্যবহার করতে না পারেন, অথবা যদি আপনার এমন ডিফল্ট মান পরিবর্তন করার প্রয়োজন হয় যা OOB কনফিগারেশনে নেই, তাহলে আপনি নিম্নলিখিত কোড স্নিপেটে দেখানো পদ্ধতি অনুযায়ী DlTdoaRangingParams.Builder ব্যবহার করে প্যারামিটার তৈরি করতে পারেন। আপনি এই প্যারামিটারগুলো DlTdoaRangingParams.createFromFiraConfigPacket() এর পরিবর্তে ব্যবহার করতে পারেন:

কোটলিন

val dlTdoaParams = DlTdoaRangingParams.Builder(1)
    .setComplexChannel(UwbComplexChannel.Builder()
            .setChannel(9).setPreambleIndex(10).build())
    .setDeviceAddress(deviceAddress)
    .setSessionKeyInfo(byteArrayOf(0x01, 0x02, 0x03, 0x04))
    .setRangingIntervalMillis(240)
    .setSlotDuration(UwbRangingParams.DURATION_2_MS)
    .setSlotsPerRangingRound(20)
    .setRangingRoundIndexes(byteArrayOf(0x01, 0x05))
    .build()

জাভা

DlTdoaRangingParams dlTdoaParams = new DlTdoaRangingParams.Builder(1)
    .setComplexChannel(new UwbComplexChannel.Builder()
            .setChannel(9).setPreambleIndex(10).build())
    .setDeviceAddress(deviceAddress)
    .setSessionKeyInfo(new byte[]{0x01, 0x02, 0x03, 0x04})
    .setRangingIntervalMillis(240)
    .setSlotDuration(UwbRangingParams.DURATION_2_MS)
    .setSlotsPerRangingRound(20)
    .setRangingRoundIndexes(new byte[]{0x01, 0x05})
    .build();