Expert:Chatting application using Huawei CloudDB, Auth service, Cloud Function, Location, Site, Map and Push Kits - Part 2

vivek_yadav

vivek yadav

Posted on February 11, 2022

Expert:Chatting application using Huawei CloudDB, Auth service, Cloud Function, Location, Site, Map and Push Kits - Part 2

Image description
In previous article, we have developed one to one text sending application. Now in this article, we will work on sent location in chat.

Previous article link: https://forums.developer.huawei.com/forumPortal/en/topic/0201792529223700165?fid=0101187876626530001

Huawei Kits Used
Huawei Cloud DB
Huawei Auth Service
Huawei Cloud function.
Huawei Push Kit
Location kit
Site kit
Map kit

Huawei API Used
1.Huawei Cloud Storage - Cloud storage is used to store users files like user profile image and images shared on the chat. Once files are uploaded successfully on storage we get the downloadable URL will act like the profile URL or the image content.

2.Huawei CloudDB API - Cloud DB is used to store users data, users chat and also used to manage users chat history with other users.
a) Upsert

     i) Insert data of the users from the profile.

     ii) Create and insert room id, room id is consider as a reference between two users chat. Using room id we will store all the respective chat data in                   the DB.

     iii) Insert Chat data between two users based on the room id.
Enter fullscreen mode Exit fullscreen mode

b) Query

     i) Get list of Contacts for chat.

     ii) Get list of user with whom logged in user chatted before.

     ii) Get details of the chat screen with all the chat messages which include, images, text and location.
Enter fullscreen mode Exit fullscreen mode

3.Huawei Auth Service – Using the Auth Service we are registering the user on the Ecosystem. We are using the Phone number auth service for the same to receive the OTP and verify the user here.

4.Huawei Cloud function – We are triggering the Huawei Push notification system using cloud function for the same.

5.Huawei Location kit - Using location kit we will get users current location, so that they can share with other users. Using the same location co- ordinate, we will try to receive the nearby service shows the nearby landmark.

6.Huawei Map kit –

a. Map kit is used to show users shared location and nearby landmarks on the map.

b. Static Map Query after the getting the location we will query the map static with the marker and create the link and upload that link to the webview to show the current location being shared.

7.Huawei Site Kit –To show the landmark on the map which can be shared with different users at the given time of request for this we have used the nearby service from the site kit.

8.Huawei Push kit - Push kit is used to push notification of message to other user. So when one user send message we will notify other user via push notification only.

Used the rest end point for the cloud function to send the push notification once the message is end trigger from the device.
On HMSMessage Received This is once parsing the data as per our need on the implementation wherein we will need to parse and image and location when shared by other success.
Let’s start send location in chat

Enable Location Kit , Site Kit and Map Kit on console as shown in below image.
Image description
Add dependencies

// HMS dependencies
implementation "com.huawei.hms:site:$rootProject.ext.sitekit"
implementation "com.huawei.hms:maps:$rootProject.ext.mapkit"
implementation "com.huawei.hms:location:$rootProject.ext.locationkit"

Enter fullscreen mode Exit fullscreen mode

Add run time location permission

private boolean checkLocationPermission() {
    int location_permission = ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION);
    int course_permission = ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_COARSE_LOCATION);
    return location_permission == PackageManager.PERMISSION_GRANTED && course_permission == PackageManager.PERMISSION_GRANTED;
}

Enter fullscreen mode Exit fullscreen mode

Let's design the page

We divided page into two parts one is for map view and other half is for showing nearby places.

XML

