Overview

The Site SDK provides place search services that allow your users to use location-based services more conveniently, helping you quickly acquire users. Site Kit provides the following core capabilities for you to quickly build apps with which your users can explore the world around them:

What You Will Create

In this codelab, you will create a place-related app, for example:

What You Will Learn

Hardware Requirements

Software Requirements

To integrate Site Kit, you must complete the following preparations:

For details, please refer to Preparations for Integrating HUAWEI HMS Core.

Adding the AppGallery Connect Configuration File of Your App

  1. Download the agconnect-services.json file of your app.
  2. Add the agconnect-services.json file to the app's root directory of your project.

Adding Build Dependencies

  1. Open the build.gradle file in the app's root directory of your project.
  2. Add build dependencies in the dependencies block.
    dependencies { implementation 'com.huawei.hms:site:{version}' }
  3. Add apply plugin: 'com.huawei.agconnect' to the file header.
  1. Add EditText for entering search keywords and TextView for displaying search results in the layout file.
    <?xml version="1.0" encoding="utf-8"?> <ScrollView xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent"> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="vertical"> <TextView android:layout_width="match_parent" android:layout_height="30dp" android:layout_gravity="bottom" android:background="#D3D3D3" android:gravity="center_vertical" android:paddingLeft="5dp" android:text="Parameters" android:textSize="16sp" /> <LinearLayout android:layout_width="match_parent" android:layout_height="wrap_content" android:orientation="horizontal"> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Query: " /> <EditText android:id="@+id/edit_text_text_search_query" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:autofillHints="" android:hint="" android:imeOptions="actionGo" android:inputType="text" android:text="Eiffel Tower" /> </LinearLayout> <Button android:id="@+id/button_text_search" android:layout_width="match_parent" android:layout_height="wrap_content" android:onClick="search" android:text="Search" android:textAllCaps="false" /> <TextView android:layout_width="match_parent" android:layout_height="30dp" android:layout_gravity="bottom" android:background="#D3D3D3" android:gravity="center_vertical" android:paddingLeft="5dp" android:text="Result" android:textSize="16sp" /> <TextView android:id="@+id/response_text_search" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textIsSelectable="true" /> </LinearLayout> </ScrollView>
  2. Declare a SearchService object and call SearchServiceFactory in the onCreate method to instantiate the object. To create a SearchService instance, you need to pass the Context parameter and the API key.
    • It is recommended that the Context parameter be of the Activity type. Otherwise, no update wizard will be displayed when HMS Core (APK) needs to be updated.
    • The API key is generated together with the agconnect-services.json file when you create an app in AppGallery Connect. Note that the API key must be encoded using encodeURI.
    Java sample code:
    package com.huawei.codelab.sitecodelab; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.EditText; import android.widget.TextView; import com.huawei.hms.site.api.SearchResultListener; import com.huawei.hms.site.api.SearchService; import com.huawei.hms.site.api.SearchServiceFactory; import com.huawei.hms.site.api.model.AddressDetail; import com.huawei.hms.site.api.model.SearchStatus; import com.huawei.hms.site.api.model.Site; import com.huawei.hms.site.api.model.TextSearchRequest; import com.huawei.hms.site.api.model.TextSearchResponse; import androidx.appcompat.app.AppCompatActivity; /** * Site activity entrance class. */ public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private SearchService searchService; private TextView resultTextView; private EditText queryInput; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { searchService = SearchServiceFactory.create(this, URLEncoder.encode("your_api_key", "utf-8")); } catch (UnsupportedEncodingException e) { Log.e(TAG, "encode apikey error"); } queryInput = findViewById(R.id.edit_text_text_search_query); resultTextView = findViewById(R.id.response_text_search); } }

    Kotlin sample code:

    package com.huawei.codelab.sitecodelab import android.os.Bundle import android.util.Log import android.widget.EditText import android.widget.TextView import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.FragmentActivity import com.huawei.hms.site.api.SearchService import com.huawei.hms.site.api.SearchServiceFactory import java.io.UnsupportedEncodingException import java.net.URLEncoder class MainActivity : AppCompatActivity() { companion object { private const val TAG = "MainActivity" } private lateinit var searchService: SearchService private lateinit var resultTextView: TextView private lateinit var queryInput: EditText override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) // Fixme: Please replace "API key" with your API KEY try { searchService = SearchServiceFactory.create(this, URLEncoder.encode("your_api_key", "utf-8")) } catch (e: UnsupportedEncodingException) { Log.e(TAG, "encode apikey error") } queryInput = findViewById(R.id.edit_text_text_search_query) resultTextView = findViewById(R.id.response_text_search) } }
  3. Create a TextSearchRequest object, which is the place search request body. In the object, the query parameter is mandatory, and other parameters are optional:
    • query: search keyword.
    • location: longitude and latitude to which search results need to be biased.
    • radius: search radius, in meters. The value ranges from 1 to 50,000. The default value is 50000. This parameter is used to specify an area where places are searched in priority, but not restrict the search result to this area.
    • poiType: POI type of returned places. For details about the value range, please refer to LocationType.
    • hwPoiType: Huawei POI type of returned places. This parameter is recommended. For details about the value range, please refer to HwLocationType.
    • countryCode: code of the country or region where places are searched, which complies with the ISO 3166-1 alpha-2 standard. This parameter is used to return search results in the specified country or region in priority, but not filter out all search results that are not in this country or region.
    • language: language in which search results are displayed. For details about the value range, please refer to language codes in Supported Languages. If this parameter is not passed, the language of the query field is used in priority. If the field language is unavailable, the local language will be used.
    • pageSize: number of records on each page. The value ranges from 1 to 20. The default value is 20.
    • pageIndex: current page number. The value ranges from 1 to 60. The default value is 1.
    • politicalView: political view. The value is a two-letter country/region code complying with ISO 3166-1 alpha-2. This parameter has been deprecated.
    • children: indicates whether to return child nodes. The default value is false, indicating that child nodes are not returned. If this parameter is set to true, full information about child nodes, if any, will be returned.
    • countries: multiple country or region codes. Up to 5 codes are allowed. This parameter is used to return search results in the specified countries or regions in priority, but not filter out all search results that are not in these countries or regions.
  4. Pass the created TextSearchRequest and SearchResultListener objects to the textSearch method to call it, obtain the search result from onSearchResult, and display places in the search result.
    Java sample code:
    public void search(View view) { TextSearchRequest textSearchRequest = new TextSearchRequest(); textSearchRequest.setQuery(queryInput.getText().toString()); textSearchRequest.setHwPoiType(HwLocationType.TOWER); searchService.textSearch(textSearchRequest, new SearchResultListener<TextSearchResponse>() { @Override public void onSearchResult(TextSearchResponse textSearchResponse) { StringBuilder response = new StringBuilder("\n"); response.append("success\n"); int count = 1; AddressDetail addressDetail; if (null != textSearchResponse) { if (null != textSearchResponse.getSites()) { for (Site site : textSearchResponse.getSites()) { addressDetail = site.getAddress(); response .append(String.format("[%s] name: %s, formatAddress: %s, country: %s, countryCode: %s \r\n", "" + (count++), site.getName(), site.getFormatAddress(), (addressDetail == null ? "" : addressDetail.getCountry()), (addressDetail == null ? "" : addressDetail.getCountryCode()))); } } else { response.append("textSearchResponse.getSites() is null!"); } } else { response.append("textSearchResponse is null!"); } Log.d(TAG, "search result is : " + response); resultTextView.setText(response.toString()); } @Override public void onSearchError(SearchStatus searchStatus) { Log.e(TAG, "onSearchError is: " + searchStatus.getErrorCode()); } }); }

    Kotlin sample code:

    fun search(view: View?) { val textSearchRequest = TextSearchRequest() textSearchRequest.query = queryInput.text.toString() textSearchRequest.hwPoiType = HwLocationType.TOWER searchService.textSearch(textSearchRequest, object : SearchResultListener<TextSearchResponse> { override fun onSearchResult(textSearchResponse: TextSearchResponse) { val response = StringBuilder("\n") response.append("success\n") var count = 1 var addressDetail: AddressDetail for (site in textSearchResponse.sites) { addressDetail = site.address response.append( String.format( "[%s] name: %s, formatAddress: %s, country: %s, countryCode: %s \r\n", "" + count++, site.name, site.formatAddress, if (addressDetail == null) "" else addressDetail.country, if (addressDetail == null) "" else addressDetail.countryCode ) ) } Log.d(TAG, "search result is : $response") resultTextView.text = response.toString() } override fun onSearchError(searchStatus: SearchStatus) { Log.e(TAG, "onSearchError is: " + searchStatus.errorCode) } }) }

Building, Loading, and Debugging the App

Open Gradle built in Android Studio and double-click installDebug to install the developed demo app.

Open the developed app, tap Search to search for places based on the preset search keyword Eiffel Tower, and check whether the search results can be properly displayed.

Well done. You have successfully completed this codelab and learned how to:

For more information about Site Kit, please refer to Site Kit Development Guide.
You can click here to download the source code.

Code copied