Discover Search Widget | HMS Site Kit - Huawei Developers

More information like this, you can visit HUAWEI Developer Forum​
Most of the developers use the services of searching places, displaying or utilizing place-related information in mobile applications. You need two basic requirements to provide a complete searchbar for your users. The first thing is a layout which enables to use searching activities like entering a keyword or showing suggestions according to user’s input, and the second thing is an API which enables to utilize all place-related information to the users.
HMS Site Kit offers you a Widget that meets all your needs to provide place search services and fetching their information. It is a search component of the built-in place search suggestion feature. When a users enters a keyword in the search box, the widget displays the list of suggested places for user. If the user clicks on any place in the list, your app will receive a Site object and use it to obtain place details.
If you have any questions about how you can integrate HMS Core into your project, please take a look at below post before beginning.
https://medium.com/huawei-developers/android-integrating-your-apps-with-huawei-hms-core-1f1e2a090e98
Note: Please do not forget to activate Site Kit in AppGalery Connect (Project Setting → Manage API) and to add build dependencies to app level build.gradle file (implementation ‘com.huawei.hms:site:{version}’).
Let’s see how to use Widget of the HMS Site Kit with an example. You can use widget by adding a SearchFragment object to your layout or using the Intent object. We will use it by adding fragment in our demo project.
Code:
<?xml version="1.0" encoding="utf-8"?>
<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"
tools:context=".ui.WidgetActivity">
<fragment
android:id="@+id/widget_fragment"
android:name="com.huawei.hms.site.widget.SearchFragment"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<androidx.cardview.widget.CardView
android:id="@+id/card_widget"
android:visibility="invisible"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="16dp"
app:cardCornerRadius="10dp"
app:cardElevation="10dp"
app:cardBackgroundColor="@android:color/holo_orange_light">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="10dp">
<TextView
android:id="@+id/nameText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@android:color/white"/>
<TextView
android:id="@+id/AddressText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"/>
<TextView
android:id="@+id/locText"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"/>
<TextView
android:id="@+id/phone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="15sp"/>
</LinearLayout>
</androidx.cardview.widget.CardView>
</LinearLayout>
You can see the fragment and a cardview in the layout given above. When users selects a place from the widget, we will fetch some information about that place and display in that card. The next step is to prepare our interface class.
Code:
package com.huawei.sitekitdemohms.interfaces
import com.huawei.hms.site.api.model.Site
import com.huawei.hms.site.widget.SearchFragment
interface WidgetInterface {
interface WidgetPresenter {
fun initWidget()
}
interface WidgetView {
fun getMyFragment() : SearchFragment
fun showMySite(site: Site)
fun showMessage(message: String?)
}
}
Two interfaces are defined one for presenter and the another is for view. initWidget() will be called with presenter object to initialize the Widget component and to set SiteSelectedListener. The view instance will get the user inputs and show place details with getMyFragment() and showMySite() methods.
Code:
package com.huawei.sitekitdemohms.ui
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.View
import android.widget.TextView
import android.widget.Toast
import androidx.cardview.widget.CardView
import com.huawei.hms.site.api.model.Site
import com.huawei.hms.site.widget.SearchFragment
import com.huawei.sitekitdemohms.R
import com.huawei.sitekitdemohms.interfaces.WidgetInterface
import com.huawei.sitekitdemohms.presenters.WidgetPresenter
class WidgetActivity : AppCompatActivity(), WidgetInterface.WidgetView {
private lateinit var textName: TextView
private lateinit var textAddr: TextView
private lateinit var textLocation: TextView
private lateinit var phno: TextView
private lateinit var card: CardView
private var presenter: WidgetInterface.WidgetPresenter?=null
private lateinit var searchFragment: SearchFragment
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_widget)
textName = findViewById(R.id.nameText)
textAddr = findViewById(R.id.AddressText)
textLocation = findViewById(R.id.locText)
phno = findViewById(R.id.phone)
card = findViewById(R.id.card_widget)
card.visibility = View.INVISIBLE
searchFragment = (supportFragmentManager.findFragmentById(R.id.widget_fragment) as SearchFragment?)!!
presenter = WidgetPresenter(this)
presenter!!.initWidget()
}
override fun getMyFragment(): SearchFragment {
return searchFragment
}
override fun showMySite(site: Site) {
textName.text = site.name
textAddr.text = site.formatAddress
textLocation.text = "Lat: " + site.location.lat + ", " + "Lng: " + site.location.lng
phno.text = "Phone: " + site.poi.internationalPhone
card.visibility = View.VISIBLE
}
override fun showMessage(message: String?) {
Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
}
}
In WidgetActivity class, searchFragment is defined and initWidget method has been called with presenter object. Moreover, override methods of view interface are also defined here.
Code:
package com.huawei.sitekitdemohms.presenters
import android.annotation.SuppressLint
import com.huawei.hms.site.api.model.SearchStatus
import com.huawei.hms.site.api.model.Site
import com.huawei.hms.site.widget.SiteSelectionListener
import com.huawei.sitekitdemohms.interfaces.WidgetInterface
import com.huawei.sitekitdemohms.utils.Constants
class WidgetPresenter internal constructor(val view: WidgetInterface.WidgetView) : WidgetInterface.WidgetPresenter {
override fun initWidget() {
view.getMyFragment().setApiKey(Constants.API_KEY)
view.getMyFragment().setOnSiteSelectedListener(object : SiteSelectionListener {
@SuppressLint("SetTextI18n")
override fun onSiteSelected(site: Site) {
view.showMySite(site)
}
override fun onError(searchStatus: SearchStatus) {
view.showMessage("Sorry, we couldn't find any results matching with your query ")
}
})
}
}
In WidgetPresenter class, initWidget() method has been generated. The searchFragment is obtained via view instance and API Key has been set. Then, SiteSelectedListener has been set from the fragment to determine user selection. When user clicks on a place, details of place are obtained with showMySite() method by using the site object that returns from the API.
Note: “API Key” is required to use Widget. You can find it in agconnect-services.json file.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
This project has been developed with an architecture that enables to provide maintainable and adaptable design for developers. You can build up your app based on it to shape your usage.
In this article, we discovered the usage of Widget Component that offerred by HMS Site Kit. I hope that it will provide greate convenience for your projects.
Thank you for reading !
References
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-widget-0000001050156642

