সফ্টওয়্যার ইঞ্জিনিয়ার
এই সেশনে, আমরা ফুল-স্ক্রিন টাইল থেকে ডাইনামিক, আংশিক-উচ্চতার Wear উইজেটে বিবর্তনের বিষয়ে টেকনিক্যাল গভীর আলোচনা করব।
আমরা ইউনিফায়েড Jetpack Glance API এবং নতুন Remote Compose ইঞ্জিনের প্রযুক্তিগত সুবিধাগুলি অন্বেষণ করব, সেগুলি কীভাবে Modern Android Development-এর সাথে নির্বিঘ্নে সারিবদ্ধ হয় তার বিশদ বিবরণ দেব।
সবশেষে, আমরা লেটেস্ট UX নির্দেশিকা শেয়ার করব এবং এক নজরে দেখে নেওয়া যায় এমন পরবর্তী প্রজন্মের UI তৈরি করতে আপনাকে সাহায্য করার জন্য প্র্যাকটিক্যাল মাইগ্রেশন স্ট্র্যাটেজি নিয়ে আলোচনা করব।
ট্রান্সস্ক্রিপ্ট করা
হ্যালো, সবাইকে।
আমার নাম ফ্র্যাঙ্ক এবং আমি Wear OS-এর জন্য আমাদের গ্ল্যান্সেবল অভিজ্ঞতা সংক্রান্ত টিমের নেতৃত্ব দিই।
স্মার্টওয়াচ হল আপনার ব্যবহারকারীদের জন্য অপরিহার্য, সারাদিনের সঙ্গী এবং আজ, আমরা আপনাকে নতুন Wear উইজেট অভিজ্ঞতা কীভাবে কাজে লাগাতে হয় তা দেখাব।
আমরা দুটি বিষয় দেখব, আমরা আপনার সবচেয়ে গুরুত্বপূর্ণ ফিচারগুলি সরাসরি আপনার ব্যবহারকারীর কব্জিতে পৌঁছে দেওয়ার দিকে নজর দেব এবং আমরা লেটেস্ট API ব্যবহার করে তা করব, এমন API যা Wear OS-এর জন্য তৈরি করাকে Android ডেভেলপারদের কাছে পরিচিত এবং স্বজ্ঞাত মনে করার জন্য ডিজাইন করা হয়েছে, যেমন আপনি।
আমরা ঠিক কীভাবে এটি করছি তা দেখার জন্য আজ আমার সাথে স্টেজে যোগ দিচ্ছেন আমার দুর্দান্ত সহকর্মী এবং ডেস্ক বন্ধু ইউরি।
হ্যালো, আমি ইউরি শিমকে।
আমি Wear OS টিমের একজন ইঞ্জিনিয়ার এবং আমার মূল ফোকাস হল রিমোট কম্পোজ এপিআই-তে কাজ করা।
আজ আমি আপনাকে রিমোট কম্পোজ সম্পর্কে একটি সংক্ষিপ্ত ভূমিকা দেব এবং তারপরে টাইলস থেকে Wear উইজেটে মাইগ্রেট করার প্রক্রিয়া সম্পর্কেও কথা বলব।
এই বলে, আমি আপনাকে ফ্র্যাঙ্কের কাছে ফিরিয়ে দিচ্ছি।
দারুণ।
ধন্যবাদ, ইউরি।
আমরা আনুষ্ঠানিকভাবে আমাদের ফুল-স্ক্রিন টাইলসকে Wear উইজেটে পরিণত করার মাধ্যমে রিস্টকে ইউনিফায়েড Android উইজেট ইকোসিস্টেমে নিয়ে আসছি।
এবং যেহেতু এই অভিজ্ঞতাগুলি এখন Jetpack Glance ব্যবহার করে তৈরি করা হয়েছে, আপনি দেখতে পাবেন যে এটি একই অন্তর্নিহিত পরিকাঠামো যা মোবাইল উইজেটের জন্য ব্যবহৃত হয়।
আপনি দেখতে পাবেন যে Wear-এর জন্য অ্যাপ তৈরি করা ভবিষ্যতে আপনার কাছে আরও পরিচিত হয়ে উঠছে।
এইসব অভিজ্ঞতা প্রদান করতে, আমরা UI স্ট্যাক-- অন্তর্নিহিত UI স্ট্যাক উন্নত করছি।
Wear উইজেট রিমোট কম্পোজ দ্বারা পরিচালিত হয়, যা রিমোট UI-এর জন্য একটি নতুন Android ফ্রেমওয়ার্ক।
এর অর্থ হল, আপনি অবশেষে উইজেটের মতো আউট-অফ-অ্যাপ অভিজ্ঞতা তৈরি করতে Jetpack Compose-এর সাথে ঘনিষ্ঠভাবে সারিবদ্ধ একটি ডিক্লারেটিভ API ব্যবহার করতে পারবেন।
রিমোট কম্পোজ, পারফর্ম্যান্স ও ব্যাটারির কার্যকারিতা নিশ্চিত করার সাথে সাথে উইজেটে আধুনিক গ্রাফিক্স ও রেসপন্সিভ লেআউট নিয়ে আসে।
অ্যাপ্লিকেশন প্রসেস থেকে আপনার UI ডিকাপল করার মাধ্যমে, আপনার উইজেট নিরাপদে সিরিয়ালাইজ করা হয় এবং বিভিন্ন ধরনের Android ডিভাইসে সহজেই রেন্ডার করা হয়, দুঃখিত।
এর অর্থ হল, আপনি ন্যূনতম প্রচেষ্টায় প্রায় সমস্ত সমর্থিত রিমোট সারফেসে এই সমৃদ্ধ অভিজ্ঞতা আনতে পারেন।
টাইল থেকে উইজেটে ট্রানজিশন যতটা সম্ভব মসৃণ করতে, আমরা দুটি স্ট্যান্ডার্ড কন্টেনার সাইজ চালু করছি: ছোট এবং বড়।
এগুলি এমনভাবে ডিজাইন করা হয়েছে যাতে আপনি মোবাইলে উইজেট তৈরি করার সময় যে দুই-বাই-এক এবং দুই-বাই-দুই গ্রিড-ভিত্তিক উইজেট ফর্ম্যাট ব্যবহার করেন, তার সাথে যেন ঘনিষ্ঠভাবে সারিবদ্ধ হয়।
কিছু হার্ডওয়্যার প্রস্তুতকারকের Wear 7 থেকে শুরু করে, আপনার Wear উইজেট এখন অন্যান্য অ্যাপের উইজেটের পাশাপাশি উল্লম্বভাবে স্ক্রল করা যায় এমন ট্রেতে থাকবে।
যেমন, Samsung Galaxy Watch-এ Wear উইজেট এইভাবে দেখা যায়।
প্ল্যাটফর্মের আর্কিটেকচার এমনভাবে তৈরি করা হয়েছে যাতে ভবিষ্যতে হার্ডওয়্যার প্রস্তুতকারকরা এই প্যাটার্ন গ্রহণ করলে ভার্টিক্যালি-স্ক্রল করা যায় এমন ট্রে কাজ করতে পারে।
আর আপনাকে কোনও ব্যবহারকারী বা আগে থেকে থাকা ব্যবহারকারীকে বাদ দেওয়ার ব্যাপারে চিন্তা করতে হবে না।
Jetpack Glance Wear API-কে Wear 4 পর্যন্ত ব্যাকওয়ার্ড কম্প্যাটিবিলিটি সাপোর্ট করার জন্য ডিজাইন করা হয়েছে।
পুরনো ডিভাইসে, যেখানে উইজেট বা টাইলসের অনুভূমিক ট্রে কাজ করে, সেখানে সিস্টেম আপনার জন্য এটি ম্যানেজ করবে।
আপনি ফুল-স্ক্রিন মোড সাপোর্ট করতে চান, শুধু এই কথাটি আপনার কোডে উল্লেখ করতে হবে এবং সিস্টেম আপনার বড় উইজেট নিয়ে এইসব ডিভাইসে ফুল-স্ক্রিন ট্র্যাডিশনাল টাইল হিসেবে দেখাবে।
এখন, ইউরি আমাদের কোডের মাধ্যমে দেখাবেন যে কীভাবে আপনার আগে থেকে থাকা টাইলস Wear উইজেটে মাইগ্রেট করবেন।
ধন্যবাদ, ফ্র্যাঙ্ক।
আপনি যদি একদম শুরু থেকে নতুন Wear উইজেট তৈরি করেন, তাহলে এটি সহজ।
আপনি শুধু GlanceWearWidgetService ডিফাইন করুন এবং রিমোট কম্পোজ ব্যবহার করে আপনার UI তৈরি করুন।
তবে, আপনার অ্যাপে আগে থেকেই প্রোডাকশনে টাইল থাকলে, আপনাকে পরিষেবা, UI ও ডেটা, দুটিই মাইগ্রেট করতে হবে।
এই ট্রানজিশন যতটা সম্ভব মসৃণ করতে, আমরা এমন পথ প্রদান করেছি যা আগে থেকে থাকা ব্যবহারকারীদের জন্য নির্বিঘ্ন অভিজ্ঞতা নিশ্চিত করে।
পরিষেবার জন্য, আপনি দুটি স্ট্র্যাটেজির মধ্যে থেকে বেছে নিতে পারবেন: ডুয়াল পরিষেবা বা সিঙ্গেল পরিষেবা।
ডুয়াল পরিষেবার মাধ্যমে, যা আমরা সাজেস্ট করি, আপনি পুরনো Wear OS ডিভাইসের জন্য আপনার বিদ্যমান TileService রাখবেন এবং Wear OS 7+-এর জন্য একটি নতুন GlanceWearWidgetService যোগ করবেন।
এর বিপরীতে, একটি পরিষেবার মাধ্যমে, আপনি একটি নতুন, একক GlanceWearWidgetService তৈরি করেন যা উভয় প্রোটোকল পরিচালনা করে, পুরনো ডিভাইসে আপনার উইজেটকে একটি টাইলে অনুবাদ করার জন্য একটি সামঞ্জস্যপূর্ণ মোডে চলে।
যাই হোক না কেন, আপনি ব্যবহারকারীদের কাছে পৌঁছাতে পারবেন।
এটি শুধু আপনি ভবিষ্যতে কোন কোড বজায় রাখবেন তা প্রভাবিত করে।
এবং আমরা Android ডেভেলপার সাইটে এই দুটি প্যাটার্ন ঠিক কীভাবে এবং কখন ব্যবহার করতে হবে তার বিস্তারিত বিবরণ সহ একটি বিস্তৃত ডকুমেন্টেশন প্রকাশ করেছি।
আপনার অ্যাপের জন্য কোন স্ট্র্যাটেজি সবচেয়ে ভালো তা জানতে এটি চেক করে দেখুন।
এখন UI লেয়ার সম্পর্কে আলোচনা করা যাক।
মাইগ্রেট করার সময়, আপনার মানসিক মডেল পরিবর্তিত হয়।
আগে, টাইল ProtoLayout ব্যবহার করত, এটি Wear টাইলের জন্য বিশেষভাবে তৈরি একটি লাইব্রেরি।
অন্যদিকে, Wear Widgets, Remote Compose-এর উপর ভিত্তি করে তৈরি করা হয়।
Remote Compose, Jetpack Compose UI-এর মতো একই ফাউন্ডেশন শেয়ার করে, একই কোর কম্পাইলার ও রানটাইম ব্যবহার করে।
এবং এটি এমনভাবে ডিজাইন করা হয়েছে যাতে পরিচিত মনে হয়, ফাউন্ডেশন এবং Material 3-এর মতো Compose UI লাইব্রেরির সাথে ঘনিষ্ঠভাবে মেলে।
তবে বক্স, কলাম বা টেক্সটের পরিবর্তে, আপনি এগুলি RemoteBox, RemoteColumn বা RemoteText দিয়ে সোয়্যাপ করবেন।
এই ক্ষেত্রে, আপনি "রিমোট" লেখার সাথে অনেক বেশি পরিচিত হয়ে উঠবেন।
এছাড়াও, আপনার ওয়ার্কফ্লো আরও দ্রুত করতে, আমরা উইজেটের জন্য বিশেষভাবে ডিজাইন করা রিমোট কম্পোজ কম্পোনেন্টের একটি সম্পূর্ণ সেট অন্তর্ভুক্ত করেছি যা ব্যবহার করার জন্য প্রস্তুত।
এর অর্থ হল, Figma-তে আপনি যা পেয়েছেন তা সহ আপনার আগে থেকে থাকা Wear Material 3 ডিজাইন সহজেই উইজেটে অ্যাডাপ্ট করা যাবে, যা ইঞ্জিনিয়ার ও ডিজাইনার, উভয়ের কাছেই পরিচিত।
এই ফ্রেমওয়ার্কগুলি কতটা সামঞ্জস্যপূর্ণ তা দেখতে, আসুন একটি বাস্তব উদাহরণ দেখি।
আমরা Material 3 সুইচ বোতামের উপরে আমাদের নিজস্ব অ্যাপ কম্পোনেন্ট তৈরি করতে চলেছি।
বাঁদিকে, স্ট্যান্ডার্ড Wear Compose কম্পোনেন্ট আছে যা আপনি অ্যাপের মধ্যে লিখবেন এবং ডানদিকে Remote Compose ভার্সন আছে।
// Wear Compose
@Composable
fun HistoryEraserButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
checked: Boolean = true,
onCheckedChange: (Boolean) -> Unit = {},
)// Wear RemoteCompose
@RemoteComposable
@Composable
fun RemoteHistoryEraserButton(
onClick: Action,
modifier: RemoteModifier = RemoteModifier,
checked: RemoteBoolean = true.rb,
onCheckedChange: Action = Action.Empty,
)প্যাটার্নগুলি কতটা একই রকম তা লক্ষ্য করুন।
তবে, রিমোট কম্পোজ কোড লেখার সময়, আপনি RemoteComposable অ্যানোটেশন ব্যবহার করবেন।
এবং যেখানে আপনি মডিফায়ার এবং বুলিয়ানের মতো পরিচিত প্যারামিটার ব্যবহার করেন, সেখানে তাদের সমতুল্য রিমোট কম্পোজ টাইপ থাকে যেমন RemoteModifier এবং RemoteBoolean।
এবং আপনি ল্যাম্বডার পরিবর্তে অ্যাকশন ব্যবহার করেন।
ল্যামডার মধ্যে এক্সিকিউট করার জন্য কোড এক্সিকিউট করার পরিবর্তে, আপনাকে একটি অ্যাকশন ঘোষণা করতে হবে, যেমন পেন্ডিং ইনটেন্ট চালু করা, কোনও পরিষেবা কল করা বা কোনও মান আপডেট করা।
আমাদের কম্পোনেন্টের বডিতে যাওয়া যাক।
আপনি লক্ষ্য করবেন যে থিমিংও অ্যালাইন করা হয়েছে।
আপনি স্ট্যান্ডার্ড কম্পোজে যেভাবে করেন ঠিক সেভাবেই রিমোট কম্পোজ কম্পোনেন্টে আপনার Material 3 রঙের স্কিম প্রয়োগ করতে পারেন, যা আপনার উইজেটকে আপনার অ্যাপের ব্র্যান্ডিংয়ের সাথে হুবহু মিলিয়ে দেয়।
// Wear Compose
val colors = MaterialTheme.colorScheme
SplitSwitchButton(
checked = checked,
onCheckedChange = onCheckedChange,
toggleContentDescription = "Arm Eraser",
onContainerClick = onClick,
modifier = modifier.fillMaxWidth(),
colors =
SwitchButtonDefaults.splitSwitchButtonColors(
checkedContainerColor = colors.errorContainer, …
),
label = { Text("History Eraser") },
secondaryLabel = { Text("Don't touch it!") },
)// Wear RemoteCompose
val colors = RemoteMaterialTheme.colorScheme
RemoteSplitSwitchButton(
checked = checked,
onCheckedChange = onCheckedChange,
toggleContentDescription = "Arm Eraser".rs,
onContainerClick = onClick,
modifier = modifier.fillMaxWidth(),
colors =
RemoteSplitSwitchButtonDefaults.splitSwitchButtonColors(
checkedContainerColor = colors.errorContainer, …
),
label = { RemoteText("History Eraser".rs) },
secondaryLabel = { RemoteText("Don't touch it!".rs) },
)এবং সবশেষে, ফলাফল দেখা যাক। এর ফলে যে UI তৈরি হয় তা আপনার প্রত্যাশা অনুযায়ী পরিষ্কার, রেসপন্সিভ, অ্যানিমেটেড টগল বোতাম।
পার্থক্য বোঝা কঠিন।
ডিভাইস বা এমুলেটরে সবসময় রান না করেই আপনার উইজেট লেআউট ডিজাইন, ইটারেট ও যাচাই করতে সাহায্য করার জন্য, আমরা Wear উইজেটের জন্য কম্পোজ প্রিভিউ সাপোর্ট যোগ করেছি।
উইজেটগুলি OEM নির্দিষ্ট কন্টেইনার সীমাবদ্ধতার উপর নির্ভর করে, যেমন আকার, আকৃতি, প্যাডিং, কোণার ব্যাসার্ধ, আমরা স্ট্যান্ডার্ড প্রিভিউ টীকা তৈরি করি, কিন্তু এই কনফিগারেশনগুলি ইনজেক্ট করার জন্য একটি অতিরিক্ত প্যারামিটার প্রদানকারীর সাথে।
@Preview(name = "Squircle Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetSquirclePreview(
@PreviewParameter(SquircleAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
@Preview(name = "Round Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetRoundPreview(
@PreviewParameter(RoundAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)লাইব্রেরিটি আগে থেকে কনফিগার করা PreviewParameter প্রোভাইডার ইমপ্লিমেন্টেশন প্রদান করে যা বাস্তব-জগতের Wear OS ডিভাইসের সাথে মেলে।
এই প্রিভিউ অ্যানোটেশন আপনাকে বিভিন্ন হার্ডওয়্যার শেপ জুড়ে আপনার লেআউট সহজেই যাচাই করতে দেয়।
আপনার লেআউট পরীক্ষা করার পাশাপাশি, আপনি এই প্রিভিউগুলি ব্যবহার করে অন-ডিভাইস উইজেট পিকারের জন্য প্রয়োজনীয় স্ট্যাটিক ছবি তৈরি করতে পারেন।
@Preview(name = "Widget Picker Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetRectangularPreview(
@PreviewParameter(RectangularAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)লাইব্রেরিটি আয়তাকার প্রিভিউ আকারের জন্য একটি প্যারামিটার প্রদান করে যা সম্পূর্ণ ক্রপ না করা আয়তাকার কন্টেনারকে অনুকরণ করে।
এবং আপনি যদি দেখতে চান যে এটি বাস্তবে ঠিক কীভাবে কাজ করে, তাহলে আমরা আমাদের Horologist মিডিয়া স্যাম্পেল অ্যাপ রিফ্রেশ করেছি যাতে একটি নতুন উইজেট অন্তর্ভুক্ত করা যায় যা এই API দেখায়।
মিডিয়া উইজেটের ছোট ও বড় ভার্সন কীভাবে যোগ করতে হয় তা আমরা দেখাই।
পুরনো ProtoLayout কোড এবং নতুন Remote Compose প্রয়োগের পাশাপাশি তুলনা দেখতে GitHub-এ এটি চেক করুন।
আমরা নিশ্চিত যে এটি আপনার ভালো লাগবে।
সবশেষে, AI-এর উল্লেখ না করে এই আলোচনা সম্পূর্ণ হবে না।
আপনার মাইগ্রেশন দ্রুত করতে, আমরা GitHub-এ উইজেট মাইগ্রেশন স্কিলে একটি নতুন টাইল প্রকাশ করেছি।
আপনি নিজের পছন্দের এজেন্টের সাথে এটি ব্যবহার করতে পারেন অথবা Android CLI ব্যবহার করে সরাসরি Android Studio-তে এটি যোগ করতে পারেন।
android skills add wear-widgets
android skills add --allএখন আমি ফ্রাঁসোয়াকে সব কিছু শেষ করার জন্য হ্যান্ডওভার করছি।
ধন্যবাদ।
ধন্যবাদ, ইউরি।
আপনি দেখতেই পাচ্ছেন, আপনার টাইলকে Wear উইজেটে পরিবর্তন করা খুবই সহজ।
সংক্ষেপে, Jetpack Glance Wear এবং Remote Compose-এ মাইগ্রেট করার মাধ্যমে আপনি শুধু আপনার UI আপডেট করছেন না, বরং আপনি আরও ইউনিফায়েড Android উইজেট ইকোসিস্টেমে যোগ দিচ্ছেন।
আপনি এখন Jetpack Compose-এর সাথে সম্পূর্ণভাবে অ্যালাইন করা আধুনিক, ডিক্লারেটিভ ফ্রেমওয়ার্ক ব্যবহার করে সুন্দর, ব্যাকওয়ার্ড কম্প্যাটিবল উইজেট তৈরি করতে পারবেন।
আপনি আজই আপনার টাইল মাইগ্রেট করা শুরু করতে পারেন, আরও তথ্যের জন্য Android Developers সাইটে শুরু করার নির্দেশিকা দেখুন-- সমস্ত বিবরণের জন্য।
আমরা আপনার তৈরি করা সমস্ত অভিব্যক্তিপূর্ণ, এক নজরে দেখার অভিজ্ঞতা দেখার জন্য উন্মুখ।
আজ সকালে আমাদের সাথে যোগ দেওয়ার জন্য ধন্যবাদ এবং আশা করি কনফারেন্সের বাকি অংশ আপনি উপভোগ করবেন।
ধন্যবাদ।
// Wear Compose
@Composable
fun HistoryEraserButton(
onClick: () -> Unit,
modifier: Modifier = Modifier,
checked: Boolean = true,
onCheckedChange: (Boolean) -> Unit = {},
)// Wear RemoteCompose
@RemoteComposable
@Composable
fun RemoteHistoryEraserButton(
onClick: Action,
modifier: RemoteModifier = RemoteModifier,
checked: RemoteBoolean = true.rb,
onCheckedChange: Action = Action.Empty,
)// Wear Compose
val colors = MaterialTheme.colorScheme
SplitSwitchButton(
checked = checked,
onCheckedChange = onCheckedChange,
toggleContentDescription = "Arm Eraser",
onContainerClick = onClick,
modifier = modifier.fillMaxWidth(),
colors =
SwitchButtonDefaults.splitSwitchButtonColors(
checkedContainerColor = colors.errorContainer, …
),
label = { Text("History Eraser") },
secondaryLabel = { Text("Don't touch it!") },
)// Wear RemoteCompose
val colors = RemoteMaterialTheme.colorScheme
RemoteSplitSwitchButton(
checked = checked,
onCheckedChange = onCheckedChange,
toggleContentDescription = "Arm Eraser".rs,
onContainerClick = onClick,
modifier = modifier.fillMaxWidth(),
colors =
RemoteSplitSwitchButtonDefaults.splitSwitchButtonColors(
checkedContainerColor = colors.errorContainer, …
),
label = { RemoteText("History Eraser".rs) },
secondaryLabel = { RemoteText("Don't touch it!".rs) },
)@Preview(name = "Squircle Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetSquirclePreview(
@PreviewParameter(SquircleAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)
@Preview(name = "Round Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetRoundPreview(
@PreviewParameter(RoundAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)@Preview(name = "Widget Picker Preview", device = "spec:width=1000dp,height=1000dp,dpi=320")
@Composable
fun WeatherWidgetRectangularPreview(
@PreviewParameter(RectangularAllWidgetPreviewParams::class) params: WearWidgetParams
) = WearWidgetPreview(MockWeatherWidget(65, WeatherCondition.CLOUDY), params)android skills add wear-widgets
android skills add --all