Practical Development of Real Estate and Renovation Applications Based on HarmonyOS Next

Practical Development of Real Estate and Renovation Applications Based on HarmonyOS Next: Building a Smart Home Service Platform from Scratch

1. Project Overview and Development Environment Setup

In today’s era of rapid smart home development, real estate and renovation applications are becoming increasingly important. This tutorial will guide you through developing a fully functional smart home service platform using HarmonyOS Next and AppGallery Connect, featuring core functionalities such as property listings, renovation design solutions, and smart device control.

Development Environment Preparation

  1. Install DevEco Studio 4.0+: Download the latest IDE from the official website
  2. Register a Huawei Developer Account: Complete real-name verification
  3. Create AppGallery Connect Project: Enable authentication services, cloud database, cloud functions, etc.
  4. Configure Project Files: Add necessary permissions to config.json
// Basic configuration example in config.json
{
  "app": {
    "bundleName": "com.example.smarthome",
    "vendor": "example",
    "version": {
      "code": 1,
      "name": "1.0"
    }
  },
  "deviceConfig": {
    "default": {
      "agconnect": {
        "api_key": "your_api_key",
        "app_id": "your_app_id"
      },
      "iot": {
        "deviceType": "smart_home_gateway"
      }
    }
  },
  "module": {
    "reqPermissions": [
      {
        "name": "ohos.permission.INTERNET"
      },
      {
        "name": "ohos.permission.LOCATION"
      }
    ]
  }
}

2. Property Listing Module Development

2.1 Cloud Property Data Model Design

// Define property data model
@Class
class HouseInfo {
  @Field()
  id: string = ''; // Property unique identifier

  @Field()
  title: string = ''; // Property title

  @Field()
  price: number = 0; // Price (yuan/month)

  @Field()
  area: number = 0; // Area (square meters)

  @Field()
  roomType: string = ''; // Layout type

  @Field()
  location: string = ''; // Geographic location

  @Field()
  images: string[] = []; // Image URL array

  @Field()
  vrUrl: string = ''; // VR viewing link

  @Field()
  isSmartHome: boolean = false; // Whether it's smart home

  constructor(partial?: Partial<HouseInfo>) {
    if (partial) {
      Object.assign(this, partial);
    }
  }
}

2.2 Implementing 3D Property Display

// 3D property display component
@Component
struct House3DView {
  @Prop houseInfo: HouseInfo

  build() {
    Column() {
      // VR viewing container
      Web({ src: this.houseInfo.vrUrl })
        .width('100%')
        .height(300)

      // Basic property information
      Row() {
        Column() {
          Text(this.houseInfo.title)
            .fontSize(20)
            .fontWeight(FontWeight.Bold)

          Text(`${this.houseInfo.price} yuan/month`)
            .fontSize(18)
            .fontColor('#FF4500')
        }
        .layoutWeight(1)

        Column() {
          Text(this.houseInfo.roomType)
          Text(`${this.houseInfo.area}㎡`)
        }
        .alignItems(HorizontalAlign.End)
      }
      .padding(10)

      // Smart home indicator
      if (this.houseInfo.isSmartHome) {
        Row() {
          Image($r('app.media.smart_home_icon'))
            .width(20)
            .height(20)
          Text('Smart Home')
            .fontColor('#1E90FF')
        }
        .margin({ top: 5 })
      }
    }
    .borderRadius(10)
    .backgroundColor(Color.White)
    .shadow({ radius: 5, color: '#999' })
  }
}

3. Renovation Design Module Implementation

3.1 AR Renovation Preview Functionality

// AR renovation preview component
@Component
struct ARDecorationView {
  @State selectedFurniture: string = ''
  @State furnitureList: string[] = [
    'sofa', 'tv_stand', 'dining_table', 'bed'
  ]

  build() {
    Column() {
      // AR view container
      Stack() {
        // In actual projects, AR SDK should be used
        Image($r('app.media.ar_background'))
          .width('100%')
          .height(300)

        if (this.selectedFurniture) {
          Image($r(`app.media.${this.selectedFurniture}`))
            .width(100)
            .height(100)
            .position({ x: 150, y: 150 })
        }
      }
      .borderRadius(8)
      .border({ width: 1, color: '#EEE' })

      // Furniture selection list
      Scroll() {
        Row() {
          ForEach(this.furnitureList, (item: string) => {
            Image($r(`app.media.${item}`))
              .width(60)
              .height(60)
              .margin(5)
              .onClick(() => {
                this.selectedFurniture = item
              })
          })
        }
        .padding(10)
      }
      .height(80)
      .margin({ top: 10 })

      // Save design button
      Button('Save Design')
        .width('80%')
        .margin({ top: 20 })
        .onClick(() => this.saveDesign())
    }
  }