What is EMU version needed to integrate HMS Site kit ?

Related

Create and Draw Huawei Map on XAMARIN!

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Hi, as you know maps are used for different purposes in most apps. In this article, I would like to show you how to use Huawei map in Xamarin and make customizations on the map. First of all, we will follow what we need to do to add Hms Map kit to our project step by step.
Then we will focus on map customizations.
Of course, before that, we will talk about the problems you may encounter until you get to this step.
Integrating the HMS Map Kit Libraries to Xamarin Project
Let’s start. First of all, we need a Huawei developer account to use Huawei mobile services and configure our app with AppGallery Connect. Please follow the link for configuration.
How to configure app in AppGallery Connect <url>https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-Guides/config-agc-0000001050143025<url>
To use the HUAWEI Map Kit SDK for Xamarin, you need to create Xamarin Android bindings libraries from HMS Map Kit SDK for Android. After downloading the SDK files at the address below, we open a blank solution in visual studio and add these projects.
Map Kit SDK for Xamarin <url>https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-Guides/libbinding-0000001050143027<url>
Then please update the aar files in the projects.
Now we will add this solution to the our project as a reference where we will go and integrate the map kit.
We added our solution to our reference. Now we will be able to use related HMS classes in our project.
Manifest & Permissions
We have to update the application’s manifest file by declaring permissions. *Before starting this, please make sure the package name is correct since the project has been added to AppGallery Connect. Make sure that the Sha256 key is entered correctly for the respective build type and agconnect-services.json file is added to your project.
Code:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Also, we need to add a meta-data element to embed your app id in the application tag between <application> tag. It is required for this app to authenticate on the Huawei’s cloud server. You can find this id in agconnect-services.json file. If you don’t do that app couldn’t render the map.
Code:
<meta-data android:name="com.huawei.hms.client.appid" android:value="appid=YOUR_APPID"/>
Creating a Map
Currently, the HMS Core Map SDK supports two map containers: MapFragment and MapView.
MapFragment is a subclass of the Android Fragment class. You can use it to place a map within a fragment. It can also function as a map container and provide an entry for accessing a HuaweiMap object. In this article we will use a Map Fragment. First off all please add following lines to your XML file to which one you want to show map.
Code:
<fragment
android:id="@+id/mapfragment_mapfragmentdemo"
class="com.huawei.hms.maps.MapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="41.019879"
map:cameraTargetLng="29.007822"
map:cameraZoom="12"
/>
In our activity’s OnCreate method, set the layout file as the content view, load AGConnectService. Get a handle to the map fragment by calling FragmentManager.FindFragmentById. Then use GetMapAsync to register for the map callback.
Also, implement the IOnMapReadyCallback interface to our Activity and override OnMapReady method which is triggered when the map is ready to use.
Code:
class NewActivty : AppCompatActivity, IOnMapReadyCallback
{
private MapView mMapView;
private HuaweiMap hMap;
private MapFragment mapFragment;
string[] permissions = {
Android.Manifest.Permission.AccessCoarseLocation,
Android.Manifest.Permission.AccessFineLocation,
Android.Manifest.Permission.Internet };
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
mapFragment = FragmentManager.FindFragmentById<MapFragment>(Resource.Id.mapfragment_mapfragmentdemo);
mapFragment.GetMapAsync(this);
ActivityCompat.RequestPermissions(this, permissions, 100);
}
public void OnMapReady(HuaweiMap huaweiMap)
{
this.hMap = huaweiMap;
}
}
Show current location
To enable this function, set the MyLocationEnabled (true) of the HuaweiMap object
Code:
public void OnMapReady(HuaweiMap huaweiMap)
{
this.hMap = huaweiMap;
hMap.UiSettings.MyLocationButtonEnabled = true;
hMap.MyLocationEnabled = true;
}
Adding a Marker and Customization
I used more than one marker in my own project and I marked them on the map by customizing them.
You can do this directly in a method where you import the hmap object, but I created this function and I wanted to use this method by giving the necessary parameters externally.
Code:
private void addMarker(LatLng position, String title, String description)
{
Marker marker;
MarkerOptions marker3Options = new MarkerOptions()
.InvokePosition(position)
.InvokeTitle(title)
.InvokeSnippet(description);
Bitmap bitmap1 = ResourceBitmapDescriptor.DrawableToBitmap(this, ContextCompat.GetDrawable(this, Resource.Drawable.markerblue));
marker3Options.InvokeIcon(BitmapDescriptorFactory.FromBitmap(bitmap1));
marker = hMap.AddMarker(marker3Options);
hMap.MarkerDragStart += OnMarkerDragStart;
hMap.MarkerDrag += OnMarkerDrag;
hMap.MarkerDragEnd += OnMarkerDragEnd;
}
Now let’s see how our additions look on the map.
Custom Information Window
When the markers are clicked, we can display custom information messages to inform. let’s see how to do this. First, create a layout for custom info.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center"
android:background="@color/colorPrimary"
android:orientation="horizontal">
<ImageView
android:id="@+id/customInfoImage"
android:layout_width="45dp"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:adjustViewBounds="true" />
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="10dp"
android:layout_marginBottom="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<TextView
android:id="@+id/customInfoTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:ellipsize="end"
android:singleLine="true"
android:textColor="@android:color/white"
android:textSize="14sp"
android:textStyle="bold" />
<TextView
android:id="@+id/customInfoDescription"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:ellipsize="end"
android:singleLine="false"
android:maxLines="2"
android:textColor="@android:color/white"
android:textSize="12sp" />
<RatingBar
android:id="@+id/customInfoRatingBar"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="5dp"
android:numStars="5"
android:outlineAmbientShadowColor="@android:color/white"
android:layout_gravity="center_vertical"
/>
</LinearLayout>
</LinearLayout>
We need to create a adapter class to be related to this layout. We are implementing HuaweiMap.IInfoWindowAdapter to this class.
Code:
class CustomMapInfoWindow : Java.Lang.Object, HuaweiMap.IInfoWindowAdapter
{
private Activity m_context;
private View m_View;
private Marker m_currentMarker;
public CustomMapInfoWindow(Activity activity)
{
m_context = activity;
m_View = m_context.LayoutInflater.Inflate(Resource.Layout.custom_info_contents, null);
}
public View GetInfoContents(Marker marker)
{
return null;
}
public View GetInfoWindow(Marker marker)
{
if (marker == null)
return null;
m_currentMarker = marker;
ImageView imageview = m_View.FindViewById<ImageView>(Resource.Id.customInfoImage);
TextView textviewTitle = m_View.FindViewById<TextView>(Resource.Id.customInfoTitle);
TextView textviewDescription = m_View.FindViewById<TextView>(Resource.Id.customInfoDescription);
RatingBar ratingBar = m_View.FindViewById<RatingBar>(Resource.Id.customInfoRatingBar);
if (marker.Title != null)
imageview.SetImageResource(Resource.Drawable.maplogo);
textviewTitle.Text = marker.Title;
textviewDescription.Text = marker.Snippet;
ratingBar.Rating = 5;
return m_View;
}
}
Then we add it to the class in which the click event of the marker is triggered.
Code:
hMap.SetInfoWindowAdapter(new CustomMapInfoWindow(this));
public void OnMarkerClick(object sender, HuaweiMap.MarkerClickEventArgs e)
{
Toast.MakeText(this, $"Marker Click Marker ID: {e.P0.Id}", ToastLength.Short).Show();
}
Now let’s see how it looks on map.
Shape
With the HMS Core Map SDK, you can add different shapes to a map, including polylines, polygons, and circles. We can use these features for many purposes, such as creating a route between two points, expressing a specific region, or expressing the areas covered by certain regions. So the limit here is your imagination or coverage of your project.
Adding a Polyline
You can use the code block below to draw polyline. You can add as many points as you want for the route and you can give these points dynamically according to the setup of your project.
Code:
private void drawPolyline()
{
Polyline polyline;
PolylineOptions polylineOptions = new PolylineOptions()
.Add(new LatLng(41.03472222, 28.90027778), new LatLng(41.00166667, 28.97111111), new LatLng(41.00415, 29.012449), new LatLng(40.985996056, 29.035333192));
polylineOptions.InvokeColor(Color.Red);
polylineOptions.Clickable(true);
polyline = hMap.AddPolyline(polylineOptions);
}
Adding a Polygon
You can use the code block below to denote a specific region.
Code:
private void drawPolygone()
{
Polygon polygon;
PolygonOptions polygonOptions = new PolygonOptions()
.Add(new LatLng(41.01929, 28.967267), new LatLng(41.016785, 28.986971), new LatLng(41.014623, 28.999753), new LatLng(41.001917, 28.978743), new LatLng(41.002298, 28.954132));
polygonOptions.InvokeFillColor(Color.Argb(60, 255, 200, 0));
polygonOptions.InvokeStrokeColor(Color.Green);
polygonOptions.InvokeStrokeWidth(30);
polygonOptions.Clickable(true);
polygonOptions.InvokeZIndex(2);
polygon = hMap.AddPolygon(polygon1Options);
}
Adding a Circle
Whether a circle is solid or hollow can be controlled by amending the circle attributes. By default, a circle is solid. You can create your apartment by adding the code block below. You can customize many features such as scanning the inside of the circle thickness according to your purpose.
Code:
private void drawCircle()
{
Circle circle;
LatLng circleLatLng = new LatLng(40.985996056, 29.035333192);
CircleOptions circleOptions = new CircleOptions();
circle = hMap.AddCircle(circleOptions);
circleOptions.InvokeCenter(circleLatLng);
circleOptions.InvokeRadius(1800);
circleOptions.InvokeStrokeWidth(5);
circleOptions.InvokeStrokeColor(Color.Blue);
circleOptions.InvokeStrokeWidth(30);
circleOptions.Clickable(true);
circleOptions.InvokeZIndex(2);
circle = hMap.AddCircle(circleOptions);
circleOptions.Clickable(true);
hMap.CircleClick += OnCircleClick;
}
How it looks on map
Final
For any questions, please contact me. I hope this article helped you add Huawei map to your own project and learn how to use it.
Thanks for reading!
References:
Github Link : <url>https://github.com/mbatuhanulper/Hms-Xamarin-Map-Demo<url>
Docs : <url>https://developer.huawei.com/consumer/en/doc/development/HMS-Plugin-Guides/drawmap-0000001050143035<url>
How can i draw dotted and dashed polyline?

