Android 17-এ ডেভেলপারদের জন্য দারুণ নতুন ফিচার ও API নিয়ে আসা হয়েছে। নিম্নলিখিত বিভাগগুলি এই ফিচারগুলির সারসংক্ষেপ করে যাতে আপনি সম্পর্কিত API ব্যবহার শুরু করতে পারেন।
নতুন, পরিবর্তিত এবং সরানো API-এর বিস্তারিত তালিকার জন্য, API diff রিপোর্ট পড়ুন। নতুন API সম্পর্কে বিস্তারিত জানতে Android API রেফারেন্স দেখুন — নতুন API হাইলাইট করা হয়েছে যাতে সহজেই দেখা যায়।
এছাড়াও, প্ল্যাটফর্মে করা পরিবর্তন আপনার অ্যাপকে প্রভাবিত করতে পারে এমন ক্ষেত্রগুলি আপনার পর্যালোচনা করা উচিত। আরও তথ্যের জন্য, নিম্নলিখিত পৃষ্ঠাগুলি দেখুন:
- Android 17-কে টার্গেট করার সময় অ্যাপকে প্রভাবিত করে এমন আচরণগত পরিবর্তন
- আচরণগত পরিবর্তন যা
targetSdkVersionনির্বিশেষে সব অ্যাপকে প্রভাবিত করে।
মূল কার্যকারিতা
Android 17-এ মূল Android কার্যকারিতা সম্পর্কিত নিম্নলিখিত নতুন ফিচার যোগ করা হয়েছে।
নতুন ProfilingManager ট্রিগার
পারফর্ম্যান্স সংক্রান্ত সমস্যা ডিবাগ করার জন্য ইন-ডেপথ ডেটা সংগ্রহ করতে আপনাকে সাহায্য করার জন্য
Android 17, ProfilingManager-এ বেশ কিছু নতুন সিস্টেম ট্রিগার যোগ করে।
নতুন ট্রিগারগুলি হল:
TRIGGER_TYPE_COLD_START: অ্যাপ কোল্ড স্টার্টের সময় ট্রিগার হয়। এটি উত্তরে কল স্ট্যাক স্যাম্পেল ও সিস্টেম ট্রেস, দুটিই প্রদান করে।TRIGGER_TYPE_OOM: কোনও অ্যাপOutOfMemoryErrorথ্রো করলে এবং উত্তরে জাভা হিপ ডাম্প প্রদান করলে ট্রিগার হয়।TRIGGER_TYPE_KILL_EXCESSIVE_CPU_USAGE: অস্বাভাবিক এবং অত্যধিক CPU ব্যবহারের কারণে কোনও অ্যাপ বন্ধ হয়ে গেলে ট্রিগার ঘটে এবং প্রতিক্রিয়া হিসাবে একটি কল স্ট্যাক স্যাম্পেল প্রদান করে।TRIGGER_TYPE_ANOMALY: সিস্টেম পারফর্ম্যান্সের অসঙ্গতি শনাক্ত করে, যেমন অতিরিক্ত বাইন্ডার কল এবং অতিরিক্ত মেমরির ব্যবহার।
সিস্টেম ট্রিগার কীভাবে সেট-আপ করতে হয় তা বুঝতে, ট্রিগার-ভিত্তিক প্রোফাইলিং এবং কীভাবে প্রোফাইলিং ডেটা ডকুমেন্টেশন উদ্ধার ও বিশ্লেষণ করতে হয় সেই সংক্রান্ত ডকুমেন্টেশন দেখুন।
অ্যাপের অসঙ্গতির জন্য প্রোফাইলিং ট্রিগার
Android 17
অন-ডিভাইস অ্যানোমালি শনাক্তকরণ পরিষেবা নিয়ে এসেছে যা
রিসোর্স-ইনটেনসিভ আচরণ এবং সম্ভাব্য কম্প্যাটিবিলিটি রিগ্রেশন মনিটর করে। ProfilingManager-এর সাথে
ইন্টিগ্রেট করা এই পরিষেবা আপনার অ্যাপকে সিস্টেম-শনাক্ত করা নির্দিষ্ট ইভেন্ট দ্বারা ট্রিগার করা প্রোফাইলিং
আর্টিফ্যাক্ট গ্রহণ করার অনুমতি দেয়।
সিস্টেমের পারফর্ম্যান্স সংক্রান্ত সমস্যা শনাক্ত করতে TRIGGER_TYPE_ANOMALY ট্রিগার ব্যবহার করুন
যেমন অত্যধিক বাইন্ডার কল এবং অত্যধিক মেমরির ব্যবহার। কোনও অ্যাপ OS-নির্ধারিত মেমরির সীমা লঙ্ঘন করলে,
অ্যানোমালি ট্রিগার ডেভেলপারদের অ্যাপ-নির্দিষ্ট হিপ ডাম্প পেতে দেয়,
যা মেমরি সংক্রান্ত সমস্যা শনাক্ত করতে এবং সমাধান করতে সাহায্য করে। এছাড়াও,
অতিরিক্ত বাইন্ডার স্প্যামের জন্য, অ্যানোমালি ট্রিগার বাইন্ডার ট্রানজ্যাকশনে
একটি স্ট্যাক স্যাম্পলিং প্রোফাইল প্রদান করে।
সিস্টেমের মাধ্যমে কোনও এনফোর্সমেন্ট আরোপ করার আগে এই API কলব্যাক হয়। যেমন, মেমরির সীমা অতিক্রম করার জন্য সিস্টেমের মাধ্যমে অ্যাপ বন্ধ করার আগে এটি ডেভেলপারদের ডিবাগ ডেটা সংগ্রহ করতে সাহায্য করতে পারে।
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
Android 17-এ নতুন JobDebugInfo API নিয়ে আসা হয়েছে যা ডেভেলপারদের JobScheduler-এর কাজ ডিবাগ করতে সাহায্য করে--কেন সেগুলি চলছে না, কতক্ষণ ধরে চলছে এবং অন্যান্য একত্রিত তথ্য।
JobDebugInfo API-এর প্রথম পদ্ধতি হল
getPendingJobReasonStats(), যা জবটি কেন পেন্ডিং এক্সিকিউশন স্টেটে ছিল তার কারণ এবং তাদের সংশ্লিষ্ট ক্রমবর্ধমান পেন্ডিং
সময়কালের একটি ম্যাপ রিটার্ন করে। এই পদ্ধতিটি getPendingJobReasonsHistory() এবং
getPendingJobReasons() পদ্ধতির সাথে যুক্ত হয়ে আপনাকে এই বিষয়ে ইনসাইট দেয় যে কেন শিডিউল করা
জব প্রত্যাশা অনুযায়ী চলছে না, তবে এটি তথ্য সংগ্রহ করার পদ্ধতিকে সহজ করে তোলে, কারণ
এটি একটিই পদ্ধতিতে সময়সীমা এবং জব সংক্রান্ত কারণ, দুটিই উপলভ্য করে।
যেমন, নির্দিষ্ট jobId-এর জন্য, পদ্ধতিটি
PENDING_JOB_REASON_CONSTRAINT_CHARGING এবং ৬০০০০ মিলি.সেকেন্ডের সময়সীমা ফিরিয়ে দিতে পারে, যা ইঙ্গিত করে
যে চার্জিং সংক্রান্ত সীমাবদ্ধতা পূরণ না হওয়ার কারণে
জবটি ৬০০০০ মিলি.সেকেন্ডের জন্য পেন্ডিং ছিল।
অ্যালাউ-হোয়াইল-আইডল অ্যালার্মের জন্য লিসেনার সাপোর্ট সহ ওয়েক লক কমান
Android 17
AlarmManager.setExactAndAllowWhileIdle-এর একটি নতুন ভ্যারিয়েন্ট নিয়ে এসেছে যা
PendingIntent-এর পরিবর্তে OnAlarmListener গ্রহণ করে। এই নতুন
কলব্যাক-ভিত্তিক মেকানিজম সেইসব অ্যাপের জন্য আদর্শ যেগুলি বর্তমানে পর্যায়ক্রমিক টাস্ক
সম্পাদন করার জন্য ক্রমাগত ওয়েক-লকের উপর নির্ভর করে, যেমন সকেট কানেকশন বজায় রাখা
মেসেজিং অ্যাপ।
গোপনীয়তা
ব্যবহারকারীর গোপনীয়তা উন্নত করতে Android 17-এ নিম্নলিখিত নতুন ফিচার অন্তর্ভুক্ত করা হয়েছে।
এনক্রিপটেড Client Hello (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 গ্রহণ করা এবং ব্যবহারকারীর গোপনীয়তা বাড়ানো সহজ করে তুলবে।
আরও তথ্যের জন্য, এনক্রিপ্টেড ক্লায়েন্ট হ্যালো ডকুমেন্টেশন দেখুন।
Android পরিচিতি পিকার
Android পরিচিতি পিকার হল একটি স্ট্যান্ডার্ড, ব্রাউজ করা যায় এমন ইন্টারফেস যার মাধ্যমে ব্যবহারকারীরা
আপনার অ্যাপের সাথে পরিচিতি শেয়ার করতে পারেন। Android 17 (API লেভেল ৩৭) বা তার পরবর্তী যেকোনও ভার্সন
চালানো ডিভাইসে উপলভ্য, পিকারটি READ_CONTACTS অনুমতির একটি গোপনীয়তা-সংরক্ষণকারী
বিকল্প অফার করে। ব্যবহারকারীর সম্পূর্ণ অ্যাড্রেস বুক অ্যাক্সেস করার অনুরোধ করার পরিবর্তে, আপনার অ্যাপ ফোন নম্বর বা ইমেল আইডির মতো প্রয়োজনীয় ডেটা ফিল্ড নির্দিষ্ট করে এবং ব্যবহারকারী শেয়ার করার জন্য নির্দিষ্ট পরিচিতি বেছে নেন। এটি আপনার অ্যাপকে শুধুমাত্র বেছে নেওয়া ডেটা পড়ার অ্যাক্সেস দেয়,
বিল্ট-ইন সার্চ, প্রোফাইল পাল্টানো এবং UI তৈরি বা ম্যানেজ না করেই
একাধিক আইটেম বেছে নেওয়ার ক্ষমতা সহ ব্যবহারকারীকে ধারাবাহিক অভিজ্ঞতা প্রদান করার সময়
গ্র্যানুলার কন্ট্রোল নিশ্চিত করে।
আরও তথ্যের জন্য, পরিচিতি পিকার ডকুমেন্টেশন দেখুন।
নিরাপত্তা
ডিভাইস ও অ্যাপের নিরাপত্তা উন্নত করতে Android 17-এ নিম্নলিখিত নতুন ফিচার যোগ করা হয়েছে।
Android-এর উন্নত সুরক্ষা মোড (AAPM)
অ্যান্ড্রয়েড অ্যাডভান্সড প্রোটেকশন মোড অ্যান্ড্রয়েড ব্যবহারকারীদের একটি শক্তিশালী নতুন নিরাপত্তা বৈশিষ্ট্য প্রদান করে, যা ব্যবহারকারীদের - বিশেষ করে যারা উচ্চ ঝুঁকিতে রয়েছে - অত্যাধুনিক আক্রমণ থেকে সুরক্ষিত করার ক্ষেত্রে একটি গুরুত্বপূর্ণ পদক্ষেপ। একটি অপ্ট-ইন বৈশিষ্ট্য হিসাবে ডিজাইন করা, AAPM একটি একক কনফিগারেশন সেটিং দিয়ে সক্রিয় করা হয়েছে যা ব্যবহারকারীরা যেকোনো সময় একটি মতামতযুক্ত নিরাপত্তা সুরক্ষা সেট প্রয়োগ করতে চালু করতে পারেন।
এই মূল কনফিগারেশনগুলির মধ্যে রয়েছে অজানা উৎস থেকে অ্যাপ ইনস্টলেশন ব্লক করা (সাইডলোডিং), USB ডেটা সিগন্যালিং সীমাবদ্ধ করা এবং Google Play Protect স্ক্যানিং বাধ্যতামূলক করা, যা ডিভাইসের আক্রমণ পৃষ্ঠের ক্ষেত্রফল উল্লেখযোগ্যভাবে হ্রাস করে। ডেভেলপাররা মোডের স্থিতি সনাক্ত করতে AdvancedProtectionManager API ব্যবহার করে এই বৈশিষ্ট্যটির সাথে একীভূত হতে পারে, যার ফলে অ্যাপ্লিকেশনগুলি স্বয়ংক্রিয়ভাবে একটি কঠোর নিরাপত্তা ভঙ্গি গ্রহণ করতে পারে বা ব্যবহারকারী যখন এটি নির্বাচন করে তখন উচ্চ-ঝুঁকিপূর্ণ কার্যকারিতা সীমাবদ্ধ করতে পারে।
PQC APK সাইনিং
Android এখন হাইব্রিড APK সিগনেচার স্কিম সমর্থন করে, যা কোয়ান্টাম কম্পিউটিং ব্যবহার করে সম্ভাব্য আক্রমণের হুমকি থেকে আপনার অ্যাপের সাইনিং আইডেন্টিটিকে ভবিষ্যতে সুরক্ষিত রাখে। এই ফিচারটি একটি নতুন APK সিগনেচার স্কিম চালু করে, যা আপনাকে একটি নতুন পোস্ট-কোয়ান্টাম ক্রিপ্টোগ্রাফি (PQC) অ্যালগরিদম (ML-DSA)-এর সাথে একটি ক্লাসিক্যাল সাইনিং কী (যেমন RSA বা EC) পেয়ার করতে দেয়।
এই হাইব্রিড অ্যাপ্রোচ আপনার অ্যাপকে ভবিষ্যতের কোয়ান্টাম আক্রমণ থেকে সুরক্ষিত রাখে এবং একই সাথে পুরনো Android ভার্সন ও ডিভাইসের সাথে সম্পূর্ণ ব্যাকওয়ার্ড কম্প্যাটিবিলিটি বজায় রাখে, যা ক্লাসিক্যাল সিগনেচার যাচাইকরণের উপর নির্ভর করে।
ডেভেলপারদের উপর প্রভাব
- Play অ্যাপ সাইনিং ব্যবহার করা অ্যাপ: আপনি Play অ্যাপ সাইনিং ব্যবহার করলে, Google Play-এর মাধ্যমে হাইব্রিড সিগনেচার আপগ্রেড করার বিকল্প পাওয়ার জন্য অপেক্ষা করতে পারেন। Google Play-এর মাধ্যমে জেনারেট করা PQC কী ব্যবহার করে এটি করা হয়। এর ফলে, ম্যানুয়ালি কী ম্যানেজ না করেই আপনার অ্যাপ সুরক্ষিত থাকে।
- সেল্ফ-ম্যানেজড কী ব্যবহার করা অ্যাপ: যেসব ডেভেলপার নিজেদের সাইনিং কী ম্যানেজ করেন, তারা হাইব্রিড আইডেন্টিটিতে রোটেট করার জন্য আপডেট করা Android বিল্ড টুল (যেমন apksigner) ব্যবহার করতে পারেন, যা PQC কী-কে নতুন ক্লাসিক্যাল কী-এর সাথে একত্রিত করে। (আপনাকে অবশ্যই একটি নতুন ক্লাসিক্যাল কী তৈরি করতে হবে, আপনি পুরনোটি আবার ব্যবহার করতে পারবেন না।)
কানেক্টিভিটি
ডিভাইস ও অ্যাপ কানেক্টিভিটি উন্নত করতে Android 17-এ নিম্নলিখিত ফিচার যোগ করা হয়েছে।
সীমাবদ্ধ স্যাটেলাইট নেটওয়ার্ক
কম-ব্যান্ডউইথ স্যাটেলাইট নেটওয়ার্কগুলিতে অ্যাপগুলিকে কার্যকরভাবে কাজ করতে সক্ষম করার জন্য অপ্টিমাইজেশন বাস্তবায়ন করে।
ব্যবহারকারীর অভিজ্ঞতা ও সিস্টেম UI
ব্যবহারকারীর অভিজ্ঞতা উন্নত করতে Android 17-এ নিম্নলিখিত পরিবর্তনগুলি অন্তর্ভুক্ত করা হয়েছে।
Assistant-এর জন্য নির্দিষ্ট ভলিউম স্ট্রিম
Android 17-এ Assistant অ্যাপের জন্য একটি বিশেষ Assistant ভলিউম স্ট্রিম চালু করা হয়েছে,
USAGE_ASSISTANT-এর সাথে প্লেব্যাকের জন্য। এই পরিবর্তন Assistant অডিওকে স্ট্যান্ডার্ড মিডিয়া স্ট্রিম থেকে আলাদা করে, যার ফলে ব্যবহারকারীরা দুটি ভলিউমই আলাদাভাবে নিয়ন্ত্রণ করতে পারেন। এটি মিডিয়া প্লেব্যাক মিউট করার মতো পরিস্থিতি তৈরি করে, তবে Assistant-এর উত্তর
শোনা যায় এবং এর উল্টোটাও হয়।
নতুন MODE_ASSISTANT_CONVERSATION অডিও মোডে অ্যাক্সেস সহ Assistant অ্যাপ
ভলিউম কন্ট্রোল সামঞ্জস্য আরও উন্নত করতে পারে। Assistant অ্যাপ এই মোড ব্যবহার করে
অ্যাক্টিভ Assistant সেশন সম্পর্কে সিস্টেমকে ইঙ্গিত দিতে পারে,
যাতে অ্যাক্টিভ USAGE_ASSISTANT প্লেব্যাকের বাইরে বা কানেক্ট করা ব্লুটুথ পেরিফেরালের মাধ্যমে
Assistant স্ট্রিম কন্ট্রোল করা যায়।
হ্যান্ডঅফ
হ্যান্ডঅফ হল একটি নতুন ফিচার এবং API যা Android 17-এ আসছে। অ্যাপ ডেভেলপাররা তাদের ব্যবহারকারীদের জন্য ক্রস-ডিভাইস কন্টিনিউটি প্রদান করতে এটির সাথে ইন্টিগ্রেট করতে পারেন। এটি ব্যবহারকারীকে একটি Android ডিভাইসে অ্যাপ অ্যাক্টিভিটি শুরু করতে এবং অন্য Android ডিভাইসে সেটি ট্রানজিশন করতে দেয়। হ্যান্ডঅফ ব্যবহারকারীর ডিভাইসের ব্যাকগ্রাউন্ডে চলে এবং ব্যবহারকারীর আশেপাশের অন্যান্য ডিভাইস থেকে উপলভ্য অ্যাক্টিভিটি, রিসিভ করা ডিভাইসে লঞ্চার ও টাস্কবারের মতো বিভিন্ন এন্ট্রি পয়েন্টের মাধ্যমে দেখায়।
অ্যাপটি রিসিভ করা ডিভাইসে ইনস্টল করা এবং উপলভ্য থাকলে, একই নেটিভ Android অ্যাপ চালু করার জন্য অ্যাপগুলি হ্যান্ডঅফ মনোনীত করতে পারে। এই অ্যাপ-টু-অ্যাপ ফ্লোতে, ব্যবহারকারীকে নির্দিষ্ট অ্যাক্টিভিটিতে ডিপ-লিঙ্ক করা হয়। বিকল্প হিসেবে, অ্যাপ-টু-ওয়েব হ্যান্ডঅফ ফলব্যাক বিকল্প হিসেবে অফার করা যেতে পারে অথবা URL হ্যান্ডঅফের মাধ্যমে সরাসরি প্রয়োগ করা যেতে পারে।
প্রতিটি অ্যাক্টিভিটির ভিত্তিতে হ্যান্ডঅফ সহায়তা প্রয়োগ করা হয়। হ্যান্ডঅফ চালু করতে, অ্যাক্টিভিটির জন্য
setHandoffEnabled()
মেথড কল করুন। হ্যান্ডঅফের সাথে অতিরিক্ত ডেটা পাস করার প্রয়োজন হতে পারে যাতে রিসিভ করা ডিভাইসে রিক্রিয়েট করা অ্যাক্টিভিটি উপযুক্ত অবস্থা ফিরিয়ে আনতে পারে। HandoffActivityData অবজেক্ট
ফেরত পেতে
onHandoffActivityDataRequested()
কলব্যাক প্রয়োগ করুন,
এতে এমন বিবরণ থাকে যা নির্দিষ্ট করে যে রিসিভ করা ডিভাইসে কীভাবে Handoff অ্যাক্টিভিটি ম্যানেজ ও আবার তৈরি করবে।
লাইভ আপডেট - সেম্যান্টিক কালার API
Android 17-এর সাথে, লাইভ আপডেট সর্বজনীন অর্থ সহ রঙকে সমর্থন করার জন্য সিম্যান্টিক কালারিং API লঞ্চ করে।
নিম্নলিখিত ক্লাসগুলি সিম্যান্টিক কালারিং সমর্থন করে:
NotificationNotification.MetricNotification.ProgressStyle.PointNotification.ProgressStyle.Segment
রঙ করা
- সবুজ: নিরাপত্তার সাথে সম্পর্কিত। এই রঙটি এমন ক্ষেত্রে ব্যবহার করা উচিত যেখানে এটি লোকজনকে জানতে দেয় যে আপনি নিরাপদ পরিস্থিতিতে আছেন।
- কমলা: সতর্কতা নির্দেশ করতে এবং শারীরিক বিপদ চিহ্নিত করতে। এই রঙটি এমন পরিস্থিতিতে ব্যবহার করা উচিত যেখানে ব্যবহারকারীদের আরও ভালো সুরক্ষা সেটিং সেট করার জন্য মনোযোগ দিতে হবে।
- লাল: সাধারণত বিপদ, থামুন বোঝায়। এটি এমনভাবে দেখানো উচিত যাতে লোকজনের মনোযোগ অবিলম্বে আকর্ষণ করা যায়।
- নীল: তথ্যমূলক কন্টেন্টের জন্য নিরপেক্ষ রঙ এবং অন্যান্য কন্টেন্ট থেকে আলাদা করে দেখানো উচিত।
বিজ্ঞপ্তির টেক্সটে কীভাবে সিম্যান্টিক স্টাইল প্রয়োগ করতে হয় তা নিম্নলিখিত উদাহরণে দেখানো হয়েছে:
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)
Android 17-এর জন্য UWB Downlink-TDoA API
ডাউনলিঙ্ক টাইম ডিফারেন্স অফ অ্যারাইভাল (DL-TDoA) রেঞ্জিং কোনও ডিভাইসকে সিগন্যালের আপেক্ষিক আগমনের সময় পরিমাপ করে একাধিক অ্যাঙ্করের সাপেক্ষে তার অবস্থান নির্ধারণ করতে দেয়।নিম্নলিখিত স্নিপেট থেকে বোঝা যায় যে কীভাবে রেঞ্জিং ম্যানেজার শুরু করতে হয়, ডিভাইসের ক্ষমতা যাচাই করতে হয় এবং DL-TDoA সেশন শুরু করতে হয়:
Kotlin
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) কনফিগারেশন
নিম্নলিখিত স্নিপেটটি ওয়াই-ফাই ও 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()-এর পরিবর্তে
এইসব প্যারামিটার ব্যবহার করতে পারবেন:
Kotlin
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();