DEV Community

HMS Community
HMS Community

Posted on

Make Search Super Easy Using Huawei Site Kit and Map Kit in Android KnowMyBoard App[ Navigation Component ] in Java

Image description
Introduction

In this article, we will learn how to integrate Huawei Site kit, Map kit and Location kit in Android application KnowMyBoard. Account Kit provides seamless login functionality to the app with large user base.

Location kit SDK for Android offers location-related APIs for Android apps. These APIs mainly relate to 6 functions like fused location, activity identification, geofence, high-precision location, indoor location, and geocoding. This mode is applicable to mobile phones and Huawei tablets. We are using Location kit to get location of user.

Huawei Map SDK for Android is a set of APIs that can be called to develop maps. You can use this SDK to easily add map-related functions to your Android app, including map display, map interaction, map drawing, and map style customization.

Huawei Site kit provides place search services including keyword search,** nearby place search*, **place detail search, and **place search suggestion*, helping your app provide convenient place-related services to attract more users and improve user loyalty. Site kit helps developers to quickly build place-based quality apps.

Following core capabilities in Site Kit to quickly build apps users can explore the world around them.

Keyword Search: Returns a place list based on keywords entered by the user.
Nearby Place Search: Searches for nearby places based on the current location of the user's device.
Place Detail Search: Searches for details about a place.
Place Search Suggestion: Returns a list of suggested places.
Autocomplete: Returns an autocomplete place and a list of suggested places based on the entered keyword.

Supported Devices

Image description
Development Overview

You need to install Android Studio IDE and I assume that you have prior knowledge of Android application development.

Hardware Requirements

A computer (desktop or laptop) running Windows 10.
Android phone (with the USB cable), which is used for debugging.
Software Requirements

Java JDK 1.8 or later.
Android Studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later
Integration steps

Step 1. Huawei developer account and complete identity verification in Huawei developer website, refer to register Huawei ID.

**Step 2. **Create project in AppGallery Connect

Step 3. Adding HMS Core SDK

Let's start coding

navigation_graph.xml

<?xml version="1.0" encoding="utf-8"?>
<navigation xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/navigation_graph"
    app:startDestination="@id/loginFragment">
    <fragment
        android:id="@+id/loginFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.LoginFragment"
        android:label="LoginFragment"/>
    <fragment
        android:id="@+id/mainFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.MainFragment"
        android:label="MainFragment"/>
    <fragment
        android:id="@+id/cameraFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.CameraFragment"
        android:label="fragment_camera"
        tools:layout="@layout/fragment_camera" />
    <fragment
        android:id="@+id/searchFragment"
        android:name="com.huawei.hms.knowmyboard.dtse.activity.fragments.SearchFragment"
        android:label="fragment_search"
        tools:layout="@layout/fragment_search" />
</navigation>
Enter fullscreen mode Exit fullscreen mode

bottom_navigation_menu.xml

<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/searchFragment"
        android:icon="@android:drawable/ic_menu_search"
        android:title="@string/search" />
    <item
        android:id="@+id/loginFragment"
        android:icon="@android:drawable/ic_menu_agenda"
        android:title="Home" />
    <item
        android:id="@+id/mainFragment"
        app:showAsAction="always"
        android:icon="@android:drawable/ic_menu_gallery"
        android:title="Gallery" />
    <item
        android:id="@+id/cameraFragment"
        android:icon="@android:drawable/ic_menu_camera"
        app:showAsAction="always"
        android:title="Camera" />
</menu>
Enter fullscreen mode Exit fullscreen mode

SearchFragment.java

public class SearchFragment extends Fragment {


    LoginViewModel loginViewModel;
    View view;
    NavController navController;
    private SearchService searchService;
    SitesAdapter adapter;
    ArrayList<Site> siteArrayList = new ArrayList<>();
    LocationResult locationResult = null;
    public SearchFragment() {
        // Required empty public constructor
    }
    ItemClickListener siteClicklistener = new ItemClickListener(){
        @Override
        public void onItemClicked(RecyclerView.ViewHolder vh, Site site, int pos){
            getActivity().getWindow().setSoftInputMode(
                    WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);
        loginViewModel.setSiteSelected(site);
        navController.navigate(R.id.loginFragment);

        }
    };

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        getActivity().getWindow().setSoftInputMode(
                WindowManager.LayoutParams.SOFT_INPUT_STATE_VISIBLE);

         view = inflater.inflate(R.layout.fragment_search, container, false);
        loginViewModel = new ViewModelProvider(getActivity()).get(LoginViewModel.class);