Accessing to Huawei Drive by using AppAuth and REST APIs Part 1

In a previous post I´ve Shown you how to Sign In with Huawei without HMS, now we are going to use the credentials provided by the OAUTH APIs to access Drive kit and list the user's available files. By using the REST APIs of Drive kit, your app will be able to work without depending on the HMS Core APK, even in non-huawei devices.
Previous requirements
A developer account
Adding the required dependencies
As we have seen on the previous article, we will require the dependencies of the AppAuth library and the latest version of account kit to get access to the "Huawei Id Sign In button".
Code:
implementation 'net.openid:appauth:0.7.1'
implementation 'com.squareup.okio:okio:1.15.0'
implementation 'com.huawei.agconnect:agconnect-core:1.4.1.300'
implementation 'com.huawei.hms:hwid:5.0.1.301'
In order to get access to the user's Huawei Drive, we must use Account Kit to apply for the related scopes. You can use this link to check the complete list of Drive Scopes, use the gradle dependency for Drive Kit to quickly access to all the Drive Scopes.
Code:
implementation 'com.huawei.hms:drive:5.0.0.302'
We will not enter in details about the setup of the App Auth library, you can refer to this article to easily complete the library configuration.
Building the Auth Request
We wil use our Huawei Sign In button to trigger the Auth reques when is pressed. To achieve that we need to connect the onClick event of the button with our ViewModel.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
The data binding library can help us to directly connect the layout with the ViewModel, but this library must be enabled first on the app level buidl.gradle file.
Code:
android{
buildFeatures{
dataBinding true
viewBinding true
}
}
To use the data binding library with kotlin, we must also add the kapt plugin
Code:
plugins {
id 'com.android.application'
id 'kotlin-android'
id 'com.huawei.agconnect'
id 'kotlin-kapt'
}
dependencies{
kapt 'com.android.databinding:compiler:3.1.4'
implementation 'androidx.lifecycle:lifecycle-livedata-ktx:2.2.0'
implementation 'androidx.lifecycle:lifecycle-viewmodel-ktx:2.2.0'
}
Now is time to link the layout with the ViewModel
activity_main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<layout
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">
<data>
<variable
name="mainVM"
type="com.hms.demo.appauthdrivekit.MainVM" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="15dp"
tools:context=".MainActivity">
<com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton
android:id="@+id/hwidbtn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="40dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
android:onClick="@{()->mainVM.onHwIdLogin(context)}"/>
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/welcome"
android:textSize="28sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="96dp"
android:text="@string/description"
android:textAlignment="center"
android:textSize="24sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView" />
<TextView
android:id="@+id/textView3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="28dp"
android:text="@string/instruction"
android:textSize="18sp"
app:layout_constraintBottom_toTopOf="@+id/hwidbtn"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
By using the variable tag we are preparing the ViewBinding object to receive and hold an instance of the ViewModel. To completly connect the ViewBinding with the ViewModel, we must obtain both from our activity and perform the assignation.
MainActivity.kt
Code:
class MainActivity : AppCompatActivity(), MainVM.LoginNavigator{
lateinit var viewModel:MainVM
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val binding=ActivityMainBinding.inflate(layoutInflater)
viewModel= ViewModelProviders.of(this).get(MainVM::class.java)
viewModel.navigator=this
setContentView(binding.root)
binding.mainVM=viewModel
}
}
Now the ViewModel is ready to listen the HwIdButton click events, when a click is detected, the Huawei OAuth request will be triggered.
MainVM.kt
Code:
class MainVM : ViewModel() {
var navigator:LoginNavigator?=null
fun onHwIdLogin(context: Context){
val appId = AGConnectServicesConfig.fromContext(context).getString(HuaweiUtils.KEY_APP_ID)
val params=HuaweiUtils.getParams(appId)
val authRequest=OAuthtils.buildRequest(params)
val authService = AuthorizationService(context)
val authIntent = authService.getAuthorizationRequestIntent(authRequest)
navigator?.navigateToHwLogin(authIntent)
authService.dispose()
}
interface LoginNavigator{
fun navigateToHwLogin(intent : Intent)
}
}
Tips & Tricks
If you want to use the App Auth library to sign in with other account systems, you can define a Data Class to hold all the required parameters by a given account system to build the auth request.
Code:
data class OAuthParams(var authEndpoint:String,
var tokenEndpoint:String,
var appId:String,
var responseTypeValues:String,
var redirectUri:Uri,
var scopes:List<String>)
object OAuthtils{
fun buildRequest(params:OAuthParams): AuthorizationRequest{
val serviceConfig = AuthorizationServiceConfiguration(
Uri.parse(params.authEndpoint), // authorization endpoint
Uri.parse(params.tokenEndpoint)// token endpoint
)
val authRequestBuilder = AuthorizationRequest.Builder(
serviceConfig, // the authorization service configuration
params.appId, // the client ID, typically pre-registered and static
params.responseTypeValues, //
params.redirectUri//The redirect URI
)
val stringBuilder= StringBuilder()
for(scope in params.scopes){
stringBuilder.append("$scope ")
}
authRequestBuilder.setScope(stringBuilder.toString())
return authRequestBuilder.build()
}
}
The related parameters for the Huawei Auth Request will be encapsulated on the HuaweiUtils object. Other objects can be defined to hold the params for other account systems which support OAuth.
Code:
object HuaweiUtils {
private const val AUTH_ENDPOINT = "https://oauth-login.cloud.huawei.com/oauth2/v3/authorize"
private const val TOKEN_ENDPOINT = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"
private const val HW_REDIRECT_URI_PREFIX = "com.huawei.apps."
private const val HW_REDIRECT_URI_SUFFIX=":/oauth2redirect"
const val KEY_APP_ID="client/app_id"
const val HW_ID_CODE = 100
fun getParams(appId:String):OAuthParams{
val scopes= getHuaweiScopes()
val redirectUri=Uri.parse("${HW_REDIRECT_URI_PREFIX}appid${HW_REDIRECT_URI_SUFFIX}")
return OAuthParams(
AUTH_ENDPOINT,
TOKEN_ENDPOINT,
appId,
ResponseTypeValues.CODE,
redirectUri,
scopes
)
}
private fun getHuaweiScopes():List<String>{
return listOf("openid",
"email",
"profile",
DriveScopes.SCOPE_DRIVE,
DriveScopes.SCOPE_DRIVE_APPDATA,
DriveScopes.SCOPE_DRIVE_FILE,
DriveScopes.SCOPE_DRIVE_METADATA,
DriveScopes.SCOPE_DRIVE_METADATA_READONLY,
DriveScopes.SCOPE_DRIVE_READONLY
)
}
}
Connecting to Huawei Drive
We will use the Auth credentials obtained from the LoginActivity to connect with Huawei Drive. As you may know, the AccessToken obtaining via OAuth has an exiration time, the AppAuth library provides us an API to always use fresh tokens.
Code:
authState.performActionWithFreshTokens(service, new AuthStateAction() {
@Override public void execute(
String accessToken,
String idToken,
AuthorizationException ex) {
if (ex != null) { // negotiation for fresh tokens failed, check ex for more details
return;
} // use the access token to do something ...
}
});
Lets define the layout of our DriveActivity, we will need to know tthe identity of the user and the available space on Huawei Drive. The list of stored Items on Drive will be added later.
More details, you can visit
Drive kit supports India region ?
Interesting.

