DEV Community

linzhongxue
linzhongxue

Posted on

Practical Development of Life Service Applications Based on HarmonyOS Next: AppGallery Connect Integration Guide

Practical Development of Life Service Applications Based on HarmonyOS Next: AppGallery Connect Integration Guide

1. Introduction: Advantages of Developing Life Service Applications on HarmonyOS

With the widespread adoption of smart terminal devices, life service applications have become an indispensable part of users' daily lives. Developing life service applications based on HarmonyOS Next allows developers to fully leverage distributed capabilities, atomic services, and card features to provide users with a seamless, all-scenario experience.

AppGallery Connect, as Huawei's official one-stop application service platform, offers developers comprehensive support throughout the entire process—from development and testing to release. This article focuses on how to use AppGallery Connect services to develop a complete life service application.

2. Project Preparation and Environment Setup

First, we need to create a new HarmonyOS application project:

  1. Open DevEco Studio, select File > New > New Project.
  2. Choose the Application template, then select Empty Ability.
  3. Configure project information:
    • Project Name: LifeServiceDemo
    • Bundle Name: com.example.lifeservice
    • Save Location: Select a local storage path
    • Compile SDK: The latest version of HarmonyOS Next
    • Language: ArkTS

After creating the project, we need to configure application information in the AppGallery Connect console:

  1. Log in to the AppGallery Connect console.
  2. Select My Projects, then click Add Project.
  3. Fill in the project name and time zone, then create the project.
  4. Under the project, select Add App and enter the application details.

3. Integrating AppGallery Connect Core Services

3.1 Configuring Project Dependencies

Add AppGallery Connect dependencies in the project's entry/build.gradle file:

// entry/build.gradle  
dependencies {  
    // AppGallery Connect core services  
    implementation 'com.huawei.agconnect:agconnect-core-harmony:1.6.0.300'  
    // Authentication service  
    implementation 'com.huawei.agconnect:agconnect-auth-harmony:1.6.0.300'  
    // Cloud database  
    implementation 'com.huawei.agconnect:agconnect-clouddb-harmony:1.6.0.300'  
}  
Enter fullscreen mode Exit fullscreen mode

3.2 Initializing the AGC SDK

Initialize the AGC service in the application entry:

// entry/src/main/ets/entryability/EntryAbility.ts  
import Ability from '@ohos.app.ability.UIAbility';  
import agconnect from '@hw-agconnect/core-harmony';  

export default class EntryAbility extends Ability {  
    onCreate(want, launchParam) {  
        console.info('EntryAbility onCreate');  
        // Initialize the AGC SDK  
        try {  
            agconnect.instance().init(this.context);  
            console.info('AGC SDK initialized successfully');  
        } catch (error) {  
            console.error('AGC SDK initialization failed: ' + error);  
        }  
    }  
}  
Enter fullscreen mode Exit fullscreen mode

4. Implementing Core Life Service Features

4.1 User Authentication Module

Life service applications typically require a login feature. We can use AppGallery Connect's authentication service:

// entry/src/main/ets/pages/LoginPage.ets  
import { agconnect } from '@hw-agconnect/core-harmony';  
import { auth } from '@hw-agconnect/auth-harmony';  

@Entry  
@Component  
struct LoginPage {  
    @State phoneNumber: string = '';  
    @State verifyCode: string = '';  
    @State isLoggedIn: boolean = false;  

    // Send verification code  
    sendVerifyCode() {  
        let request = {  
            countryCode: "86",  
            phoneNumber: this.phoneNumber,  
            verifyCodeType: 0 // 0: Registration/login verification code  
        };  

        auth().requestVerifyCode(request)  
            .then(() => {  
                console.info('Verify code sent successfully');  
                prompt.showToast({ message: 'Verification code sent' });  
            })  
            .catch(err => {  
                console.error('Failed to send verify code: ' + err);  
                prompt.showToast({ message: 'Failed to send verification code' });  
            });  
    }  

    // Login with phone number and verification code  
    loginWithPhone() {  
        let credential = auth.PhoneAuthProvider.credentialWithVerifyCode(  
            "86",   
            this.phoneNumber,   
            this.verifyCode  
        );  

        auth().signIn(credential)  
            .then(user => {  
                console.info('Login success: ' + JSON.stringify(user));  
                this.isLoggedIn = true;  
                prompt.showToast({ message: 'Login successful' });  
            })  
            .catch(err => {  
                console.error('Login failed: ' + err);  
                prompt.showToast({ message: 'Login failed' });  
            });  
    }  