  private saveDesign() {
    // Implementation for saving to cloud database
    console.log('Design saved:', this.selectedFurniture)
  }
}

3.2 Cloud Storage for Design Solutions

// Design solution data operation class
class DesignService {
  private cloudDB: any

  constructor() {
    this.cloudDB = agconnect.cloudDB()
  }

  // Save design solution
  async saveDesign(designData: object): Promise<boolean> {
    try {
      await this.cloudDB.upsert('DesignCollection', designData)
      return true
    } catch (error) {
      console.error('Failed to save design:', error)
      return false
    }
  }

  // Get user's historical designs
  async getUserDesigns(userId: string): Promise<object[]> {
    const query = this.cloudDB.createQuery()
      .equalTo('userId', userId)
      .orderByDesc('createTime')

    const result = await this.cloudDB.executeQuery(query)
    return result.getSnapshotObjects()
  }
}

4. Smart Home Control Module

4.1 Device Connection and Management

// Smart home device management class
class SmartHomeManager {
  private deviceList: any[] = []

  // Discover nearby devices
  async discoverDevices() {
    try {
      const result = await window.hilink.discover({
        deviceType: 'smart_home'
      })
      this.deviceList = result.devices
      return true
    } catch (error) {
      console.error('Device discovery failed:', error)
      return false
    }
  }

  // Connect device
  async connectDevice(deviceId: string) {
    return window.hilink.connect({
      deviceId: deviceId,
      timeout: 5000
    })
  }

  // Control device
  async controlDevice(deviceId: string, command: object) {
    return window.hilink.invoke({
      deviceId: deviceId,
      serviceId: 'control',
      method: 'SET',
      params: command
    })
  }
}

4.2 Implementing Device Control Panel

// Smart lighting control component
@Component
struct LightControlPanel {
  @State isConnected: boolean = false
  @State brightness: number = 50
  @State colorTemp: number = 4000
  private deviceId: string = 'light_001'

  build() {
    Column() {
      if (!this.isConnected) {
        Button('Connect Smart Light')
          .onClick(() => this.connectDevice())
      } else {
        Text('Light Brightness')
          .fontSize(16)
          .margin({ top: 10 })

        Slider({
          value: this.brightness,
          min: 0,
          max: 100,
          step: 1
        })
        .onChange((value: number) => {
          this.brightness = value
          this.updateDevice()
        })

        Text('Color Temperature')
          .fontSize(16)
          .margin({ top: 20 })

        Row() {
          Text('Warm')
          Slider({
            value: this.colorTemp,
            min: 2700,
            max: 6500,
            step: 100
          })
          .layoutWeight(1)
          .margin({ left: 10, right: 10 })
          .onChange((value: number) => {
            this.colorTemp = value
            this.updateDevice()
          })
          Text('Cool')
        }
        .width('100%')

        Button('Turn Off Light')
          .margin({ top: 20 })
          .onClick(() => {
            this.brightness = 0
            this.updateDevice()
          })
      }
    }
    .padding(15)
  }

  private async connectDevice() {
    const success = await new SmartHomeManager().connectDevice(this.deviceId)
    this.isConnected = success
  }

  private async updateDevice() {
    await new SmartHomeManager().controlDevice(this.deviceId, {
      brightness: this.brightness,
      colorTemp: this.colorTemp
    })
  }
}

5. User System and Data Synchronization

5.1 User Authentication and Personal Center

// User authentication service encapsulation
class AuthService {
  // Phone number login
  static async phoneLogin(phone: string, code: string): Promise<boolean> {
    try {
      const credential = agconnect.auth.PhoneAuthProvider.credentialWithVerifyCode(
        '86', phone, code
      )
      await agconnect.auth().signIn(credential)
      return true
    } catch (error) {
      console.error('Login failed:', error)
      return false
    }
  }

  // Get current user
  static getCurrentUser() {
    return agconnect.auth().currentUser
  }

  // Logout
  static async logout() {
    await agconnect.auth().signOut()
  }
}

