<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Supasin Tatiyanupanwong</title>
    <description>The latest articles on DEV Community by Supasin Tatiyanupanwong (@supasintatiyanupanwong).</description>
    <link>https://dev.to/supasintatiyanupanwong</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F378077%2F230a8937-92c4-4d1c-9770-efbdbf8873c0.png</url>
      <title>DEV Community: Supasin Tatiyanupanwong</title>
      <link>https://dev.to/supasintatiyanupanwong</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/supasintatiyanupanwong"/>
    <language>en</language>
    <item>
      <title>Encapsulates Google Maps and Huawei Maps support with Map Kit library</title>
      <dc:creator>Supasin Tatiyanupanwong</dc:creator>
      <pubDate>Sat, 02 May 2020 15:46:12 +0000</pubDate>
      <link>https://dev.to/supasintatiyanupanwong/simplify-huawei-maps-support-and-maintain-single-codebase-4jbc</link>
      <guid>https://dev.to/supasintatiyanupanwong/simplify-huawei-maps-support-and-maintain-single-codebase-4jbc</guid>
      <description>&lt;p&gt;By now, you probably know all about Huawei’s infamous U.S. trade ban. With Huawei being blacklisted by the U.S. Department of Commerce, all Huawei devices since then can no longer shipped with Google Mobile Services (GMS) by default.&lt;/p&gt;

&lt;p&gt;Given the circumstances, Huawei's current solution is to create its own platform as a replacement - Huawei Mobiles Services (HMS). Huawei Mobile Services has been around for years, but Huawei relaunched and expanded the platform following the U.S. trade ban that deprived it of GMS.&lt;/p&gt;

&lt;p&gt;One feature of GMS that being used in most of the apps I developed so far is Google Maps and with about one-fourth of my user base currently using Huawei devices, it is clear to me that supporting HMS is essential.&lt;/p&gt;

&lt;p&gt;However, supporting both GMS and HMS is quite cumbersome and requires you to maintains separate codebase for each platform. Take a look at one of the examples in the following snippets:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.huawei.hms.maps.CameraUpdateFactory&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.huawei.hms.maps.model.LatLng&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.huawei.hms.maps.model.MarkerOptions&lt;/span&gt;

&lt;span class="n"&gt;mapView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMapAsync&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LatLng&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;13.7650594&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;100.5383354&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;marker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MarkerOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMarker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;animateCaemra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CameraUpdateFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newLatLngZoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;16f&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight kotlin"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.android.gms.maps.CameraUpdateFactory&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.android.gms.maps.model.LatLng&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;com.google.android.gms.maps.model.MarkerOptions&lt;/span&gt;

&lt;span class="n"&gt;mapView&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getMapAsync&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;map&lt;/span&gt; &lt;span class="p"&gt;-&amp;gt;&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;LatLng&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;13.7650594&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;100.5383354&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="kd"&gt;val&lt;/span&gt; &lt;span class="py"&gt;marker&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="nc"&gt;MarkerOptions&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;position&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;addMarker&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;marker&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;animateCaemra&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nc"&gt;CameraUpdateFactory&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;newLatLngZoom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;location&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;16f&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You may notice that both codes are the same, except import statements. It may look simple at first, but the problem is you cannot share logic between these two APIs. That's not good.&lt;/p&gt;

&lt;p&gt;So, my solution to this problem is to implement a wrapper library that encapsulate both APIs and decide which API to be used at runtime. It is now available on &lt;a href="https://github.com/SupasinTatiyanupanwong/map-kit-android"&gt;GitHub&lt;/a&gt;.&lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--vJ70wriM--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://practicaldev-herokuapp-com.freetls.fastly.net/assets/github-logo-ba8488d21cd8ee1fee097b8410db9deaa41d0ca30b004c0c63de0a479114156f.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/SupasinTatiyanupanwong"&gt;
        SupasinTatiyanupanwong
      &lt;/a&gt; / &lt;a href="https://github.com/SupasinTatiyanupanwong/map-kit-android"&gt;
        map-kit-android
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Encapsulates Google Maps SDK for Android and HUAWEI Map Kit.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;h1&gt;
Map Kit&lt;/h1&gt;
&lt;p&gt;Abstraction wrapper that encapsulates Maps APIs of supported platforms for Android, allowing access to multiple Maps APIs while maintaining your application single codebase.&lt;/p&gt;
&lt;p&gt;Map Kit is currently providing support for Google Maps and Huawei Maps.&lt;/p&gt;
&lt;h2&gt;
Usage&lt;/h2&gt;
&lt;p&gt;This project contains 3 artifacts; &lt;code&gt;maps-core&lt;/code&gt;, &lt;code&gt;maps-google&lt;/code&gt;, and &lt;code&gt;maps-huawei&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;maps-core&lt;/code&gt; artifact provides abstraction interface to interact with Maps APIs.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;maps-google&lt;/code&gt; artifact provides Google Maps integration.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;maps-huawei&lt;/code&gt; artifact provides Huawei Maps integration.&lt;/p&gt;
&lt;h3&gt;
Migration from existing Maps APIs&lt;/h3&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Google Name&lt;/th&gt;
&lt;th&gt;Huawei Name&lt;/th&gt;
&lt;th&gt;Map Kit Name&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;com.google.android.gms.maps.*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;com.huawei.hms.maps.*&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;me.tatiyanupanwong.supasin.android.libraries.kits.maps.*&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;GoogleMap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;HuaweiMap&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MapClient&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;new LatLng()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new LatLng()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MapKit.newLatLng()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;new *Options()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;new *Options()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MapKit.new*Options()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*.builder()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*.builder()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MapKit.new*Builder()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;*Factory.*()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;*Factory.*()&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MapKit.get*Factory().*()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;Tile.NO_TILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;Tile.NO_TILE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;MapKit.noTile()&lt;/code&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;
&lt;h3&gt;
Limitations&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Models are currently not &lt;code&gt;Parcelable&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*MapOptions&lt;/code&gt; is currently not supported.&lt;/li&gt;
&lt;li&gt;Google's &lt;code&gt;StreetView&lt;/code&gt; is currently not supported.&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
Additional documentation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developers.google.com/maps/documentation/android-sdk/intro" rel="nofollow"&gt;Maps SDK for Android - Google Developer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://developer.huawei.com/consumer/en/hms/huawei-MapKit" rel="nofollow"&gt;Map Kit - HMS Core - HUAWEI Developer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
Download&lt;/h2&gt;
&lt;p&gt;Add the following to your…&lt;/p&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/SupasinTatiyanupanwong/map-kit-android"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;



&lt;p&gt;I hope you find this useful. Please check it out and thanks for reading!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;P.S.&lt;/strong&gt; I do have other library projects like this in my pipeline, so I may publish them at some point.&lt;/p&gt;

</description>
      <category>android</category>
      <category>huawei</category>
      <category>hms</category>
      <category>maps</category>
    </item>
  </channel>
</rss>
