[Huawei Developers] Freemind R:
More information like this, you can visit HUAWEI Developer Forum

​

Introduction

This article shows the setp to integrate HMS Flutter Location plugin with a news app.

The news app will obtain the country that the user is located in. It will then fetch that country's news headlines and display them onto a list.

For example, if the user is currently located in Hong Kong, the app will show Hong Kong's news headlines on launch. The user may switch to read other countries' news headlines afterwards.

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/680/186/2640852000006680186.20200616034859.33547066190436236294715883928838:50510731013059:2800:5634BCCD866975E74505E2D0C7EFA0DF46CF282A69540449EDDFAFC2AB07530A.gif"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/680/186/2640852000006680186.20200616034859.33547066190436236294715883928838:50510731013059:2800:5634BCCD866975E74505E2D0C7EFA0DF46CF282A69540449EDDFAFC2AB07530A.gif[/IMG]​

The datasource of the news headlines are obtained from the NewsAPI.

Configuration

Assuming that there is already a running Flutter app,

*Update: for 1) and 2), the plugin is now uploaded to pub.dev, there is no need to download and configure it manually.

Add this to your pubspec.yaml is the preferred way.

dependencies:
huawei_location: ^4.0.4+300

1) Download the huawei_location flutter plugin and unzip it. For this project, it is placed under the project's root.

2) Configure pubspec.yaml to add the following under dependencies. Replace the path to your own's.

huawei_location:
path: 'hms/location/huawei_location'

3) Configure AndroidManifest.xml for location permission.

<uses-permission android:name="android.permission.ACCESS_COARES_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

Project Structure

The architecture of the flutter project is shown below, which is adapted from this repo.

https://github.com/FilledStacks/flutter-tutorials/tree/master/010-provider-architecture

[IMG="https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/680/186/2640852000006680186.20200616013323.09871215568513765718777419265287:50510731013059:2800:15B521DE68D89AA0D866D42B5D9809DC7F05E4E97934EA12D283E94511593CC5.png"]https://communityfile-dre.op.hicloud.com/FileServer/getFile/cmtybbs/006/680/186/2640852000006680186.20200616013323.09871215568513765718777419265287:50510731013059:2800:15B521DE68D89AA0D866D42B5D9809DC7F05E4E97934EA12D283E94511593CC5.png[/IMG]

The project is layered into three parts, namely UI, Services and Business Logic.

The UI is dumb and display only what it is given. It will not contain any logic to process the data.

The Service provides various services and exposes APIs for others to use.

The business logic contains view models and models etc.

Since the UI is pretty simple and does not contain any logic to process data, we will mainly focus on Services and Business Logic.

Services

1) Permission Service

Accessing user's location generally requires permission at runtime.

The permission services expose two methods to achieve this. For convenience, the built-in PermissionHandler from Huawei-location plugin is used.

class PermissionServicesImpl implements PermissionServices {
PermissionHandler _permissionHandler = PermissionHandler();

@override
Future<bool> hasLocationPermission() async {
return _permissionHandler.hasLocationPermission();
}

@override
Future<bool> requestLocationPermission() async {
return _permissionHandler
.requestLocationPermission();
}
}

For this app, the permission to obtain user's location information is acquired during app launch. If the user has allowed, the country code obtained is saved with SharedPreferences.

Future<void> _initApp() async {
final isPermitted = await _permissionServices.requestLocationPermission();
if(isPermitted == null) {
await _sharedPreferencesServices.saveCountryCode(CommonString.defaultCountry);}
if(isPermitted) {
final hwLocation = await _locationService.getHWLocation();
if(hwLocation != null) {
await _sharedPreferencesServices.saveCountryCode(hwLocation.countryCode);
}
} else {
await _sharedPreferencesServices.saveCountryCode(CommonString.defaultCountry);
}
}

2) Location Service

The location service provides only one method to return HWLocation using huawei_location plugin.

It utilizes location plugin's FusedLocationProviderClient.getLastLocationWithAddress(LocationRequest) to acquire HWLocation.

Remember to set LocationRequest.needAddress to true if you need to obtain the address information also.

class LocationServicesImpl implements LocationService {
final PermissionServices _permissionServices =
serviceLocator<PermissionServices>();

@override
Future<HWLocation> getHWLocation() async {
if (await _permissionServices.hasLocationPermission()) {
FusedLocationProviderClient locationService =
FusedLocationProviderClient();
LocationRequest locationRequest = LocationRequest();
locationRequest.needAddress = true;
final hwLocation = locationService
.getLastLocationWithAddress(locationRequest);
return hwLocation;
}
}
}

3) SharedPreferences Service

The shared preferences service allows the ability to store and retreive country code. For simplicity, only the abstract class is shown.

abstract class SharedPreferencesServices {
Future<void> saveCountryCode(String countryCode);
Future<String> getCountryCode();
}

4) TopHeadlines Service

TopHeadlines service allows the ability to fetch a specific countries' news headlines and also to change to another countries' news headlines. For simplicity, only the abstract class is shown.

abstract class TopHeadlinesService {

Future<List<Article>> getTopHeadlines(String countryCode);
Future<List<Article>> changeHeadlinesLanguage(String countryCode);
}

Business Logic

1) HeadlinesScreenViewModel:

This viewmodel is responsible for managing the state of the headlines screen, processing data and gluing all parts together.

In case of a change in state, the viewmodel will notify its listneres (the UI), so that they could act on the event.

To complete the picture, in the loadData method, the country code is first retreived from SharedPreferences, the country code is then used to call getTopHeadlines(String countryCode) to fetch the headline news of that particular country.

The app will call loadData at the initState lifecycle method of the headlines screen.

void loadData() async {
_setIsLoading(true);
final _countryCode = await _sharedPreferencesServices
.getCountryCode()
.timeout(Duration(milliseconds: 2000), onTimeout: () => CommonString.defaultCountry);
_headlines = await _topHeadlinesService
.getTopHeadlines(_countryCode)
.timeout(Duration(milliseconds: 2000), onTimeout: () => null);
_setIsLoading(false);
}

The above explains the necessary parts of using HMS Location kit for Flutter.

If you are interested in the details, feel free to visit the github repo.

https://github.com/lkhe/news_app