با استفاده از Maps SDK برای اندروید، میتوانید یک برنامه پوشیدنی مبتنی بر نقشه ایجاد کنید که مستقیماً روی دستگاههای Wear OS by Google اجرا میشود. کاربران برنامه شما میتوانند با نگاه کردن به مچ دست خود، موقعیت مکانی خود را روی نقشه ببینند. به عنوان مثال، آنها میتوانند موقعیت خود را در یک مسیر ترسیم کنند، سپس برای جزئیات بزرگنمایی کنند یا روی یک نشانگر ضربه بزنند تا پنجره اطلاعات ارائه شده توسط برنامه شما را ببینند.
این صفحه عملکرد API موجود در دستگاه پوشیدنی را شرح میدهد و به شما کمک میکند تا ساخت برنامه خود را شروع کنید.
شروع کار با Wear OS
ساخت یک اپلیکیشن پوشیدنی با Maps SDK برای اندروید اساساً مشابه ساخت یک اپلیکیشن Google Maps برای هر دستگاه اندرویدی دیگر است. تفاوت در طراحی شما برای دستگاه پوشیدنی با اندازه کوچکتر است تا کاربرد و عملکرد اپلیکیشن بهینه شود.
اندروید استودیو ابزار پیشنهادی برای توسعه Wear OS است، زیرا تنظیمات پروژه، گنجاندن کتابخانه و بستهبندی آسان را فراهم میکند.
برای کمک کلی در طراحی یک برنامه پوشیدنی، به دستورالعملهای طراحی Wear OS مراجعه کنید. برای کمک در ایجاد اولین برنامه پوشیدنی خود، به راهنمای ایجاد برنامههای پوشیدنی مراجعه کنید.
ساخت اولین اپلیکیشن نقشه روی Wear OS
این راهنمای سریع فرض میکند که شما با Maps SDK برای اندروید آشنا هستید، راهنماهای Wear OS را برای ایجاد یک ماژول پوشیدنی در برنامه خود دنبال کردهاید و اکنون میخواهید یک نقشه به ماژول پوشیدنی اضافه کنید.
افزودن وابستگیها برای ماژول wear
مطمئن شوید که وابستگیهای زیر در فایل build.gradle.kts ماژول Wear OS برنامه شما گنجانده شده است:
dependencies { // ... compileOnly("com.google.android.wearable:wearable:2.9.0") implementation("com.google.android.support:wearable:2.9.0") implementation("com.google.android.gms:play-services-maps:19.0.0") // This dependency is necessary for ambient mode implementation("androidx.wear:wear:1.3.0") }
برای اطلاعات بیشتر در مورد وابستگیها، به راهنمای افزودن ماژول Wear OS در پروژه موجود خود مراجعه کنید.
پیادهسازی ژست کشیدن انگشت برای رد کردن و تنظیم رنگ پسزمینه اولیه
توصیه میشود برای نمایش نقشه روی دستگاه پوشیدنی SwipeDismissFrameLayout استفاده کنید. با استفاده از کلاس SwipeDismissFrameLayout ، میتوانید ژست swipe-to-dimiss را پیادهسازی کنید که به کاربران امکان میدهد با کشیدن انگشت از سمت چپترین لبه صفحه، از برنامه خارج شوند.
برای تنظیم یک رنگ پسزمینه اولیه سفارشی، از ویژگی map:backgroundColor XML برای تعریف رنگی که باید تا زمان بارگذاری کاشیهای نقشه نمایش داده شود، استفاده کنید.
عناصر SwipeDismissFrameLayout و backgroundColor را به عنوان ظرف SupportMapFragment به تعریف layout خود اضافه کنید:
<androidx.wear.widget.SwipeDismissFrameLayout
android:id="@+id/map_container"
android:layout_width="match_parent"
android:layout_height="match_parent">
<fragment
android:id="@+id/map"
android:name="com.google.android.gms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:backgroundColor="#fff0b2dd" />
</androidx.wear.widget.SwipeDismissFrameLayout> وقتی شیء SwipeDismissFrameLayout را در activity خود دریافت کردید، یک callback اضافه کنید و رفتار callback را طوری تنظیم کنید که عمل رد کردن (dismiss) لازم را مطابق شکل زیر انجام دهد:
کاتلین
class MainActivity : AppCompatActivity(), OnMapReadyCallback, AmbientModeSupport.AmbientCallbackProvider { public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main) // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. val controller = AmbientModeSupport.attach(this) Log.d(MainActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient) // Retrieve the containers for the root of the layout and the map. Margins will need to be // set on them to account for the system window insets. val mapFrameLayout = findViewById<SwipeDismissFrameLayout>(R.id.map_container) mapFrameLayout.addCallback(object : SwipeDismissFrameLayout.Callback() { override fun onDismissed(layout: SwipeDismissFrameLayout) { onBackPressed() } }) // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment mapFragment.getMapAsync(this) } // ... }
جاوا
public class MainActivity extends AppCompatActivity implements OnMapReadyCallback, AmbientModeSupport.AmbientCallbackProvider { public void onCreate(Bundle savedState) { super.onCreate(savedState); // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main); // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this); Log.d(MainActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient()); // Retrieve the containers for the root of the layout and the map. Margins will need to be // set on them to account for the system window insets. final SwipeDismissFrameLayout mapFrameLayout = (SwipeDismissFrameLayout) findViewById( R.id.map_container); mapFrameLayout.addCallback(new SwipeDismissFrameLayout.Callback() { @Override public void onDismissed(SwipeDismissFrameLayout layout) { onBackPressed(); } }); // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); mapFragment.getMapAsync(this); } // ... }
اضافه کردن نقشه
طبق معمول از متد فراخوانی onMapReady(GoogleMap) برای دریافت یک هندل به شیء GoogleMap استفاده کنید. این فراخوانی زمانی فعال میشود که نقشه آماده استفاده باشد. در متد فراخوانی، میتوانید نشانگرها یا چندخطیها را به نقشه اضافه کنید، شنوندهها را اضافه کنید یا دوربین را حرکت دهید. مثال زیر یک نشانگر در نزدیکی خانه اپرای سیدنی اضافه میکند:
کاتلین
private val sydney = LatLng(-33.85704, 151.21522) override fun onMapReady(googleMap: GoogleMap) { // Add a marker with a title that is shown in its info window. googleMap.addMarker( MarkerOptions().position(sydney) .title("Sydney Opera House") ) // Move the camera to show the marker. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(sydney, 10f)) }
جاوا
private static final LatLng SYDNEY = new LatLng(-33.85704, 151.21522); @Override public void onMapReady(@NonNull GoogleMap googleMap) { // Add a marker with a title that is shown in its info window. googleMap.addMarker(new MarkerOptions().position(SYDNEY) .title("Sydney Opera House")); // Move the camera to show the marker. googleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(SYDNEY, 10)); }
فعال کردن حالت محیطی
کیت توسعه نرمافزار نقشههای اندروید (Maps SDK) از حالت محیطی (ambient mode) برای برنامههای پوشیدنی پشتیبانی میکند. برنامههایی که از حالت محیطی پشتیبانی میکنند، گاهی اوقات برنامههای همیشه روشن (always on apps) نامیده میشوند. حالت محیطی زمانی فعال میشود که کاربر دیگر به طور فعال از برنامه استفاده نمیکند و به برنامه اجازه میدهد تا روی دستگاه پوشیدنی قابل مشاهده باقی بماند.
کیت توسعه نرمافزار نقشهها برای اندروید، رندر ساده و کمرنگی از نقشه را برای استفاده در حالت محیطی ارائه میدهد و سبک نقشه هنگام تغییر دستگاه از حالت تعاملی به حالت محیطی، بهطور خودکار تنظیم میشود. همه نشانگرها، اشیاء و کنترلهای رابط کاربری در حالت محیطی ناپدید میشوند. این امر مصرف برق برنامه شما را کاهش میدهد و ظاهر و حس سازگار با سایر برنامههای محیطی، مانند صفحه ساعتها، را تضمین میکند.
برای اطمینان از اینکه برنامه شما از حالت محیطی نقشه استفاده میکند، مراحل زیر را انجام دهید:
- SDK اندروید خود را بهروزرسانی کنید تا شامل پلتفرم اندروید ۶.۰ (API 23) یا بالاتر باشد، که APIهایی را فراهم میکند که به فعالیتها اجازه میدهد به حالت محیطی بروند. برای اطلاعات در مورد نحوه بهروزرسانی SDK خود، به مستندات اندروید در مورد افزودن بستههای SDK مراجعه کنید.
- با تنظیم
targetSdkVersionروی ۲۳ یا بالاتر در مانیفست برنامه ، مطمئن شوید که پروژه شما اندروید ۶.۰ یا بالاتر را هدف قرار میدهد. - وابستگیهای پوشیدنی را به فایل
build.gradle.ktsبرنامه خود اضافه کنید. نمونه را در این صفحه ببینید. - همانطور که در کلاس آموزش اندروید در مورد قابل مشاهده نگه داشتن برنامه توضیح داده شده است، ورودی کتابخانه مشترک پوشیدنی را به مانیفست برنامه پوشیدنی اضافه کنید.
- همانطور که در کلاس آموزش اندروید در مورد قابل مشاهده نگه داشتن برنامه توضیح داده شده است، مجوز
WAKE_LOCKرا به مانیفستهای برنامههای دستی و پوشیدنی اضافه کنید. - در متد
onCreate()از activity خود، متدAmbientModeSupport.attach()را فراخوانی کنید. این به سیستم عامل میگوید که برنامه همیشه روشن است، به طوری که وقتی دستگاه خاموش میشود، باید به جای بازگشت به صفحه ساعت، وارد حالت محیطی شود. - رابط
AmbientModeSupport.AmbientCallbackProviderرا در Activity خود پیادهسازی کنید تا بتواند تغییرات حالت محیطی را دریافت کند. - نقشه خود را طوری تنظیم کنید که از حالت محیطی پشتیبانی کند. میتوانید این کار را با تنظیم ویژگی
map:ambientEnabled="true"در فایل طرحبندی XML فعالیت انجام دهید، یا این کار را به صورت برنامهنویسی با تنظیمGoogleMapOptions.ambientEnabled(true)انجام دهید. این تنظیم به API اطلاع میدهد که باید کاشیهای نقشه لازم را برای استفاده در حالت محیطی از قبل بارگذاری کند. - وقتی اکتیویتی به حالت ambient mode تغییر میکند، سیستم متد
onEnterAmbient()را درAmbientCallbackکه شما ارائه میدهید، فراخوانی میکند.onEnterAmbient()نادیده بگیرید وSupportMapFragment.onEnterAmbient(ambientDetails)یاMapView.onEnterAmbient(ambientDetails)فراخوانی کنید. API به یک رندر غیرتعاملی و کمرنگ از نقشه تغییر میکند. - به طور مشابه، در
onExitAmbient()متدSupportMapFragment.onExitAmbient()یاMapView.onExitAmbient()را فراخوانی کنید. API به رندرینگ عادی نقشه تغییر حالت میدهد.
نمونه کد زیر حالت محیطی را در اکتیویتی فعال میکند:
کاتلین
class AmbientActivity : AppCompatActivity(), AmbientModeSupport.AmbientCallbackProvider { private lateinit var mapFragment: SupportMapFragment public override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main) // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. val controller = AmbientModeSupport.attach(this) Log.d(AmbientActivity::class.java.simpleName, "Is ambient enabled: " + controller.isAmbient) // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = supportFragmentManager .findFragmentById(R.id.map) as SupportMapFragment } override fun getAmbientCallback(): AmbientModeSupport.AmbientCallback { return object : AmbientModeSupport.AmbientCallback() { /** * Starts ambient mode on the map. * The API swaps to a non-interactive and low-color rendering of the map when the user is no * longer actively using the app. */ override fun onEnterAmbient(ambientDetails: Bundle) { super.onEnterAmbient(ambientDetails) mapFragment.onEnterAmbient(ambientDetails) } /** * Exits ambient mode on the map. * The API swaps to the normal rendering of the map when the user starts actively using the app. */ override fun onExitAmbient() { super.onExitAmbient() mapFragment.onExitAmbient() } } } }
جاوا
public class AmbientActivity extends AppCompatActivity implements AmbientModeSupport.AmbientCallbackProvider { private SupportMapFragment mapFragment; public void onCreate(Bundle savedState) { super.onCreate(savedState); // Set the layout. It only contains a SupportMapFragment and a DismissOverlay. setContentView(R.layout.activity_main); // Enable ambient support, so the map remains visible in simplified, low-color display // when the user is no longer actively using the app but the app is still visible on the // watch face. AmbientModeSupport.AmbientController controller = AmbientModeSupport.attach(this); Log.d(AmbientActivity.class.getSimpleName(), "Is ambient enabled: " + controller.isAmbient()); // Obtain the MapFragment and set the async listener to be notified when the map is ready. mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.map); } @Override public AmbientCallback getAmbientCallback() { return new AmbientCallback() { /** * Starts ambient mode on the map. * The API swaps to a non-interactive and low-color rendering of the map when the user is no * longer actively using the app. */ @Override public void onEnterAmbient(Bundle ambientDetails) { super.onEnterAmbient(ambientDetails); mapFragment.onEnterAmbient(ambientDetails); } /** * Exits ambient mode on the map. * The API swaps to the normal rendering of the map when the user starts actively using the app. */ @Override public void onExitAmbient() { super.onExitAmbient(); mapFragment.onExitAmbient(); } }; } }
میتوانید صفحه را در حالی که برنامه در حالت محیطی است، بهروزرسانی کنید. برای جزئیات بیشتر در مورد بهروزرسانی محتوا و حالت محیطی به طور کلی، به کلاس آموزشی اندروید در مورد قابل مشاهده نگه داشتن برنامه خود مراجعه کنید.
استفاده از نمای خیابان در Wear OS
نمای خیابان به طور کامل در دستگاههای پوشیدنی پشتیبانی میشود.
برای اینکه کاربران هنگام مشاهده یک پانورامای نمای خیابان بتوانند از برنامه خارج شوند، از رابط StreetViewPanorama.OnStreetViewPanoramaLongClickListener برای گوش دادن به یک حرکت کلیک طولانی استفاده کنید. وقتی کاربر در جایی از تصویر نمای خیابان کلیک طولانی میکند، یک رویداد onStreetViewPanoramaLongClick(StreetViewPanoramaOrientation) دریافت خواهید کرد. برای نمایش یک دکمه خروج DismissOverlayView.show() را فراخوانی کنید.
کد نمونه
یک نمونه برنامه در GitHub موجود است که میتوانید از آن به عنوان نقطه شروع برای برنامه خود استفاده کنید. این نمونه به شما نشان میدهد که چگونه یک نقشه گوگل ساده را در Wear OS راهاندازی کنید.
قابلیتهای پشتیبانیشده در API نقشهها در Wear OS
این بخش تفاوتهای قابلیتهای پشتیبانیشده برای نقشهها در دستگاههای پوشیدنی را در مقایسه با دستگاههای دستی (تلفنها و تبلتها) شرح میدهد. تمام ویژگیهای API که در زیر ذکر نشدهاند، باید طبق مستندات برای API کامل کار کنند.
| عملکرد | |
|---|---|
| حالت کاملاً تعاملی و حالت Lite | شما میتوانید از Maps SDK برای اندروید در حالت کاملاً تعاملی یا در حالت ساده استفاده کنید. اگر میخواهید عملکرد را در دستگاه پوشیدنی بهینه کنید و برنامه شما نیازی به پشتیبانی از تعاملاتی مانند حرکات، یا حرکت افقی و بزرگنمایی نقشه ندارد، حالت ساده را در نظر بگیرید. در حالت ساده، اینتنت برای اجرای برنامه موبایل گوگل مپ هنگام لمس نقشه توسط کاربر غیرفعال است و نمیتوان آن را در دستگاه پوشیدنی فعال کرد. برای مشاهده لیست کامل تفاوتهای بین حالت Lite و حالت کاملاً تعاملی، به مستندات حالت Lite مراجعه کنید. |
| نوار ابزار نقشه | نوار ابزار نقشه غیرفعال است و نمیتوان آن را در دستگاه پوشیدنی فعال کرد. |
| کنترلهای رابط کاربری | کنترلهای رابط کاربری به طور پیشفرض در دستگاههای پوشیدنی غیرفعال هستند. این شامل کنترلهای زوم، قطبنما و مکان من میشود. میتوانید طبق معمول آنها را با استفاده از کلاس UiSettings فعال کنید. |
| حرکات | حرکات تک لمسی همانطور که انتظار میرود کار میکنند. به عنوان مثال میتوان به لمس و کشیدن برای جابجایی نقشه، دوبار ضربه زدن برای بزرگنمایی و ضربه زدن با دو انگشت برای کوچکنمایی اشاره کرد. پشتیبانی از حرکات چند لمسی بسته به دستگاه کاربر متفاوت است. نمونههایی از حرکات چند لمسی شامل فشار دادن دو انگشت برای کج کردن نقشه، نیشگون گرفتن برای بزرگنمایی و چرخش دو انگشتی است. |
| نقشههای داخلی و ساختمانها | نقشههای داخلی به طور پیشفرض در دستگاههای پوشیدنی غیرفعال هستند. میتوانید آنها را با فراخوانی GoogleMap.setIndoorEnabled(true) فعال کنید. اگر نقشههای داخلی فعال باشند، نقشه سطح پیشفرض کف را نشان میدهد. عنصر رابط کاربری انتخابگر سطح در دستگاههای پوشیدنی پشتیبانی نمیشود. |
| روکش کاشی | پوششهای کاشی در دستگاههای پوشیدنی پشتیبانی نمیشوند . |
بهترین شیوهها برای توسعه با API نقشهها در Wear OS
چگونه بهترین تجربه کاربری را در اپلیکیشن خود ارائه دهید:
- نقشه باید بخش بزرگی از صفحه نمایش را اشغال کند. این امر برای بهینهسازی قابلیت استفاده از نقشه در دستگاه پوشیدنی کوچک ضروری است.
- هنگام طراحی تجربه کاربری برنامه خود، این واقعیت را در نظر بگیرید که یک دستگاه پوشیدنی باتری کمی دارد. فعال نگه داشتن صفحه نمایش و قابل مشاهده بودن نقشه بر عملکرد باتری تأثیر میگذارد.