简介

位置服务SDK提供位置查询服务,既能帮助您的用户更加方便地使用位置相关服务,还能帮助您快速获取用户。Site Kit通过提供如下核心能力,帮助您快速构建基于位置服务的产品,满足用户对探索周边地点的需求:

您将建立什么

您通过位置服务SDK可以开发围绕位置搜索的App,比如:

您将会学到什么

硬件要求

软件要求

集成Site Kit能力,您需要完成以下准备工作:

具体操作,请按照HUAWEI HMS Core集成准备中详细说明来完成。

添加应用的AppGallery Connect配置文件

  1. 下载应用中的"agconnect-services.json"配置文件。
  2. 将"agconnect-services.json"文件配置在模块级目录下。

添加编译依赖

  1. 打开模块级的"build.gradle"文件。
  2. 在"dependencies"中添加如下编译依赖。
    dependencies { implementation 'com.huawei.hms:site:{version}' }
  3. 在文件头添加配apply plugin: 'com.huawei.agconnect'
  1. 在layout中添加EditText,用来输入查询的关键字;添加TextView,用来展示查询结果。
    <?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. 声明SearchService对象,并在onCreate方法中通过SearchServiceFactory实例化SearchService。创建SearchService实例需要传入Context和API Key参数:
    • Context参数建议传入Activity类型,否则在升级HMS Core(APK)时不会弹出升级界面。
    • API Key在AppGallery Connect上创建应用的时候连同"agconnect-services.json"文件同时生成的。需要对API Key进行encodeURI编码。
    Java示例代码如下:
    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示例代码如下:

    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. 创建TextSearchRequest对象,它是位置搜索的请求体。其中query是必选参数,其余可选:
    • query:搜索关键字。
    • location:搜索结果偏向的经纬度。
    • radius:搜索半径,单位:米。取值范围:[1, 50000],默认50000米。该参数只用于优先显示结果,而非将结果限制在该搜索半径内。
    • poiType:返回地点的POI类型,取值范围请参见LocationType
    • hwPoiType:返回地点的华为POI类型,取值范围请参见HwLocationType,推荐使用该类型。
    • countryCode:在指定的国家内搜索,采用ISO 3166-1 alpha-2。该参数用于优先返回指定国家的结果,而不是过滤掉所有非该国家的结果。
    • language:搜索结果的语种,取值范围请参见支持的语言的语种代码。如果不传,优先使用query字段的语种,其次使用地点的当地语言。
    • pageSize:每页返回的记录数。取值范围:[1, 20],默认20。
    • pageIndex:当前页数。取值范围:[1, 60],默认1。
    • politicalView:政治观点参数,采用ISO 3166-1-alpha-2规范的2位国家/地区码,该参数已废弃。
    • children:是否返回子节点。默认为false,不返回子节点。传入children为true,如果有子节点信息,则返回子节点的全量信息。
    • countries:支持传入多个国家码,最多5个。该参数用于优先返回指定国家的结果,而不是过滤掉所有非该国家的结果。
  4. 调用textSearch接口,需传入上一步创建的TextSearchRequest和结果监听对象SearchResultListener,从回调的onSearchResult方法中获取结果,并展示地点信息。
    Java示例代码如下:
    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示例代码如下:

    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) } }) }

编译、加载、调试

使用Android Studio自带的Gradle编译工具,双击"installDebug",即可安装Demo。

打开开发调试版本的位置服务App后,查询字符串已预置Eiffel Tower,点击"Search",查看是否能获取到结果。

干得好,您已经成功完成了codelab并学到了:

更多关于位置服务的功能请参见位置服务指南文档
您可以点击下载源码

Code copied