        SearchView searchView = view.findViewById(R.id.ed_search);
        RecyclerView recyclerView = view.findViewById(R.id.suggestion_rv);
        navController = Navigation.findNavController(getActivity(), R.id.nav_host_fragment);
        searchView.setFocusable(true);
        searchView.onActionViewExpanded();
        adapter = new SitesAdapter(siteArrayList, getContext(),siteClicklistener);
        recyclerView.setAdapter(adapter);
        recyclerView.setLayoutManager(new LinearLayoutManager(getContext()));
        recyclerView.setHasFixedSize(true);
        loginViewModel.getLocationResult().observeForever(new Observer<LocationResult>() {
            @Override
            public void onChanged(LocationResult locationResult1) {
                locationResult = locationResult1;
            }
        });
        searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
            @Override
            public boolean onQueryTextSubmit(String query) {

                return false;
            }

            @Override
            public boolean onQueryTextChange(String newText) {
                if(newText.length() > 4){
                    //keywordSearch(newText);
                    nearByPlacesSearch(newText);
                }
                return false;
            }
        });


        return view;
    }

    void keywordSearch(String search){
        try {
            String key = URLEncoder.encode(Constants.API_KEY, "UTF-8");
            // Instantiate the SearchService object.
            searchService = SearchServiceFactory.create(getContext(),  key);
            // Create a request body.
            TextSearchRequest request = new TextSearchRequest();
            request.setQuery(search);
            if(locationResult!=null){
                 Coordinate location = new Coordinate(locationResult.getLastHWLocation().getLatitude(),locationResult.getLastHWLocation().getLongitude());
                request.setLocation(location);
            }
            request.setRadius(1000);
            request.setCountryCode("IN");
            request.setLanguage("en");
            request.setPageIndex(1);
            request.setPageSize(5);
            request.setChildren(false);
            // Create a search result listener.
            SearchResultListener<TextSearchResponse> resultListener = new SearchResultListener<TextSearchResponse>() {
                // Return search results upon a successful search.
                @Override
                public void onSearchResult(TextSearchResponse results) {
                    if (results == null || results.getTotalCount() <= 0) {
                        return;
                    }
                    List<Site> sites = results.getSites();
                    if(sites == null || sites.size() == 0){
                        return;
                    }

                    siteArrayList.clear();
                    for (Site site : sites) {
                        siteArrayList.add(site);
                    }

                    siteArrayList.addAll(sites);
                    adapter.notifyDataSetChanged();
                }



                // Return the result code and description upon a search exception.
                @Override
                public void onSearchError(SearchStatus status) {
                    Log.i("TAG", "Error : " + status.getErrorCode() + " " + status.getErrorMessage());
                }
            };
            // Call the keyword search API.
            searchService.textSearch(request, resultListener);
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }

    }

    void nearByPlacesSearch(String newText){
        try{
            String key = URLEncoder.encode(Constants.API_KEY, "UTF-8");
            // Instantiate the SearchService object.
            searchService = SearchServiceFactory.create(getContext(), key);
            // Create a request body.
            NearbySearchRequest request = new NearbySearchRequest();
            if(locationResult!=null){
                Coordinate location = new Coordinate(locationResult.getLastHWLocation().getLatitude(),locationResult.getLastHWLocation().getLongitude());
                request.setLocation(location);
            }
            request.setQuery(newText);
            request.setRadius(1000);
            request.setHwPoiType(HwLocationType.ADDRESS);
            request.setLanguage("en");
            request.setPageIndex(1);
            request.setPageSize(5);
            request.setStrictBounds(false);
            // Create a search result listener.
            SearchResultListener<NearbySearchResponse> resultListener = new SearchResultListener<NearbySearchResponse>() {
                // Return search results upon a successful search.
                @Override
                public void onSearchResult(NearbySearchResponse results) {
                    if (results == null || results.getTotalCount() <= 0) {
                        return;
                    }
                    List<Site> sites = results.getSites();
                    if(sites == null || sites.size() == 0){
                        return;
                    }
                    siteArrayList.clear();
                    for (Site site : sites) {
                        siteArrayList.add(site);
                    }

                    siteArrayList.addAll(sites);
                    adapter.notifyDataSetChanged();
                }
                // Return the result code and description upon a search exception.
                @Override
                public void onSearchError(SearchStatus status) {
                    Log.i("TAG", "Error : " + status.getErrorCode() + " " + status.getErrorMessage());
                }
            };
            // Call the nearby place search API.
            searchService.nearbySearch(request, resultListener);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

}
Enter fullscreen mode Exit fullscreen mode

Result

Image description

Tricks and Tips

Makes sure that agconnect-services.json file added.
Make sure required dependencies are added
Make sure that service is enabled in AGC
Enable data binding in gradle.build file
Make sure bottom navigation id’s should be same as fragment id’s in navigation graph
Make sure that set apk key before calling service.

Conclusion

In this article, we have learnt how to integrate Huawei Site kit, Map kit and Location kit in Android application KnowMyBoard. You can also go through previous article part-3 here. Hoping Site kit and Map kit capabilities are helpful to you as well, like this sample, you can make use as per your requirement.

Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Site kit, Map kit and Location kit in Android application KnowMyBoard.

Reference

Map KitTraining video

Site KitTraining video

Top comments (0)