<LinearLayout 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:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:weightSum="2">

    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".15"
        android:orientation="horizontal">


        <ImageView
            android:id="@+id/imageLocation"
            android:layout_width="40dp"
            android:layout_height="match_parent"
            android:layout_centerVertical="true"
            android:padding="5dp"
            android:src="@drawable/ic_baseline_arrow_back" />

        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_centerInParent="true"
            android:layout_centerVertical="true"
            android:text="@string/send_loc"
            android:textColor="@color/black"
            android:textSize="18sp"
            android:textStyle="bold" />

        <ImageView
            android:layout_width="40dp"
            android:layout_height="match_parent"
            android:layout_alignParentEnd="true"
            android:layout_marginEnd="10dp"
            android:padding="5dp"
            android:src="@drawable/hwsearchview_ic_public_input_search"
            android:visibility="gone" />


    </RelativeLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight=".8"
        android:orientation="vertical">

        <FrameLayout
            android:layout_width="match_parent"
            android:layout_height="match_parent">


            <com.huawei.hms.maps.MapView xmlns:map="http://schemas.android.com/apk/res-auto"
                android:id="@+id/mapView"
                android:layout_width="match_parent"
                android:layout_height="match_parent"
                map:cameraTargetLat="51"
                map:cameraTargetLng="10"
                map:cameraZoom="8.5"
                map:mapType="normal"
                map:uiCompass="true"
                map:uiZoomControls="true" />
            <LinearLayout
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:orientation="horizontal">

                <Button
                    android:id="@+id/btnHospital"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_marginStart="8dp"
                    android:layout_weight="1"
                    android:text="@string/btnHospital" />

                <Button
                    android:id="@+id/btnAtm"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_toEndOf="@id/btnHospital"
                    android:layout_weight="1"
                    android:text="@string/btnAtm" />

                <Button
                    android:id="@+id/btnPetrolBunk"
                    android:layout_width="0dp"
                    android:layout_height="wrap_content"
                    android:layout_toEndOf="@id/btnAtm"
                    android:layout_weight="1"
                    android:text="@string/btnPetrol" />
            </LinearLayout>
        </FrameLayout>

    </LinearLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="0dp"
        android:layout_weight="1.05"
        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:paddingStart="5dp"
            android:text="@string/nearby_places"
            android:textColor="@color/black"
            android:textSize="16sp" />


        <RelativeLayout
            android:id="@+id/rlSendCurrentLocation"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_marginStart="20dp"
            android:paddingStart="5dp">

            <ImageView
                android:id="@+id/currentlocation_icon_iv"
                android:layout_width="40dp"
                android:layout_height="40dp"
                android:layout_centerVertical="true"
                android:scaleType="fitXY"
                android:src="@drawable/ic_baseline_location"
                android:tint="@color/colorPrimary"
                tools:ignore="UseAppTint" />

            <TextView
                android:id="@+id/currnet_location_title"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_marginStart="10dp"
                android:layout_marginTop="8dp"
                android:layout_toEndOf="@id/currentlocation_icon_iv"
                android:text="@string/send_location"
                android:textColor="@color/black"
                android:textSize="18sp" />

            <TextView
                android:id="@+id/currnet_location_accurecy"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_below="@id/currnet_location_title"
                android:layout_marginStart="10dp"
                android:layout_marginTop="1dp"
                android:layout_toEndOf="@id/currentlocation_icon_iv"
                android:text="@string/accuracy"
                android:textColor="@color/grey"
                android:textSize="14sp" />


        </RelativeLayout>

        <androidx.recyclerview.widget.RecyclerView
            android:id="@+id/rvNearByLocation"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />

        <TextView
            android:id="@+id/response_text_search"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:textIsSelectable="true" />
    </LinearLayout>
</LinearLayout>

Enter fullscreen mode Exit fullscreen mode

Image description
It's time to start coding

Get Current location

FusedLocationProviderClient mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(context);
SettingsClient mSettingsClient = LocationServices.getSettingsClient(context);
LocationRequest mLocationRequest = new LocationRequest();
mLocationRequest.setInterval(5000);
mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

mFusedLocationProviderClient.getLastLocation().addOnSuccessListener(location -> {
    AppLog.logD(TAG,
            "Lat long--->Fushed" + location.getLongitude()
                    + "," + location.getLatitude() + "," + location.getAccuracy());
    if (location != null) {
        locationMutableLiveData.postValue(location);
    }


}).addOnFailureListener(e -> {
    AppLog.logE(TAG, "error" + e);
    Toast.makeText(context, "Location not found", Toast.LENGTH_SHORT).show();

});

Enter fullscreen mode Exit fullscreen mode

Get Nearby location

public void getNearbyData(double latitude, double longitude, SearchService searchService, String locationType) {
    NearbySearchRequest request = new NearbySearchRequest();
    Coordinate location = new Coordinate(latitude, longitude);
    request.setLocation(location);
    request.setQuery(locationType);
    request.setRadius(5);
    request.setHwPoiType(HwLocationType.ADDRESS);
    request.setLanguage("en");
    request.setPageIndex(1);
    request.setPageSize(10);
    request.setStrictBounds(false);
    SearchResultListener<NearbySearchResponse> resultListener = new SearchResultListener<NearbySearchResponse>() {
        @Override
        public void onSearchResult(NearbySearchResponse results) {
            arrayListMutableLiveData.postValue(new ArrayList<>(results.getSites()));
        }

        @Override
        public void onSearchError(SearchStatus status) {
            AppLog.logE("TAG", "Error : " + status.getErrorCode() + " " + status.getErrorMessage());
        }
    };
    searchService.nearbySearch(request, resultListener);

}

Enter fullscreen mode Exit fullscreen mode