    build() {  
        Column() {  
            if (!this.isLoggedIn) {  
                TextInput({ placeholder: 'Enter phone number' })  
                    .width('90%')  
                    .height(50)  
                    .onChange(value => this.phoneNumber = value)  

                TextInput({ placeholder: 'Enter verification code' })  
                    .width('90%')  
                    .height(50)  
                    .onChange(value => this.verifyCode = value)  

                Row() {  
                    Button('Get Verification Code')  
                        .onClick(() => this.sendVerifyCode())  

                    Button('Login')  
                        .onClick(() => this.loginWithPhone())  
                }  
            } else {  
                Text('Welcome back!')  
                    .fontSize(20)  
            }  
        }.width('100%').height('100%').justifyContent(FlexAlign.Center)  
    }  
}  
Enter fullscreen mode Exit fullscreen mode

4.2 Service Information Display Module

Life service applications often need to display various service information. We can use the cloud database to store this data:

// entry/src/main/ets/pages/ServiceListPage.ets  
import { clouddb } from '@hw-agconnect/clouddb-harmony';  

// Define service data model  
@Class  
class ServiceInfo {  
    @Field()  
    id: string = '';  

    @Field()  
    name: string = '';  

    @Field()  
    description: string = '';  

    @Field()  
    price: number = 0;  

    @Field()  
    rating: number = 0;  
}  

@Entry  
@Component  
struct ServiceListPage {  
    @State serviceList: ServiceInfo[] = [];  

    aboutToAppear() {  
        this.queryServices();  
    }  

    // Query service list  
    queryServices() {  
        const cloudDBZone = clouddb.cloudDBZone('LifeServiceDB');  
        const query = clouddb.CloudDBZoneQuery.where(ServiceInfo).orderByDesc('rating');  

        cloudDBZone.executeQuery(query, ServiceInfo)  
            .then(result => {  
                this.serviceList = result;  
                console.info('Query services success: ' + result.length);  
            })  
            .catch(err => {  
                console.error('Query services failed: ' + err);  
            });  
    }  

    build() {  
        List({ space: 10 }) {  
            ForEach(this.serviceList, (item: ServiceInfo) => {  
                ListItem() {  
                    Column() {  
                        Text(item.name)  
                            .fontSize(18)  
                            .fontWeight(FontWeight.Bold)  

                        Text(item.description)  
                            .fontSize(14)  
                            .margin({ top: 5 })  

                        Row() {  
                            Text('¥' + item.price)  
                                .fontColor(Color.Red)  

                            Text('Rating: ' + item.rating.toFixed(1))  
                                .margin({ left: 20 })  
                        }.margin({ top: 5 })  
                    }.padding(10)  
                }  
            })  
        }.width('100%').height('100%')  
    }  
}  
Enter fullscreen mode Exit fullscreen mode

5. Implementing Advanced Features

5.1 Service Booking Function

// entry/src/main/ets/pages/ReservationPage.ets  
import { clouddb } from '@hw-agconnect/clouddb-harmony';  

@Class  
class Reservation {  
    @Field()  
    id: string = '';  

    @Field()  
    serviceId: string = '';  

    @Field()  
    userId: string = '';  

    @Field()  
    reserveTime: string = '';  

    @Field()  
    status: number = 0; // 0: Pending 1: Confirmed 2: Completed 3: Canceled  
}  

@Entry  
@Component  
struct ReservationPage {  
    @State serviceInfo: ServiceInfo = new ServiceInfo();  
    @State reserveDate: string = '2023-12-31';  
    @State reserveTime: string = '14:00';  

    // Submit reservation  
    submitReservation() {  
        const reservation = new Reservation();  
        reservation.serviceId = this.serviceInfo.id;  
        reservation.reserveTime = `${this.reserveDate} ${this.reserveTime}`;  

        const cloudDBZone = clouddb.cloudDBZone('LifeServiceDB');  
        cloudDBZone.executeUpsert(reservation)  
            .then(() => {  
                console.info('Reservation submitted successfully');  
                prompt.showToast({ message: 'Reservation submitted successfully' });  
            })  
            .catch(err => {  
                console.error('Reservation failed: ' + err);  
                prompt.showToast({ message: 'Reservation failed' });  
            });  
    }  