Integration of Text to Speech feature of Huawei ML Kit in Book Reading Android app (Kotlin) - Part 4

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we can learn how to integrate the Text to Speech feature of Huawei ML Kit in Book Reading app. Text to speech (TTS) can convert text information into human voice in real time. This service uses Deep Neural Networks in order to process the text and create a natural sound, rich timbers are also supported to enhance the result. TTS is widely used in broadcasting, news, voice navigation, and audio reading. For example, TTS can convert a large amount of text into speech output and highlight the content that is being played to free users eyes, bringing interests to users. TTS records a voice segment based on navigation data, and then synthesizes the voice segment into navigation voice, so that navigation is more personalized.
Precautions
1. The text in a single request can contain a maximum of 500 characters and is encoded using UTF-8.
2. Currently, TTS in French, Spanish, German, Italian, Russian, Thai, Malay, and Polish is deployed only in China, Asia, Africa, Latin America, and Europe.
3. TTS depends on on-cloud APIs. During commissioning and usage, ensure that the device can access the Internet.
4. Default specifications of the real-time output audio data are as follows: MP3 mono, 16-bit depth, and 16 kHz audio sampling rate.
Requirements
1. Any operating system (MacOS, Linux and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification in Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Click Manage APIs tab and enable ML Kit.
9. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
10. Add the below plugin and dependencies in build.gradle(Module) file.
Code:
apply plugin: id 'com.huawei.agconnect'
dataBinding {
enabled = true
}
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// ML Kit - Text to Speech
implementation 'com.huawei.hms:ml-computer-voice-tts:3.3.0.305'
// Data Binding
implementation 'androidx.databinding:databinding-runtime:7.1.1'
11. Now Sync the gradle.
12. Add the required permission to the AndroidManifest.xml file.
Code:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the ListActivity.kt to find the button click.
Java:
class ListActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_list)
btn_voice.setOnClickListener {
val intent = Intent([email protected], TranslateActivity::class.java)
startActivity(intent)
}
}
}
In the TranslateActivity.kt to find the business logic for text translation.
Java:
class TranslateActivity : AppCompatActivity() {
private lateinit var binding: ActivityTranslateBinding
private lateinit var ttsViewModel: TtsViewModel
private var sourceText: String = ""
private lateinit var mlTtsEngine: MLTtsEngine
private lateinit var mlConfigs: MLTtsConfig
private val TAG: String = TranslateActivity::class.java.simpleName
private var callback: MLTtsCallback = object : MLTtsCallback {
override fun onError(taskId: String, err: MLTtsError) {
}
override fun onWarn(taskId: String, warn: MLTtsWarn) {
}
override fun onRangeStart(taskId: String, start: Int, end: Int) {
Log.d("", start.toString())
img_view.setImageResource(R.drawable.on)
}
override fun onAudioAvailable(p0: String?, p1: MLTtsAudioFragment?, p2: Int, p3: android.util.Pair<Int, Int>?, p4: Bundle?) {
}
override fun onEvent(taskId: String, eventName: Int, bundle: Bundle?) {
if (eventName == MLTtsConstants.EVENT_PLAY_STOP) {
Toast.makeText(applicationContext, "Service Stopped", Toast.LENGTH_LONG).show()
}
img_view.setImageResource(R.drawable.off)
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(activity_translate)
binding = setContentView(this, activity_translate)
binding.lifecycleOwner = this
ttsViewModel = ViewModelProvider(this).get(TtsViewModel::class.java)
binding.ttsViewModel = ttsViewModel
setApiKey()
supportActionBar?.title = "Text to Speech Conversion"
ttsViewModel.ttsService.observe(this, Observer {
startTtsService()
})
ttsViewModel.textData.observe(this, Observer {
sourceText = it
})
}
private fun startTtsService() {
mlConfigs = MLTtsConfig()
.setLanguage(MLTtsConstants.TTS_EN_US)
.setPerson(MLTtsConstants.TTS_SPEAKER_FEMALE_EN)
.setSpeed(1.0f)
.setVolume(1.0f)
mlTtsEngine = MLTtsEngine(mlConfigs)
mlTtsEngine.setTtsCallback(callback)
// ID to use for Audio Visualizer.
val id = mlTtsEngine.speak(sourceText, MLTtsEngine.QUEUE_APPEND)
Log.i(TAG, id)
}
private fun setApiKey(){
MLApplication.getInstance().apiKey = "DAEDAOB+zyB7ajg1LGcp8F65qxZduDjQ1E6tVovUp4lU/PywqhT4g+bxBCtStYAa33V9tUQrKvUp89m+0Gi/fPwfNN6WCJxcVLA+WA=="
}
override fun onDestroy() {
super.onDestroy()
mlTtsEngine.shutdown()
}
override fun onPause() {
super.onPause()
mlTtsEngine.stop()
}
}
In the activity_list.xml we can create the UI screen.
Code:
<?xml version="1.0" encoding="utf-8"?>
<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:paddingTop="10dp"
android:paddingBottom="10dp"
tools:context=".ListActivity">
android:id="@+id/btn_voice"
android:layout_width="310dp"
android:layout_height="wrap_content"
android:layout_marginTop="50dp"
android:textAlignment="center"
android:layout_gravity="center_horizontal"
android:textSize="20sp"
android:textColor="@color/black"
android:padding="8dp"
android:textAllCaps="false"
android:text="Text to Voice" />
</LinearLayout>
In the activity_translate.xml we can create the UI screen.
Java:
<?xml version="1.0" encoding="utf-8"?>
<layout 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">
<data>
<variable
name="ttsViewModel"
type="com.example.huaweibookreaderapp1.TtsViewModel" />
</data>
<androidx.constraintlayout.widget.ConstraintLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"
tools:context=".TranslateActivity">
<Button
android:id="@+id/btn_click"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:onClick="@{() -> ttsViewModel.callTtsService()}"
android:text="@string/speak"
android:textSize="20sp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.43" />
<EditText
android:id="@+id/edt_text"
android:layout_width="409dp"
android:layout_height="wrap_content"
android:layout_marginBottom="36dp"
android:ems="10"
android:textSize="20sp"
android:hint="@string/enter_text_here"
android:inputType="textPersonName"
android:onTextChanged="@{ttsViewModel.noDataChangedText}"
android:paddingStart="70dp"
app:layout_constraintBottom_toTopOf="@+id/btn_click"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="1.0"
app:layout_constraintStart_toStartOf="parent"
android:autofillHints="@string/enter_text_here" />
<ImageView
android:id="@+id/img_view"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_marginTop="7dp"
app:layout_constraintBottom_toTopOf="@+id/edt_text"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.498"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.8"
app:srcCompat="@drawable/off"
android:contentDescription="@string/speaker" />
</androidx.constraintlayout.widget.ConstraintLayout>
</layout>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to integrate the Text to Speech feature of Huawei ML Kit in Book Reading app. Text to speech (TTS) can convert text information into human voice in real time. This service uses Deep Neural Networks in order to process the text and create a natural sound, rich timbers are also supported to enhance the result.
I hope you have read this article. If you found it is helpful, please provide likes and comments.
Reference
ML Kit – Text to Speech
ML Kit – Training Video

Expert: Directory App MVVM Jetpack (HMS Account and AuthService) in Android using Kotlin- Part-1

Overview
In this article, I will create a Directory android application using Kotlin in which I will integrate HMS Core kits such as HMS Account and AuthService Kit.
App will make use of android MVVM clean architecture using Jetpack components such as DataBinding, AndroidViewModel, Observer, LiveData and much more.
In this article we are going to implement DataBinding using Observable pattern.
Huawei ID Service Introduction
Huawei ID login provides you with simple, secure, and quick sign-in and authorization functions. Instead of entering accounts and passwords and waiting for authentication, users can just tap the Sign in with HUAWEI ID button to quickly and securely sign in to your app with their HUAWEI IDs.
Prerequisite
Huawei Phone EMUI 3.0 or later.
Non-Huawei phones Android 4.4 or later (API level 19 or higher).
HMS Core APK 4.0.0.300 or later
Android Studio
AppGallery Account
App Gallery Integration process
Sign In and Create or Choose a project on AppGallery Connect portal.
Navigate to Project settings and download the configuration file.
Navigate to General Information, and then provide Data Storage location.
App Development
Add Required Dependencies:
Launch Android studio and create a new project. Once the project is ready.
Add following dependency for HMS Kits
Navigate to the Gradle scripts folder and open build.gradle (project: app).
Code:
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
//noinspection GradleDependency
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.6.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.annotation:annotation:1.3.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
implementation 'androidx.lifecycle:lifecycle-extensions:2.2.0'
implementation 'androidx.navigation:navigation-fragment-ktx:2.4.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Code Implementation
Created following package model, event, viewmodel.
ViewModel: The ViewModel makes it easy to update data changes on the UI.Create a package named viewmodel in your main folder.Then create a new file and name it LoginViewModel.kt along with their FactoryViewModelProviders.
LoginViewModel.kt:
Code:
package com.hms.directoryapp
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.content.Intent
import android.util.Log
import androidx.databinding.Observable
import androidx.lifecycle.AndroidViewModel
import com.hms.directoryapp.event.ActivityNavigation
import com.hms.directoryapp.event.LiveMessageEvent
const val HMS_SIGN_IN: Int = 9001
@SuppressLint("StaticFieldLeak")
class LoginViewModel(application: Application) : AndroidViewModel(application), Observable {
private val context = getApplication<Application>().applicationContext
private var mAuthManager: AccountAuthService? = null
private var mAuthParam: AccountAuthParams? = null
val startActivityForResultEvent = LiveMessageEvent<ActivityNavigation>()
fun login() {
mAuthParam = AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setIdToken()
.setAccessToken()
.createParams()
mAuthManager = AccountAuthManager.getService(Activity(), mAuthParam)
startActivityForResultEvent.sendEvent {
startActivityForResult(
mAuthManager?.signInIntent,
HMS_SIGN_IN
)
}
}
fun onResultFromActivity(requestCode: Int, data: Intent?) {
when (requestCode) {
HMS_SIGN_IN -> {
val authAccountTask = AccountAuthManager.parseAuthResultFromIntent(data)
onCompleteLogin(authAccountTask)
}
}
}
private fun onCompleteLogin(doneTask: Task<AuthAccount>) {
if (doneTask.isSuccessful) {
val authAccount = doneTask.result
Log.d("LoginViewModel", "SigIn Success")
context.startActivity(Intent(context, OrderActivity::class.java))
} else {
Log.d("LoginViewModel", "SigIn Error")
}
}
override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
}
}
Xml layout DataBinding
To include data binding in the UI, enclose all content with <layout></layout>.
The ViewModel is introduced to the layout in the <data></data> section, as shown. Ensure that the type value points to the specific folder that has the required ViewModel.
activity_main.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android">
<RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="6dp"
android:text="Directory App "
android:textAlignment="center"
android:textColor="@color/white"
android:background="@color/purple_500"
android:textSize="34sp"
android:textStyle="bold" />
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:gravity="center">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="SigIn / SignUp "
android:textAlignment="center"
android:textColor="@color/black"
android:textSize="34sp"
android:textStyle="bold" />
<Button
android:id="@+id/btn_sign"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"
android:background="@color/cardview_dark_background"
android:text="Login With Huawei Id"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
</layout>
MainActivity.kt:
Code:
package com.hms.directoryapp
import android.content.Intent
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import androidx.databinding.DataBindingUtil
import androidx.lifecycle.ViewModelProviders
import com.hms.directoryapp.databinding.ActivityMainBinding
import com.hms.directoryapp.event.ActivityNavigation
class MainActivity : AppCompatActivity(), ActivityNavigation {
private lateinit var viewModel: LoginViewModel
private lateinit var dataBinding: ActivityMainBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
dataBinding = DataBindingUtil.setContentView(this, R.layout.activity_main)
val viewModel: LoginViewModel by lazy {
val activity = requireNotNull(this) {}
ViewModelProviders.of(this, LoginViewModelFactory(activity.application))
.get(LoginViewModel::class.java)
}
dataBinding.loginViewModel = viewModel
dataBinding.lifecycleOwner = this
viewModel.startActivityForResultEvent.setEventReceiver(this, this)
}
public override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
viewModel.onResultFromActivity(requestCode, data)
super.onActivityResult(requestCode, resultCode, data)
}
}
App Build Result
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Tips and Tricks
Identity Kit displays the HUAWEI ID registration or sign-in page first. The user can use the functions provided by Identity Kit only after signing in using a registered HUAWEI ID.
Conclusion
In this article, we have learned how to integrate Huawei ID in Android application. After completely read this article user can easily implement Huawei ID in the Directory App android application using Kotlin.
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.
References
HMS Docs:
https://developer.huawei.com/consum.../HMSCore-Guides/introduction-0000001050048870