Set up Map and showing nearby places

@Override
public void onMapReady(HuaweiMap huaweiMap) {
    hMap = huaweiMap;
    hMap.setMyLocationEnabled(true);
    hMap.getUiSettings().setMyLocationButtonEnabled(true);
    Util.showProgressBar(LocationActivity.this);
    locationViewModel.getCurrentLocation(LocationActivity.this);
    locationViewModel.locationMutableLiveData.observe(LocationActivity.this, location -> {
        if (location != null) {
            this.location = location;
            updateDetails(location);
        }
    });
    locationViewModel.arrayListMutableLiveData.observe(LocationActivity.this, this::recyclerView);
}

private void updateDetails(Location location) {
    float zoom = 14.0f;
    LatLng latLng1 = new LatLng(location.getLatitude(), location.getLongitude());
    CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(latLng1, zoom);
    hMap.animateCamera(cameraUpdate);
    currentLocationAccuracy.setText(String.format("Accurate to %s meters", location.getAccuracy()));

    locationViewModel.getNearbyData(location.getLatitude(), location.getLongitude(), searchService, Constants.LOCATION_TYPE_HOSPITAL);
}

Enter fullscreen mode Exit fullscreen mode

Image description
Send chat massage

private void setMessage(String messageType) {
    ChitChatSharedPref.initializeInstance(MessageActivity.this);
    Util.showProgressBar(MessageActivity.this);
    UserChat userChat = new UserChat();
    userChat.setRoom_id(roomId);
    userChat.setMessage_timestamp(Long.parseLong(Util.getTimeStamp()));
    userChat.setChat_id(Util.getRandomNumber());
    userChat.setReceiver_name(receiverText);
    userChat.setReceiver_phone(receiverPhoneNumber);
    userChat.setSender_name(ChitChatSharedPref.getInstance().getString(Constants.USER_NAME, ""));
    userChat.setSender_phone(ChitChatSharedPref.getInstance().getString(Constants.PHONE_NUMBER, ""));

    userChat.setMessage_type(messageType);
    switch (messageType) {

        case Constants.MESSAGE_TYPE_MAP:
            userChat.setMessage_data(jsonMapModel);
            messageViewModel.saveUserChat(userChat);
            messageViewModel.userUpdatedSuccessfully.observe(MessageActivity.this, aBoolean -> {
                if (aBoolean) {
                    Util.stopProgressBar();
                    getChatList();
                    Toast.makeText(MessageActivity.this, getString(R.string.showMessageSuccess), Toast.LENGTH_SHORT).show();
                } else {
                    Util.stopProgressBar();
                    Toast.makeText(MessageActivity.this, getString(R.string.showMessageFailed), Toast.LENGTH_SHORT).show();
                }
            });
            break;
        case Constants.MESSAGE_TYPE_TEXT:
            userChat.setMessage_data(textSend.getText().toString());
            messageViewModel.saveUserChat(userChat);
            messageViewModel.userUpdatedSuccessfully.observe(MessageActivity.this, aBoolean -> {
                if (aBoolean) {
                    Util.stopProgressBar();
                    getChatList();
                } else {
                    Util.stopProgressBar();
                }
            });
            break;
    }
    messageViewModel.queryForToken(receiverPhoneNumber, MessageActivity.this);


}

Enter fullscreen mode Exit fullscreen mode

Image description
Send push notification

PushApis pushApis = new PushApis(MessageActivity.this);
if (messageType.equalsIgnoreCase(Constants.MESSAGE_TYPE_MAP)) {
    pushApis.sendPushNotification(roomId, messageType, "104739093", jsonMapModel, s);
} else if (messageType.equalsIgnoreCase(Constants.MESSAGE_TYPE_TEXT)) {
    pushApis.sendPushNotification(roomId, messageType, "104739093", MessageActivity.this.textSend.getText().toString(), s);
    textSend.setText("");
}

Enter fullscreen mode Exit fullscreen mode

Conclusion

In this article, we have learned how we can create a simple messaging application with Cloud DB, Auth Service, Push Kit , Location Kit , Site Kit and Map Kit. We can also use cloud storage to store profile picture, location, documents or audio and video files.

Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.

Reference

https://developer.huawei.com/consumer/en/agconnect/cloud-base/

https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/service-introduction-0000001050040060

https://developer.huawei.com/consumer/en/hms/huawei-locationkit/

https://developer.huawei.com/consumer/en/hms/huawei-MapKit/

https://developer.huawei.com/consumer/en/hms/huawei-sitekit/

💖 💪 🙅 🚩
vivek_yadav
vivek yadav

Posted on February 11, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related