Android XR-এর মাধ্যমে স্ক্রিন-স্পেসের বাইরে গিয়ে আপনার অ্যাপকে বাস্তব দুনিয়ায় অ্যাঙ্কর করুন। এই সেশন থেকে আপনি শিখবেন কীভাবে Jetpack Compose Glimmer এবং ARCore-এর Geospatial API ব্যবহার করে জিওস্পেশিয়াল-সচেতন Android XR অভিজ্ঞতা তৈরি করতে হয়। ARCore-এর মাধ্যমে ডিভাইসের জিওস্পেশিয়াল পোজ কীভাবে পাওয়া যায় তা দিয়ে আমরা শুরু করব। তারপর, আপনি দেখতে পাবেন যে কীভাবে Glimmer-এর মিনিমাল UI কম্পোনেন্ট ভিজ্যুয়াল পজিশনিং সিস্টেমের (VPS) মাধ্যমে বাস্তব-জগতের লোকেশনে অ্যাঙ্কর করা যেতে পারে। আমরা এগুলি একত্রিত করে একটি সহজ, লোকেশন-সচেতন স্পেশিয়াল অভিজ্ঞতা তৈরি করব।
ট্রান্সস্ক্রিপ্ট করা
হ্যালো সবাইকে, Android ডেভেলপার সামিটে Android XR ট্র্যাকের প্রথম সেশনে আপনাদের স্বাগত।
হ্যাঁ!
আপনাদের মধ্যে অনেকেই Android XR সম্পর্কে জানতে আগ্রহী দেখে আমরা খুবই আনন্দিত।
আমার নাম ইয়াসমিন কুইন্টানা ইভজেন এবং আমার সাথে আছেন পল হুভার ও ডেরেক ব্রিডি, কথোপকথন চলাকালীন তারা আমাদের সাথে যোগ দেবেন।
এই সেশনের বিষয় হল Android XR এবং Jetpack XR-এর জন্য Jetpack Compose Glimmer ও ARCore-এর মাধ্যমে আপনি কীভাবে স্পেশিয়ালি অ্যাঙ্কর করা, বাস্তব-জগতের অভিজ্ঞতা তৈরি করতে পারেন।
তবে প্রথমে, Android XR-এর একটি সংক্ষিপ্ত পরিচিতি দেওয়া যাক।
Android XR হল একটি নতুন প্ল্যাটফর্ম যা ব্যবহারকারীরা আপনার অ্যাপের সাথে কীভাবে ইন্টার্যাক্ট করবেন তা নতুনভাবে সংজ্ঞায়িত করে, স্ক্রিনের বাইরে এবং তাদের চারপাশের স্পেসে নিয়ে যায়।
আমরা প্ল্যাটফর্মটি এমনভাবে ডিজাইন করি যাতে ডিজিটাল অভিজ্ঞতা সরাসরি বাস্তব পরিবেশে নিয়ে আসা যায়।
এর অর্থ হল, এক ঝলকে দেখে নেওয়া যায় এমন ওভারলে যা বাস্তব জগতের উপস্থিতি বা একটি অসীম ইমারসিভ পরিবেশকে উন্নত করে।
এটি সেই একই ওপেন Android ইকোসিস্টেম যা আমরা বছরের পর বছর ধরে একসাথে তৈরি করছি এবং এখন ক্যানভাসটি রুমের মতোই বড় এবং আপনার কল্পনা যতটা প্রসারিত হতে পারে ততটাই বিস্তৃত।
আমরা XR-কে ডিভাইসের একটি স্পেকট্রাম হিসেবে দেখি, যার মধ্যে ইন্টেলিজেন্ট আইওয়্যার থেকে শুরু করে ইমারসিভ হেডসেট এবং তারযুক্ত XR গ্লাস পর্যন্ত বিভিন্ন ডিভাইস রয়েছে। ইন্টেলিজেন্ট আইওয়্যার অডিও ও ডিসপ্লে গ্লাসে হালকা ওজনের, অগমেন্টেড অভিজ্ঞতা প্রদান করে। অন্যদিকে, ইমারসিভ হেডসেট এবং তারযুক্ত XR গ্লাস ফোকাস, প্রোডাক্টিভিটি এবং ইমারসিভ বিনোদনের সুবিধা প্রদান করে।
Android XR ফ্যামিলির সবচেয়ে নতুন ডিভাইস হল XREAL AURA, যা আজ থেকেই কেনার জন্য উপলভ্য।
এই ডিভাইসটি হালকা ও শক্তিশালী, যা Android-এর পরিচিতির সাথে XR অভিজ্ঞতা প্রদান করে।
প্ল্যাটফর্মের জন্য আমাদের লক্ষ্য হল, আপনি যদি আগে থেকেই Android-এর জন্য ডেভেলপ করেন, তাহলে XR-এর জন্য ডেভেলপ করার জন্য আপনি প্রস্তুত।
আপনার পরিচিত একই অ্যাপ মডেল, লাইব্রেরি ও টুল ব্যবহার করে, আমরা Android XR-এ আপনার জন্য বিল্ড করা সহজ করতে চাই।
কোনও পরিবর্তন না করে বা সামান্য পরিবর্তন করে, আপনার বর্তমান 2D Android-মানানসই অ্যাপ Android XR হেডসেট এবং তারযুক্ত XR গ্লাসে কাজ করবে।
এবং XR প্ল্যাটফর্মের জন্য বিশেষভাবে তৈরি লাইব্রেরির সেট আমরা প্রদান করি যাতে আপনি বাড়িতে বসেই দুর্দান্ত XR অভিজ্ঞতা তৈরি করতে পারেন।
যেসব ডেভেলপার অন্যান্য ইমারসিভ প্ল্যাটফর্মে অভিজ্ঞতা তৈরি করতে অভ্যস্ত, তারা OpenXR এবং আমাদের 3D ইঞ্জিন সাপোর্ট, যেমন Unity, Godot এবং Unreal-এর সাহায্যে তৈরি করতে পারেন।
Android লাইব্রেরি ব্যবহার করে তৈরি করার ব্যাপারে কথা বলা যাক।
আমরা Jetpack XR SDK প্রদান করি, এটি হল Kotlin লাইব্রেরির একটি সেট যা আপনাকে ইমারসিভ ও অগমেন্টেড অভিজ্ঞতা জুড়ে XR-এ আপনার অ্যাপ এক্সটেন্ড করতে সাহায্য করে।
আমাদের ইমারসিভ লাইব্রেরিগুলি দেখে নেওয়া যাক।
আমাদের Jetpack XR লাইব্রেরি এই বছর বিটা ও স্টেবল ভার্সনে রিলিজ করা হয়েছে, যা আপনাকে ইমারসিভ XR অভিজ্ঞতা তৈরি করার জন্য প্রয়োজনীয় আত্মবিশ্বাস দেয়।
Jetpack XR-এর জন্য ARCore হল পারসেপশন লেয়ার।
এই লাইব্রেরি বাস্তব জগত সম্পর্কে তথ্য প্রদান করে, যেমন টেবিলের মতো সমতল পৃষ্ঠ কোথায় এবং ব্যবহারকারীর হাত কীভাবে অবস্থান করছে।
এটি 3D স্পেসে পয়েন্ট ট্র্যাক করতে পারে এবং সঠিক অনুমতি দেওয়া হলে অ্যাপকে সেই তথ্য প্রদান করে।
তারপর Jetpack XR SceneCore আছে, যা আপনার স্পেশিয়াল কন্টেন্ট প্লেস করার জন্য একটি সিন গ্রাফ প্রদান করে।
এই লাইব্রেরি 3D স্পেসে এন্টিটি দেখাতে পারে, সুনির্দিষ্ট সিন গ্রাফ প্লেসমেন্টের জন্য স্পেশিয়াল বিহেভিয়ার প্রদান করে।
এবং Jetpack Compose for XR নতুন সাবস্পেস কম্পোজেবল প্রদান করে যা বিশেষ করে 3D-এর জন্য তৈরি করা হয়েছে।
Android ডেভেলপাররা যারা আগে থেকেই কম্পোজ লেআউট সম্পর্কে জানেন, যেমন সারি ও কলাম দিয়ে তৈরি করা, তারা স্পেশিয়াল UI লেআউট করাকে সহজ বলে মনে করবেন।
স্পেশিয়াল রো তৈরি করে, আপনি ম্যানুয়ালি পজিশন বা সাইজ গণনা না করেই একাধিক স্পেশিয়াল প্যানেল পাশাপাশি ডিক্লেরেটিভভাবে লেআউট করতে পারবেন।
স্পেশাল প্যানেল বা অরবিটারের মতো সাবস্পেস কম্পোজেবল ব্যবহার করে, আপনি সহজেই আপনার 2D কম্পোনেন্টকে এই নতুন 3D স্পেসে প্রসারিত করতে পারবেন।
এবং অবশ্যই, সাবস্পেস কম্পোজেবল শুধু 2D কন্টেন্ট দেখানোর চেয়েও বেশি কিছু করতে পারে।
Compose for XR স্পেশিয়াল ভিডিওর পাশাপাশি স্পেশিয়াল এক্সটার্নাল সারফেস ও স্পেশিয়াল glTF মডেলের মাধ্যমে 3D মডেলও সাপোর্ট করে।
এখন, আসুন, অগমেন্টেড অ্যাপ নিয়ে কিছু আলোচনা করা যাক।
Jetpack Projected লাইব্রেরির সাহায্যে, আপনি সেন্সর এবং ডিসপ্লের মতো ইন্টেলিজেন্ট আইওয়্যার হার্ডওয়্যার ব্যবহার করার জন্য আপনার বর্তমান মোবাইল অ্যাপকে উন্নত করতে পারেন।
সবশেষে, Jetpack Compose Glimmer, চশমার জন্য অপ্টিমাইজ করা Android XR অভিজ্ঞতা তৈরি করার জন্য একটি UI টুলকিট।
Jetpack Compose Glimmer-এ আপনার XR অভিজ্ঞতা তৈরি করার জন্য স্টাইল এবং ব্যবহার করার জন্য প্রস্তুত কম্পোনেন্ট রয়েছে।
আমরা গত বছর Glimmer লঞ্চ করেছি এবং এর ক্ষমতা ক্রমাগত বাড়িয়ে চলেছি, যার মধ্যে রয়েছে একটি এজেন্টিক দক্ষতা যা আপনাকে Glimmer-এর সাহায্যে ডিসপ্লে গ্লাস অ্যাপ তৈরি করতে সাহায্য করে।
android skills add display-glasses-with-jetpack-compose-glimmerলঞ্চ করার পর থেকে আমরা আপনার মতামত শুনছি।
আমরা জানতে পেরেছি যে আপনি চান আমরা যেন Jetpack Compose Glimmer-কে ইন্টেলিজেন্ট আইওয়্যার ছাড়াও অন্যান্য ডিভাইসে ব্যবহার করার সুবিধা দিই।
আমরা আনন্দের সাথে জানাচ্ছি যে Glimmer-এর সাথে আপনার স্পেশিয়ালি অ্যাঙ্কর করা অভিজ্ঞতা আরও ভালভাবে সাপোর্ট করার জন্য আমরা পরিবর্তন করেছি, যা আমরা এই আলোচনায় পরে বিস্তারিতভাবে আলোচনা করব।
Glimmer অপ্টিমাইজ করার জন্য আমাদের কাজ শুরু হয়েছে বিভিন্ন XR ফর্ম ফ্যাক্টর জুড়ে দেখানোর জন্য একটি নতুন সারফেস তৈরি করার মাধ্যমে, ডিসপ্লে থেকে শুরু করে তারযুক্ত XR গ্লাস পর্যন্ত।
এই নতুন সারফেস যোগ করার ফলে আপনি আরও সহজে UI কাস্টমাইজ করতে পারবেন।
আপনার অ্যাপ ব্র্যান্ডের স্বতন্ত্রতা বাড়াতে, আমরা Glimmer কম্পোনেন্টে কাস্টম রঙ যোগ করেছি।
আপনার XR অ্যাপ জুড়ে ব্র্যান্ড স্টাইল প্রকাশ করতে এগুলি ব্যবহার করুন।
আমাদের Jetpack Compose Glimmer লাইব্রেরি হেল্পার ফাংশন প্রদান করে যা আপনার টার্গেট করা রঙ, ব্র্যান্ডের রঙকে গ্লাস-সেফ রঙে কনভার্ট করে।
এটি অপটিক্যাল সি-থ্রু ডিসপ্লেতে দৃশ্যমানতা অপ্টিমাইজ করার জন্য করা হয়।
তাহলে, এটি কীভাবে কাজ করে তা দেখা যাক।
আমরা এই চশমা অ্যাপের জন্য ফোকাস করা বোতামের রঙ পরিবর্তন করতে চাই, যা আমি সেট করতে চলেছি-- আমার পছন্দের রঙগুলির মধ্যে একটি বেছে নিন।
val brandColor = Color(0xFFFFAABB)
val focusedColor = ButtonDefaults.focusedColor(brandColor)
Column(…) {
LeadingImageCard(
focusable = false,
…
) {
…
}
ButtonGroup(...) {
Button(
onClick = {},
leadingIcon = { … },
focusedColor = focusedColor,
) { Text("Add to cart") }
/* Rest of the buttons */
}
}লক্ষ্য করুন যে কোডে রঙ যোগ করা হলে, Glimmer হেল্পার ফাংশন এটিকে অপ্টিমাইজ করা দৃশ্যমানতার জন্য চশমা-নিরাপদ রঙে অ্যাডজাস্ট করে।
এইসব কিছু আমাদের Jetpack Compose Glimmer লাইব্রেরির মধ্যে তৈরি করা হয়েছে, যা নিশ্চিত করে যে আপনি এমন অভিজ্ঞতা তৈরি করছেন যা বিভিন্ন এনভায়রনমেন্ট জুড়ে দারুণ দেখায়।
Android Studio-তে, আপনি এমুলেটর ব্যবহার করে দেখতে পারেন যে আপনার স্মার্টগ্লাসের UI বিভিন্ন ব্যাকগ্রাউন্ডে কেমন দেখাবে, যেমন আলো, অন্ধকার বা ব্যস্ত পরিবেশ।
এইসব আপডেট হল একেবারে প্রাথমিক আপডেট।
ঠিক আছে, না।
আমার টিম আমাকে বলেছিল যে আপনি এটি শুনে হাসবেন না, কিন্তু আমি এখনও এটি ধরে রেখেছি।
তবে এখন, আমি পলকে Jetpack Compose Glimmer সম্পর্কে আরও কিছু বলার জন্য অনুরোধ করব।
টেস্ট করা হচ্ছে, ঠিক আছে!
আমাকে পরবর্তী বোতামে ক্লিক করতে হবে।
ঠিক আছে, ধন্যবাদ ইয়াসমিন।
ঠিক আছে।
তাই, ইয়াসমিন যেমন বলেছেন, Jetpack Compose Glimmer ডিসপ্লে গ্লাসের জন্য অ্যাপ্লিকেশন ডেভেলপ করার জন্য প্রয়োজনীয় ফাউন্ডেশনাল বিল্ডিং ব্লক প্রদান করে।
আমাদের কম্পোনেন্টগুলি অপটিক্যাল সি-থ্রু ডিসপ্লের জন্য তৈরি করা পেশাদার পদ্ধতিগুলিকে ইন্টিগ্রেট করে এবং আমরা সেগুলি সরাসরি আপনাদের জন্য API-তে তৈরি করেছি, যা আপনাদের সমস্ত ডেভেলপারদের সুন্দর এবং কার্যকরী অপটিক্যাল সি-থ্রু অভিজ্ঞতা তৈরি করার ক্ষমতা দেয়।
এই ধরনের অপটিক্যাল সি-থ্রু ডিভাইসের জন্য অ্যাপ ডিজাইন ও তৈরি করার সময় আপনাকে কয়েকটি বিষয় মনে রাখতে হবে।
প্রথমত, এটি একটি ট্রান্সপারেন্ট ডিসপ্লে, যার অর্থ হল এতে কোনও কালো রঙ নেই।
যখন পৃথিবী দেখা যায় তখন কালো রঙটি স্বচ্ছ হয়।
তাই, আপনার UI, টেক্সট ও কন্টেন্টের জন্য কনট্রাস্ট বজায় রাখতে, আপনি ডার্ক ব্যাকগ্রাউন্ডের উপর নির্ভর করতে পারবেন না।
কালো রঙ অদৃশ্য হলেও, আপনি এটি ব্যবহার করে অন্যান্য ডিজিটাল কন্টেন্ট অস্পষ্ট করতে পারেন।
Glimmer UI ফ্রেমওয়ার্কে, আমাদের একটি ডেপথ API আছে যা আপনাকে সহজেই UI এলিমেন্টগুলিকে একে অপরের থেকে আলাদা করতে এবং হায়ারার্কির অনুভূতি প্রদান করতে দেয়।
এখানে, আপনি দেখতে পাবেন যে এই স্ট্যাকের কার্ডগুলির গভীরতা কীভাবে তাদের একে অপরের থেকে আলাদা থাকতে সাহায্য করে।
আমাদের ভিশন সায়েন্টিস্টরা টেক্সট ও আইকনের জন্য টার্গেট কনট্রাস্ট রেশিও প্রদান করেছেন যা বেশিরভাগ আলোর পরিস্থিতিতে দৃশ্যমান।
ইয়াসমিন যেমন দেখিয়েছেন, আমরা এটি তৈরি করতে পারি বা ফ্রেমওয়ার্কে এটি তৈরি করেছি যাতে সারফেসের রঙ কাস্টমাইজ করার সময় আপনি নিশ্চিত হতে পারেন যে ইন্টারফেসটি ব্যবহারকারীদের কাছে বোধগম্য হবে।
আমরা এই এবং অন্যান্য পেশাদার পদ্ধতি আমাদের ক্রমবর্ধমান কম্পোনেন্ট লাইব্রেরিতে তৈরি করেছি।
আমরা সম্প্রতি অনেক নতুন কম্পোনেন্ট শিপ করেছি।
আমাদের নতুন সংস্করণের মধ্যে একটি হল পেজার কম্পোনেন্ট, যাতে গ্রেসফুল মোশন ট্রানজিশন ও জেসচার বিল্ট-ইন থাকে।
val pagerState =
rememberGlimmerPagerState(pageCount = { 10 })
GlimmerHorizontalPager(pagerState) { page ->
/* Card Content */
}আপনি Compose-এর অনুভূমিক পেজার সম্পর্কে জানলে, এই কম্পোনেন্টটি আপনার কাছে পরিচিত মনে হবে।
এছাড়াও, আমরা চারটি নতুন কার্ড ভেরিয়েন্ট নিয়ে এসেছি যা পেজার, স্ট্যাক এবং অন্যান্য Glimmer UI-এর সাথে নির্বিঘ্নে ইন্টিগ্রেট করার জন্য ডিজাইন করা হয়েছে।
লিডিং ইমেজ কার্ড এবং ট্রেলিং ইমেজ কার্ডে টেক্সট এবং ছবি একে অপরের পাশে দেখানো হয়।
তাই আপনার কাছে সমান পরিমাণে টেক্সট এবং ভিজ্যুয়াল তথ্য থাকলে এই কার্ডের ভেরিয়েন্টগুলি ব্যবহার করুন।
আমরা ইমেজ কার্ডকে তার নিজস্ব কার্ড ভেরিয়েন্টে আলাদা করেছি।
এই ভিডিও পিকারের মতো, আপনার কাছে যদি একটি বড় ছবি থাকে এবং তার সাথে হয়ত এক লাইনের টেক্সট বা ক্যাপশন থাকে, তাহলে এটি ব্যবহার করা সবচেয়ে ভালো।
অ্যাকশন কার্ড ভেরিয়েন্ট একটি কার্ডে একটি বোতাম এম্বেড করে।
ব্যবহারকারী কার্ড অ্যাক্টিভেট করলে ঠিক কী হবে তা জানাতে চাইলে এটি ব্যবহার করুন, যেমন এই ডেস্টিনেশন পিকার।
বোতামের গ্রুপ আপনাকে একটি ছোট জায়গায় অনেক বোতাম প্যাক করার সুবিধা দেয়।
ButtonGroup {
Button(onClick = {}) { Text("Button 1") }
Button(onClick = {}) { Text("Button 2") }
Button(onClick = {}) { Text("Button 3") }
Button(onClick = {}) { Text("Button 4") }
Button(onClick = {}) { Text("Button 5") }
}এখানে এই সহজ কোডের মাধ্যমে আপনি এইসব সুন্দর ট্রানজিশন, স্ক্রল করার আচরণ, স্ক্রিম যা প্রান্তগুলি লুকায় এবং সেগুলি শুধুমাত্র প্রয়োজন হলেই দেখায় এবং ইনপুট যা চশমা থেকে কন্ট্রোলে অটোমেটিক রুট করা হয় তা পাবেন।
বোতাম গ্রুপে আমাদের নতুন আইকন বোতাম এবং টগল বোতামও থাকতে পারে।
var buttonChecked by remember { mutableStateOf(false) }
ToggleButton(
checked = buttonChecked,
leadingIcon = { Icon(FavoriteIcon) },
onCheckedChange = { buttonChecked = it }
) {
Text(if (buttonChecked) "On" else "Off")
}এই মিডিয়া কন্ট্রোল তৈরি করতে আমাদের সব ধরনের বোতাম এখানে ব্যবহার করা হয়েছে।
এখন বিভিন্ন ব্যাকগ্রাউন্ডে আপনার UI পরীক্ষা করা সহজ।
চশমা এমুলেটর আপনাকে ৩৬০ ডিগ্রি ফটো যোগ করতে এবং প্যান করতে দেয় যাতে আপনি বিভিন্ন ব্যাকগ্রাউন্ড, ব্যস্ত ব্যাকগ্রাউন্ড এবং আলো, অন্ধকার ইত্যাদিতে এটি পরীক্ষা করতে পারেন।
প্রাসঙ্গিক অ্যাকশন দেখানোর জন্য এই ধরনের বিস্তারিত ভিউতে বোতামের গ্রুপ ব্যবহার করা খুব ভালো।
ট্যাপ করার পরে, আপনি বিস্তারিত ভিউয়ার স্টেটে নেভিগেট করতে শেয়ার করা এলিমেন্ট ট্রানজিশন ব্যবহার করতে পারবেন, তারপর আগের ভিউতে ফিরে যেতে সিস্টেমের ব্যাক জেসচার ব্যবহার করতে পারবেন।
খুব সুন্দর।
এছাড়াও, আমরা ভয়েস ইনপুট ইন্ডিকেটর ও অ্যালার্ট ডায়ালগ যোগ করেছি।
তাই, হ্যাঁ, অনেক নতুন জিনিস।
কিন্তু এখন আমরা কিছু নতুন জিনিস দেখেছি, আসুন কিছু তৈরি করি।
ইন্টেলিজেন্ট আইওয়্যার তৈরি করতে Glimmer ব্যবহার করার পাশাপাশি, আমরা তারযুক্ত XR গ্লাসের জন্য অভিজ্ঞতা তৈরি করতে Glimmer ব্যবহার করতে পারি।
এবং আমরা চাই যে আপনি এমন অভিজ্ঞতা তৈরি করুন যা বাস্তব-জগতের লোকেশন-ভিত্তিক অ্যাঙ্কর দিয়ে শুরু করে আপনার চারপাশের বিশ্বকে আরও উন্নত করে।
ধরুন, আপনি কোনও নতুন শহরে গেছেন, হয়ত কোনও ডেভেলপার কনফারেন্সে যোগ দিতে এবং আপনি সেই শহরের আশেপাশে খাবার জায়গা খুঁজছেন।
আপনি নিজের পছন্দের নেভিগেশন অ্যাপকে আশেপাশের রেস্তোরাঁ এবং সেগুলির রেটিং খুঁজে দিতে বলতে পারেন।
লোকেশন, প্রসঙ্গ, ইন্টেলিজেন্স ও নির্দেশিকা প্রদান করে, সরাসরি লোকেশনের উপর তথ্য ওভারলে করা যেতে পারে।
এখানে, আপনি আমাদের লেটেস্ট Glimmer কম্পোনেন্ট দেখতে পাবেন, যার নাম আইকন মার্কার।
এটি আপনাকে বাস্তব জগতের মূল উপাদানগুলিকে হাইলাইট করতে এবং এই কার্ডের মতো অন্যান্য Glimmer কম্পোনেন্টের সাথে সেগুলিকে পেয়ার করতে দেয়।
এই উদাহরণে, এটি Google Maps, Places এবং Geospatial API ব্যবহার করে আগ্রহের পয়েন্টগুলি অ্যানোটেট করে।
হ্যালো ডেরেক, এটি কীভাবে সেট-আপ করতে হয় তা এদের দেখাও।
আসুন, এটি করা যাক।
ঠিক আছে।
ঠিক আছে।
তাই, পল যেমন আগে উল্লেখ করেছেন, আসুন আমরা তৈরি করা শুরু করি।
তাই, আমরা developer.android.com/xr-এ ডেভেলপার ডকুমেন্টেশন ব্যবহার করব এবং Jetpack Compose Glimmer কম্পোনেন্ট লাইব্রেরি দেখব।
তাই আপনি Glimmer-এ উপলভ্য সব কম্পোনেন্টের ভিজ্যুয়াল ওভারভিউ দেখতে পাবেন।
আর UI-এর এই অংশটি দিয়ে শুরু করা যাক যা পল আগেই দেখিয়েছেন।
তাই আমরা স্পেশিয়াল ইন্ডিকেটর ও ইনফো বক্স তৈরি করতে Glimmer UI ব্যবহার করব।
তাহলে, আমরা যে কম্পোনেন্টগুলি ব্যবহার করব সেগুলি শনাক্ত করার মাধ্যমে শুরু করা যাক।
বাঁদিকে, আপনি একটি আইকন মার্কার দেখতে পাবেন এবং ডানদিকে, আমরা একটি কার্ড ব্যবহার করব যা জায়গাটির বর্ণনা দেবে।
তাই, আপনি Android Studio-তে গেলে, আসলে আপনি এই প্যানেলটি অন্য যেকোনও কম্পোজ কম্পোনেন্টের মতোই প্রিভিউ করতে পারবেন এবং আপনি রিয়েল টাইমে আপনার পরিবর্তনগুলি দেখতে পারবেন।
তাই, আগে যেমন উল্লেখ করা হয়েছে, আপনি বিভিন্ন ধরনের ব্যাকগ্রাউন্ড এনভায়রনমেন্টে UI-এর প্রিভিউ দেখতে পারবেন এবং নিশ্চিত করতে পারবেন যে আপনার UI-এর কন্ট্রাস্ট একাধিক ধরনের পরিস্থিতিতে পর্যাপ্ত, যেমন অন্ধকার এবং আলো এনভায়রনমেন্ট।
এখন ক্যানভাস সেট করা হয়ে গেছে, আমরা একটি সারি তৈরি করব, কিছুটা স্পেস দিয়ে তাতে একটি আইকন মার্কার রাখব এবং কিছু স্যাম্পেল টেক্সট সহ একটি কার্ড রাখব।
আর আসলে, এই বিষয়ে আপনাকে সব জানানো হল।
আপনি 2D প্রিভিউতে খুশি হলে, আমরা বাস্তব দুনিয়ায় কিছু চিহ্নিত করা শুরু করতে পারি এবং UI স্পেশিয়ালাইজ করার মাধ্যমে আমরা তা করব।
এর অর্থ হল, আমরা 2D-এর পরিবর্তে 3D-তে এটি দেখাব।
তাই, স্পেশিয়াল UI সাব স্পেসে থাকে, যা ব্যবহারকারীর সামনে থাকা কিছু 3D স্পেস।
Subspace {
SpatialPanel {
VideoPlayer()
}
}And by default, a subspace actually lays out the its its contents at a comfortable distance away from the user.
তাই, Geospatial API কীভাবে ব্যবহার করতে হয় তা দেখানোর আগে, আসুন প্রথমে কাছাকাছি কিছু রাখি।
তাই, আমি আগে যে সাবস্পেস কম্পোজেবল সম্পর্কে কথা বলেছি, তাতে একটি ঐচ্ছিক প্যারামিটার আছে যা আপনাকে ফলো টার্গেট নির্দিষ্ট করতে দেয়।
val state by
qrCode.state.collectAsState()
Subspace(FollowTarget.anchor(anchor)) {
SpatialPanel {
Row {
IndicatorDot()
Spacer()
QrCodeCard(state)
}
}
}তাই বাস্তব জগতের সাথে কিছু অ্যাটাচ করতে, প্রথমে আপনাকে একটি অ্যাঙ্কর তৈরি করতে হবে যা Jetpack XR-এর জন্য ARCore থেকে পাওয়া যায়।
এবং এই উদাহরণে, আমি আসলে QR কোড শনাক্তকরণ ফিচার ব্যবহার করছি।
এবং এটি আপনাকে QR কোড পড়তে এবং ট্র্যাক করতে দেবে, যাতে আপনার কন্টেন্ট স্পেসে সেই QR কোড ফলো করতে পারে এবং আমরা আগে যে UI দেখেছি সেটি অ্যাটাচ করব।
ঠিক আছে।
তাহলে, আমি আপনাকে দেখালাম যে কীভাবে আশেপাশের বাস্তব জগতে ডিজিটাল কন্টেন্ট প্লেস করতে হয়।
এবং পলের উদাহরণে ফিরে যাওয়া যাক।
ব্যক্তিগতভাবে আমি নেদারল্যান্ডসের বাসিন্দা।
আমি মাউন্টেন ভিউ সম্পর্কে খুব বেশি জানি না।
তাই, এই ইভেন্টের পরে, আমি আপনাকে এমন একটি অ্যাপ তৈরি করতে সাহায্য করতে চাই যা আপনাকে কিছু মজাদার কফি প্লেস খুঁজে পেতে সাহায্য করবে।
তাই, আসুন দেখা যাক, Jetpack XR-এর জন্য ARCore-এ এখন উপলভ্য Geospatial API-এর মাধ্যমে আমরা কীভাবে আমাদের ব্যবহারকারীদের কিছু খুঁজে পেতে সাহায্য করতে পারি।
তাই, Geospatial API যা মূলত স্মার্টফোনে লঞ্চ করা হয়েছিল, তা এখন Android XR-এও উপলভ্য।
এটি Google Street View থেকে ডেটা ব্যবহার করে এবং কাজ করে এমন এলাকায় ডিভাইসের অবস্থান নির্ধারণ করতে জিপিএস পরিমাপের সাথে এটি একত্রিত করে।
তাই, ইন্টেলিজেন্ট আইওয়্যারে, Geospatial API ব্যবহার করে ব্যবহারকারীর লোকেশন ও কোন দিকে যাচ্ছেন তা সঠিকভাবে নির্ধারণ করা যায় এবং এটি অত্যন্ত নির্ভুল ধাপে ধাপে নেভিগেশন ব্যবহারের সুবিধা দেয়।
আর তারযুক্ত XR গ্লাসের মতো ইমারসিভ ডিভাইসে, Geospatial API আপনাকে এমন অভিজ্ঞতা তৈরি করতে দেয় যা বাস্তব জগতে সঠিকভাবে অবস্থান করে।
যেমন, আপনি বিল্ডিংয়ে স্পেশিয়াল কন্টেন্ট অ্যাঙ্কর করতে বা বিশেষ সিটি ট্যুর তৈরি করতে পারবেন।
তাহলে, এই তিনটি ধাপের মাধ্যমে Geospatial API ব্যবহার করা শুরু করা যাক।
প্রথমটি হল, আপনি Google Cloud Platform প্রোজেক্ট তৈরি করবেন এবং আপনার অ্যাপে যাচাইকরণ কনফিগার করবেন।
তারপর, আপনার অ্যাপে Geospatial API কনফিগার ও চালু করা হলে, আপনি ব্যবহারকারীর কাছে সূক্ষ্ম গ্র্যানুলারিটি ব্যবহার করে তার লোকেশন পাওয়ার অনুমতি চাইবেন।
তারপর, Geospatial API ব্যবহার করার জন্য সেশন কনফিগার করার পরে, আপনি সব সেট করে ফেলেছেন।
তাই, আপনি আমাদের নতুনভাবে রিফ্রেশ করা Android XR ডেভেলপার পৃষ্ঠায় Geospatial API-এর ডেভেলপার ডকুমেন্টেশনে সব বিবরণ খুঁজে পাবেন।
তাই, ব্যবহারকারীর লোকেশন ব্যবহার করে Google Maps Platform থেকে Places API-কে ব্যবহারকারীর কাছাকাছি কিছু দুর্দান্ত ক্যাফে খুঁজে বের করতে বলে শুরু করা যাক।
তাহলে প্রথমে, ব্যবহারকারী কোথায় আছেন?
ব্যবহারকারীর লোকেশন সম্পর্কে ক্রমাগত আপডেট পেতে আমরা Geospatial API-কে জিজ্ঞাসা করব।
produceState<AppStatus>(Initializing) {
val geospatial = Geospatial.getInstance(session)
val wait = geospatial.state.onEach {
value = WaitingForGeospatial(it.geospatialTrackingState)
}.first {
it.geospatialTrackingState == Geospatial.GeospatialTrackingState.RUNNING
}
val accuracyWait = geospatial.state.onEach {
value = WaitingForGeospatialAccuracy(it)
}.first { it.horizontalAccuracy < horizontalAccuracyRequirement }
value = WaitingForPlacesResults
val result = client.findNearby(context, accWait.geospatialPose)
value = Done(result)
}তাই, আমরা XR সেশনের মাধ্যমে জিওস্পেশিয়াল অবজেক্ট অ্যাক্সেস করব।
তারপরে, Geospatial চালু হওয়া পর্যন্ত আমরা অপেক্ষা করব, কারণ এটি প্রয়োজনীয় সেন্টার সেন্সর চালু করে এবং Cloud API-এর সাথে কানেক্ট করে।
এবং তারপর, আমরা একটি নির্দিষ্ট লেভেলের নির্ভুলতার জন্য অপেক্ষা করব।
তাই, জিপিএস পরিমাপের ডেটা পাওয়া গেলে বা ভিজ্যুয়াল পজিশনিং সিস্টেম ব্যবহারকারীর লোকেশন ম্যাচ করতে পারলে, অ্যাকুরেসি লেভেল উন্নত হতে পারে।
লোকেশন সংক্রান্ত অভিজ্ঞতা যাতে সঠিক জায়গায় অ্যাঙ্কর করা হয় এবং ফলাফল যাতে ব্যবহারকারীর আশেপাশের এলাকার হয় তা নিশ্চিত করার জন্য উচ্চ পর্যায়ের যথার্থতার জন্য অপেক্ষা করা গুরুত্বপূর্ণ।
তারপর, আমরা অবশেষে Geospatial API থেকে লোকেশন ভ্যালু ব্যবহার করে Places API-এর মাধ্যমে সার্চে পারফর্ম করার জন্য প্রস্তুত।
val bounds = CircularBounds.newInstance(
LatLng(pose.latitude, pose.longitude),
100.0, // radius, in meters
)
val placeFields = listOf(
Place.Field.ID, Place.Field.DISPLAY_NAME,
Place.Field.RATING, Place.Field.LOCATION,
)
return placesClient.searchNearby(
SearchNearbyRequest.builder(bounds, placeFields)
.setIncludedTypes(listOf(PlaceTypes.CAFE))
.setMaxResultCount(10)
.build()
).await()তাই, আমরা Places API-এর সাথে SearchNearbyRequest ব্যবহার করে ব্যবহারকারীর আগে পাওয়া লোকেশনের আশেপাশে জায়গা খুঁজব এবং ১০০ মিটারের মধ্যে ফলাফল খুঁজে পাব।
আমরা জায়গার আইডি, যে নাম দেখানো হবে, রেটিং এবং অবশ্যই লোকেশন পাব।
এবং অবশেষে, আমরা জায়গার ধরন ফিল্টার সহ নির্দিষ্ট প্যারামিটার দিয়ে সার্চ করব।
তাহলে, ডেটা সম্পর্কে এইটুকুই, এবার UI-তে ফিরে যাওয়া যাক।
তাই, আমাদের মার্কার ও ইনফো বক্স আগে থেকে কীভাবে প্লেস করতে হবে তা আমাদের খুঁজে বের করতে হবে এবং তার জন্য আমরা জিওস্পেশিয়াল অ্যাঙ্কর ব্যবহার করব।
তাই, কোডে ফিরে গিয়ে, আরও একবার, আমরা XR সেশন ব্যবহার করে Geospatial API অ্যাক্সেস করব এবং তারপরে আগে সার্চ ফলাফল থেকে পাওয়া নির্দিষ্ট অক্ষাংশ ও দ্রাঘিমাংশ ব্যবহার করে একটি জিওস্পেশিয়াল অ্যাঙ্কর তৈরি করব।
val anchorResult by produceState<AnchorResult?>(null) {
val geospatial = Geospatial.getInstance(session)
value = geospatial.createAnchorOnSurface(
place.location.latitude, place.location.longitude,
surface = GeospatialSurface.TERRAIN,
altitudeAboveSurface = 3.0,
eastUpSouthQuaternion = Quaternion()
)
}তাই, এই উদাহরণে, আমরা সেইসব কোঅর্ডিনেটে ভূখণ্ডের ৩ মিটার উপরে উচ্চতা নির্দিষ্ট করেছি, তবে আপনি কাজ করে এমন ছাদের সাথেও অ্যাটাচ করতে পারেন, যার অর্থ হল সেই লোকেশনে বিল্ডিংয়ের ছাদের সাপেক্ষে উচ্চতার ভ্যালু নির্ধারণ করা হবে।
তাই, আপনি কোয়াটার্নিয়ন ব্যবহার করে অ্যাঙ্কর ঘোরাতে পারেন, যা অ্যাঙ্করের ঘূর্ণন মান নির্দিষ্ট করে।
তবে, এই উদাহরণে আমরা ডিফল্ট সেটিংস ব্যবহার করব কারণ আমরা UI-কে ব্যবহারকারীর দিকে ঘোরাব।
তারপর, আমরা এই অ্যাঙ্করে আগের Glimmer UI অ্যাটাচ করব এবং এটি আপনাকে স্পেশিয়াল-অ্যাঙ্কর করা অভিজ্ঞতার জন্য বিল্ডিং ব্লক প্রদান করে।
when (anchorResult) {
is AnchorCreateSuccess ->
Subspace(FollowTarget.anchor(anchorResult.anchor)) {
SpatialPanel(SubspaceModifier.rotateToLookAtUser()) {
PlaceIndicator(place)
}
}
else ->
Log.e("Demo", "Failed to create anchor $anchorResult")
}তাই, আমরা বিশ্বাস করি যে Geospatial API দুর্দান্ত ওয়েফাইন্ডিং অভিজ্ঞতা প্রদান করতে পারে এবং Glimmer-এর সাহায্যে ডিজাইন করলে তা এক ঝলকে দেখে নেওয়া যায় এমন ব্যবহারকারীর অভিজ্ঞতা তৈরি করতে সাহায্য করবে যা বিশেষভাবে আপনার সি-থ্রু ডিসপ্লের জন্য তৈরি করা হয়েছে।
Geospatial API সম্পর্কে আরও তথ্যের জন্য, সম্প্রতি আপডেট করা developer.android.com/xr দেখুন।
আর আমি ইয়াসমিনকে এটি ফিরিয়ে দেব যাতে তিনি শেষ করতে পারেন।
এই সেশনে, আমরা Android XR-এর কিছু ক্ষমতা সম্পর্কে আলোচনা করেছি: Jetpack XR-এর জন্য ARCore এবং Jetpack Compose Glimmer।
তারযুক্ত XR গ্লাসে Android XR কী কী নতুন ফিচার নিয়ে আসবে তা নিয়ে আমরা উৎসাহী।
ডেভেলপাররা ইতিমধ্যেই Android XR-এর জন্য অ্যাপ তৈরি করছেন এবং আমরা আশা করি Google Play Store-এ আপনার ক্রিয়েটিভ কাজ দেখতে পাব।
আপনাকে শুরু করতে সাহায্য করার জন্য, আমাদের ডেভেলপার ডকুমেন্টেশন দেখুন, আমাদের XR এক্সপেরিমেন্ট থেকে অনুপ্রেরণা নিন এবং কোডল্যাব ব্যবহার করে শুরু করুন।
আপনাদের সকলের জন্য আমরা অনেক দুর্দান্ত XR সেশন, ডেমো এবং ওয়ার্কশপের পরিকল্পনা করেছি।
তাই, টিউন-ইন করুন এবং ইমারসিভ ও অগমেন্টেড অভিজ্ঞতা জুড়ে Android XR-এর জন্য তৈরি করা সম্পর্কে জানুন।
Android XR টিমের পক্ষ থেকে, এখানে উপস্থিত থাকার জন্য আপনাদের সকলকে অনেক ধন্যবাদ এবং আমরা আশা করি Android ডেভেলপার সামিটে বাকি সময়টা আপনারা উপভোগ করবেন।
তাই, ধন্যবাদ।
android skills add display-glasses-with-jetpack-compose-glimmerval brandColor = Color(0xFFFFAABB)
val focusedColor = ButtonDefaults.focusedColor(brandColor)
Column(…) {
LeadingImageCard(
focusable = false,
…
) {
…
}
ButtonGroup(...) {
Button(
onClick = {},
leadingIcon = { … },
focusedColor = focusedColor,
) { Text("Add to cart") }
/* Rest of the buttons */
}
}val pagerState =
rememberGlimmerPagerState(pageCount = { 10 })
GlimmerHorizontalPager(pagerState) { page ->
/* Card Content */
}ButtonGroup {
Button(onClick = {}) { Text("Button 1") }
Button(onClick = {}) { Text("Button 2") }
Button(onClick = {}) { Text("Button 3") }
Button(onClick = {}) { Text("Button 4") }
Button(onClick = {}) { Text("Button 5") }
}var buttonChecked by remember { mutableStateOf(false) }
ToggleButton(
checked = buttonChecked,
leadingIcon = { Icon(FavoriteIcon) },
onCheckedChange = { buttonChecked = it }
) {
Text(if (buttonChecked) "On" else "Off")
}Subspace {
SpatialPanel {
VideoPlayer()
}
}val state by
qrCode.state.collectAsState()
Subspace(FollowTarget.anchor(anchor)) {
SpatialPanel {
Row {
IndicatorDot()
Spacer()
QrCodeCard(state)
}
}
}produceState<AppStatus>(Initializing) {
val geospatial = Geospatial.getInstance(session)
val wait = geospatial.state.onEach {
value = WaitingForGeospatial(it.geospatialTrackingState)
}.first {
it.geospatialTrackingState == Geospatial.GeospatialTrackingState.RUNNING
}
val accuracyWait = geospatial.state.onEach {
value = WaitingForGeospatialAccuracy(it)
}.first { it.horizontalAccuracy < horizontalAccuracyRequirement }
value = WaitingForPlacesResults
val result = client.findNearby(context, accWait.geospatialPose)
value = Done(result)
}val bounds = CircularBounds.newInstance(
LatLng(pose.latitude, pose.longitude),
100.0, // radius, in meters
)
val placeFields = listOf(
Place.Field.ID, Place.Field.DISPLAY_NAME,
Place.Field.RATING, Place.Field.LOCATION,
)
return placesClient.searchNearby(
SearchNearbyRequest.builder(bounds, placeFields)
.setIncludedTypes(listOf(PlaceTypes.CAFE))
.setMaxResultCount(10)
.build()
).await()val anchorResult by produceState<AnchorResult?>(null) {
val geospatial = Geospatial.getInstance(session)
value = geospatial.createAnchorOnSurface(
place.location.latitude, place.location.longitude,
surface = GeospatialSurface.TERRAIN,
altitudeAboveSurface = 3.0,
eastUpSouthQuaternion = Quaternion()
)
}when (anchorResult) {
is AnchorCreateSuccess ->
Subspace(FollowTarget.anchor(anchorResult.anchor)) {
SpatialPanel(SubspaceModifier.rotateToLookAtUser()) {
PlaceIndicator(place)
}
}
else ->
Log.e("Demo", "Failed to create anchor $anchorResult")
}