Find the RecyclerView Item Click Listeners to Navigate to Different activities in Quiz Android app (Kotlin) – Part 4

{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we can learn how to click the items of Recyclerview to navigate to different activities in Quiz App. Here, I have given the items in grid view to click each item. So, I will provide a series of articles on this Quiz App, in upcoming articles.
If you are new to this application, follow my previous articles.
https://forums.developer.huawei.com/forumPortal/en/topic/0202877278014350004
https://forums.developer.huawei.com/forumPortal/en/topic/0201884103719030016?fid=0101187876626530001
https://forums.developer.huawei.com/forumPortal/en/topic/0202890333711770040
Requirements
1. Any operating system (MacOS, Linux, and Windows).
2. Must have a Huawei phone with HMS 4.0.0.300 or later.
3. Must have a laptop or desktop with Android Studio, Jdk 1.8, SDK platform 26 and Gradle 4.6 and above installed.
4. Minimum API Level 24 is required.
5. Required EMUI 9.0.0 and later version devices.
How to integrate HMS Dependencies
1. First register as Huawei developer and complete identity verification on the Huawei developers website, refer to register a Huawei ID.
2. Create a project in android studio, refer Creating an Android Studio Project.
3. Generate a SHA-256 certificate fingerprint.
4. To generate SHA-256 certificate fingerprint. On right-upper corner of android project click Gradle, choose Project Name > Tasks > android, and then click signingReport, as follows.
Note: Project Name depends on the user created name.
5. Create an App in AppGallery Connect.
6. Download the agconnect-services.json file from App information, copy and paste in android Project under app directory, as follows.
7. Enter SHA-256 certificate fingerprint and click Save button, as follows.
Note: Above steps from Step 1 to 7 is common for all Huawei Kits.
8. Add the below maven URL in build.gradle(Project) file under the repositories of buildscript, dependencies and allprojects, refer Add Configuration.
Java:
maven { url 'http://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.6.0.300'
9. Add the below plugin and dependencies in build.gradle(Module) file.
Java:
apply plugin: id 'com.huawei.agconnect'
// Huawei AGC
implementation 'com.huawei.agconnect:agconnect-core:1.6.0.300'
// Recyclerview
implementation 'androidx.recyclerview:recyclerview:1.2.1'
// Lifecycle components
implementation "androidx.lifecycle:lifecycle-extensions:2.2.0"
10. Now Sync the gradle.
Let us move to development
I have created a project on Android studio with empty activity let us start coding.
In the Home.kt we can find the business logic for button click listeners.
Java:
class Home : AppCompatActivity(), HomeAdapter.ItemListener {
private lateinit var recyclerView: RecyclerView
private lateinit var arrayList: ArrayList<QuesIcons>
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home)
recyclerView = findViewById(R.id.recyclerview_list)
arrayList = ArrayList()
arrayList.add(QuesIcons("Android", R.drawable.android_icon, "#09A9FF"))
arrayList.add(QuesIcons("HMS", R.drawable.huawei_icon, "#3E51B1"))
arrayList.add(QuesIcons("Sports", R.drawable.sports_icon, "#673BB7"))
arrayList.add(QuesIcons("Country Flags", R.drawable.flags_icon, "#4BAA50"))
val adapter = HomeAdapter(applicationContext, arrayList, this)
recyclerView.adapter = adapter
recyclerView.layoutManager = GridLayoutManager(this, 2)
recyclerView.setHasFixedSize(true)
}
override fun onItemClick(item: Int) {
when(item ) {
0 -> {val intent = Intent([email protected], AndroidActivity::class.java)
startActivity(intent)
}
1 -> {val intent = Intent([email protected], HMSActivity::class.java)
startActivity(intent)
}
2 -> {val intent = Intent([email protected], SportsActivity::class.java)
startActivity(intent)
}
3 -> {val intent = Intent([email protected], QuizActivity::class.java)
startActivity(intent)
}
}
}
}
In the HomeAdapter.kt we can find the business logic to holder the adapter items.
Java:
class HomeAdapter(private val mContext: Context, private val mValues: ArrayList<QuesIcons>, private var mListener: ItemListener?) :
RecyclerView.Adapter<HomeAdapter.ViewHolder>() {
inner class ViewHolder(v: View) : RecyclerView.ViewHolder(v), View.OnClickListener {
private val textView: TextView
private val imageView: ImageView
private val relativeLayout: RelativeLayout
private var item: QuesIcons? = null
fun setData(item: QuesIcons) {
this.item = item
textView.text = item.heading
imageView.setImageResource(item.titleImage)
relativeLayout.setBackgroundColor(Color.parseColor(item.colour))
}
override fun onClick(view: View) {
if (mListener != null) {
item?.let { mListener!!.onItemClick(adapterPosition) }
}
}
init {
v.setOnClickListener(this)
textView = v.findViewById<View>(R.id.text_item) as TextView
imageView = v.findViewById<View>(R.id.img_icon) as ImageView
relativeLayout = v.findViewById<View>(R.id.relativeLayout) as RelativeLayout
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
val view: View = LayoutInflater.from(mContext).inflate(R.layout.home_list, parent, false)
return ViewHolder(view)
}
override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
viewHolder.setData(mValues[position])
}
override fun getItemCount(): Int {
return mValues.size
}
interface ItemListener {
fun onItemClick(position: Int)
}
}
Create QuesIcons.kt data class to find the declared the data.
Java:
data class QuesIcons(var heading: String, var titleImage: Int, var colour: String)
In the activity_home.xml we can create the recycler view list.
Java:
<?xml version="1.0" encoding="utf-8"?>
<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:paddingLeft="8dp"
android:paddingRight="8dp"
tools:context=".Home">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recyclerview_list"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</LinearLayout>
In the home_list.xml we can create customize view for items.
Java:
<?xml version="1.0" encoding="utf-8"?>
<androidx.cardview.widget.CardView xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:card_view="http://schemas.android.com/apk/res-auto"
android:id="@+id/cardView"
android:layout_width="match_parent"
android:layout_height="170dp"
android:layout_margin="4dp"
card_view:cardCornerRadius="4dp">
<RelativeLayout
android:id="@+id/relativeLayout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:layout_marginTop="10dp"
android:layout_gravity="center">
<ImageView
android:id="@+id/img_icon"
android:layout_width="90dp"
android:layout_height="90dp"
android:layout_centerInParent="true"
android:contentDescription="@null"
card_view:tint="@color/white" />
<TextView
android:id="@+id/text_item"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:textColor="@android:color/white"
android:textSize="16sp"
android:layout_below="@+id/img_icon" />
</RelativeLayout>
</androidx.cardview.widget.CardView>
Demo
Tips and Tricks
1. Make sure you are already registered as Huawei developer.
2. Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
3. Make sure you have added the agconnect-services.json file to app folder.
4. Make sure you have added SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to click the items of Recyclerview to navigate to different activities in Quiz App. Here, we can find the items in grid view to click each item. So, I will provide a series of articles on this Quiz App, in upcoming articles. So, I will provide a series of articles on this Quiz App, in upcoming articles.
I hope you have read this article. If you found it helpful, please provide likes and comments.
Reference
Clik here - https://www.geeksforgeeks.org/android-recyclerview/

Categories

Resources