5.2 User Preference Data Synchronization

// User preference settings component
@Component
struct UserPreferenceSettings {
  @State favoriteStyle: string = 'modern'
  @State notificationEnabled: boolean = true

  build() {
    Column() {
      Text('Renovation Style Preference')
        .fontSize(18)
        .margin({ bottom: 10 })

      Radio({ group: 'style' }) {
        RadioOption('Modern').value('modern')
        RadioOption('Nordic').value('nordic')
        RadioOption('Chinese').value('chinese')
      }
      .onChange((value: string) => {
        this.favoriteStyle = value
        this.savePreferences()
      })

      Row() {
        Text('Receive Notifications')
          .fontSize(18)
        Toggle({ type: ToggleType.Switch })
          .margin({ left: 10 })
          .onChange((isOn: boolean) => {
            this.notificationEnabled = isOn
            this.savePreferences()
          })
      }
      .margin({ top: 20 })
    }
    .onAppear(() => this.loadPreferences())
  }

  private async loadPreferences() {
    const user = AuthService.getCurrentUser()
    if (!user) return

    const db = agconnect.cloudDB()
    const query = db.createQuery('UserPreferences')
      .equalTo('userId', user.uid)

    const result = await db.executeQuery(query)
    if (result.snapshotObjects.length > 0) {
      const prefs = result.snapshotObjects[0]
      this.favoriteStyle = prefs.favoriteStyle || 'modern'
      this.notificationEnabled = prefs.notificationEnabled !== false
    }
  }

  private async savePreferences() {
    const user = AuthService.getCurrentUser()
    if (!user) return

    const prefs = {
      userId: user.uid,
      favoriteStyle: this.favoriteStyle,
      notificationEnabled: this.notificationEnabled,
      updateTime: new Date().getTime()
    }

    await agconnect.cloudDB().upsert('UserPreferences', prefs)
  }
}

6. Project Optimization and Release

6.1 Performance Optimization Recommendations

  1. Lazy Loading for Images: Implement on-demand loading for property image lists
  2. Data Caching: Use local database to cache frequently used data
  3. Component Reuse: Extract common UI components to reduce duplicate code
  4. On-Demand Loading: Implement dynamic imports for complex functional modules
// Lazy loading image component example
@Component
struct LazyImage {
  @Prop src: string
  @State loaded: boolean = false

  build() {
    Stack() {
      if (!this.loaded) {
        Progress()
          .width(50)
          .height(50)
      }

      Image(this.src)
        .onComplete(() => {
          this.loaded = true
        })
        .visibility(this.loaded ? Visibility.Visible : Visibility.None)
    }
    .width('100%')
    .height(200)
  }
}

6.2 Application Release Process

  1. Generate Signing Certificate: Create release certificate in DevEco Studio
  2. Build Release Package: Build HAP package in Release mode
  3. Submit for Review: Submit application in AppGallery Connect
  4. Configure Distribution: Set target countries and regions
  5. Publish Application: Official release after approval
// Pre-publish checklist
async function prePublishCheck() {
  // Check required permissions
  const permissions = [
    'ohos.permission.INTERNET',
    'ohos.permission.LOCATION'
  ]

  for (const perm of permissions) {
    const granted = await abilityAccessCtrl.verifyAccessToken(perm)
    if (!granted) {
      console.error(`Missing required permission: ${perm}`)
      return false
    }
  }

  // Check AGC service initialization
  try {
    await agconnect.instance().init()
    return true
  } catch (error) {
    console.error('AGC initialization failed:', error)
    return false
  }
}

7. Summary and Expansion Directions

Through this tutorial, you have mastered the core skills for developing real estate and renovation applications. A complete project should include the following modules:

  1. Property Display System: 3D/VR viewing, map positioning
  2. Renovation Design Tools: AR preview, style matching
  3. Smart Home Control: Device connection, scene modes
  4. User Center: Preference settings, design favorites

Recommended Expansion Directions:

  1. Integrate AI design assistant to provide intelligent renovation suggestions
  2. Develop community features for users to share renovation cases
  3. Connect with e-commerce platforms for one-click building material purchases
  4. Add construction progress tracking functionality

HarmonyOS Next’s distributed capabilities are particularly suitable for real estate and renovation applications, enabling seamless cross-device experiences across phones, tablets, smart screens, and other devices.

Leave a Reply