    build() {  
        Column() {  
            Text(this.serviceInfo.name)  
                .fontSize(20)  
                .fontWeight(FontWeight.Bold)  

            Text('Reservation Time')  
                .margin({ top: 20 })  

            DatePicker({  
                start: '2023-01-01',  
                end: '2023-12-31',  
                selected: this.reserveDate  
            }).onChange(value => this.reserveDate = value)  

            TimePicker({  
                selected: this.reserveTime  
            }).onChange(value => this.reserveTime = value)  

            Button('Submit Reservation')  
                .margin({ top: 20 })  
                .onClick(() => this.submitReservation())  
        }.padding(20)  
    }  
}  
Enter fullscreen mode Exit fullscreen mode

5.2 Service Review Function

// entry/src/main/ets/pages/ReviewPage.ets  
import { clouddb } from '@hw-agconnect/clouddb-harmony';  

@Class  
class Review {  
    @Field()  
    id: string = '';  

    @Field()  
    serviceId: string = '';  

    @Field()  
    userId: string = '';  

    @Field()  
    rating: number = 5;  

    @Field()  
    comment: string = '';  

    @Field()  
    createTime: string = '';  
}  

@Entry  
@Component  
struct ReviewPage {  
    @State serviceInfo: ServiceInfo = new ServiceInfo();  
    @State rating: number = 5;  
    @State comment: string = '';  

    // Submit review  
    submitReview() {  
        const review = new Review();  
        review.serviceId = this.serviceInfo.id;  
        review.rating = this.rating;  
        review.comment = this.comment;  
        review.createTime = new Date().toISOString();  

        const cloudDBZone = clouddb.cloudDBZone('LifeServiceDB');  
        cloudDBZone.executeUpsert(review)  
            .then(() => {  
                console.info('Review submitted successfully');  
                prompt.showToast({ message: 'Review submitted successfully' });  
            })  
            .catch(err => {  
                console.error('Review failed: ' + err);  
                prompt.showToast({ message: 'Review failed' });  
            });  
    }  

    build() {  
        Column() {  
            Text(this.serviceInfo.name)  
                .fontSize(20)  
                .fontWeight(FontWeight.Bold)  

            Text('Rate the service')  
                .margin({ top: 20 })  

            Slider({  
                value: this.rating,  
                min: 1,  
                max: 5,  
                step: 1,  
                style: SliderStyle.OutSet  
            }).onChange(value => this.rating = value)  

            Text('Rating: ' + this.rating)  

            TextInput({ placeholder: 'Enter your review' })  
                .width('90%')  
                .height(100)  
                .margin({ top: 20 })  
                .onChange(value => this.comment = value)  

            Button('Submit Review')  
                .margin({ top: 20 })  
                .onClick(() => this.submitReview())  
        }.padding(20)  
    }  
}  
Enter fullscreen mode Exit fullscreen mode

6. Application Release and Operations

After completing development, we can release the application through AppGallery Connect:

  1. In DevEco Studio, select Build > Generate Key and CSR to generate a signing certificate.
  2. After configuring the signing information, select Build > Build Hap(s)/App(s) > Build Release Hap(s).
  3. In the AppGallery Connect console, select My Apps, then click Release App.
  4. Upload the generated HAP file, fill in the app details, and submit for review.

AppGallery Connect also provides rich operational analysis features:

  • App Analytics: View user engagement, retention rates, and other metrics.
  • User Acquisition: Track user acquisition channels.
  • Monetization Analysis: Analyze app revenue.
  • Performance Management: Monitor app performance metrics.

7. Conclusion

This article detailed how to develop a complete life service application based on HarmonyOS Next and AppGallery Connect. By integrating core services such as authentication and cloud databases, we can quickly build feature-rich applications. HarmonyOS's distributed capabilities also enable seamless cross-device collaboration, providing users with a smooth, all-scenario experience.

As the HarmonyOS ecosystem continues to evolve, life service applications will have even more innovative possibilities. Developers can further explore features such as atomic services and cards to create smarter and more convenient service experiences.

Top comments (0)