基于HarmonyOS Next的体育类应用开发实战:从零构建篮球赛事管理系统
一、项目概述与开发环境准备
随着全民健身热潮的兴起,体育类应用在移动端的需求日益增长。本教程将带领开发者使用HarmonyOS Next的AppGallery Connect服务,开发一个功能完整的篮球赛事管理系统。该系统将包含赛事发布、球队管理、球员数据统计等核心功能,全面展示鸿蒙生态下体育类应用的开发流程。
开发环境要求:
- 安装最新版DevEco Studio(建议4.0及以上版本)
- 配置HarmonyOS SDK(API Version 9+)
- 注册华为开发者账号并开通AppGallery Connect服务
项目技术栈:
- 前端:ArkTS + 声明式UI
- 后端:AppGallery Connect的云数据库、云函数、认证服务
- 数据统计:AppGallery Connect的分析服务
二、项目初始化与基础配置
首先在DevEco Studio中创建新项目,选择"Application"模板,设备类型选择"Phone",语言选择ArkTS:
// 项目入口文件:EntryAbility.ts
import UIAbility from '@ohos.app.ability.UIAbility';
import window from '@ohos.window';
export default class EntryAbility extends UIAbility {
// 应用启动时创建
onCreate(want, launchParam) {
console.info('BasketballApp onCreate');
// 初始化AppGallery Connect服务
this.initAGC();
}
private async initAGC() {
try {
// 引入AGC核心模块
const agconnect = await import('@hw-agconnect/core-ohos');
// 使用项目配置初始化AGC
agconnect.default.instance().configInstance(
this.context,
{
api_key: "您的API_KEY",
client_id: "您的CLIENT_ID",
client_secret: "您的CLIENT_SECRET",
project_id: "您的PROJECT_ID",
package_name: "com.example.basketballapp"
}
);
console.info('AGC初始化成功');
} catch (error) {
console.error('AGC初始化失败:', error);
}
}
// 窗口创建时调用
onWindowStageCreate(windowStage: window.WindowStage) {
windowStage.loadContent('pages/Index', (err, data) => {
if (err) {
console.error('加载页面失败:', err);
return;
}
console.info('页面加载成功:', data);
});
}
}
在resources/base/profile/main_pages.json
中配置应用路由:
{
"src": [
"pages/Index",
"pages/Login",
"pages/Home",
"pages/Matches",
"pages/Teams",
"pages/Players",
"pages/Stats"
]
}
三、用户认证模块实现
体育类应用通常需要用户系统来管理不同角色的权限。我们使用AppGallery Connect的认证服务来实现这一功能。
1. 配置认证服务
在AppGallery Connect控制台启用认证服务,选择"手机号码"和"邮箱地址"作为登录方式。
2. 实现登录页面
// pages/Login.ets
import { LoginButton, LoginType } from '@hw-agconnect/auth-ohos';
import router from '@ohos.router';
@Entry
@Component
struct LoginPage {
@State phoneNumber: string = '';
@State verifyCode: string = '';
@State isCounting: boolean = false;
@State countdown: number = 60;
build() {
Column() {
Image($r('app.media.logo'))
.width(120)
.height(120)
.margin({ top: 40, bottom: 30 })
TextInput({ placeholder: '请输入手机号码' })
.type(InputType.Number)
.maxLength(11)
.height(50)
.width('80%')
.onChange((value: string) => {
this.phoneNumber = value;
})
Row() {
TextInput({ placeholder: '验证码' })
.type(InputType.Number)
.maxLength(6)
.height(50)
.width('60%')
.onChange((value: string) => {
this.verifyCode = value;
})
Button(this.isCounting ? `${this.countdown}s后重试` : '获取验证码')
.width('35%')
.height(50)
.margin({ left: 10 })
.enabled(!this.isCounting && this.phoneNumber.length === 11)
.onClick(() => {
this.sendVerifyCode();
})
}
.width('80%')
.margin({ top: 20 })
Button('登录')
.type(ButtonType.Capsule)
.width('80%')
.height(50)
.margin({ top: 40 })
.enabled(this.phoneNumber.length === 11 && this.verifyCode.length === 6)
.onClick(() => {
this.loginWithPhone();
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Start)
.alignItems(HorizontalAlign.Center)
}
// 发送验证码
private sendVerifyCode() {
const auth = require('@hw-agconnect/auth-ohos').default;
const agconnect = require('@hw-agconnect/core-ohos').default;
auth.getInstance(agconnect.instance())
.requestPhoneVerifyCode(this.phoneNumber)
.then(() => {
console.info('验证码发送成功');
this.startCountdown();
})
.catch((err: Error) => {
console.error('验证码发送失败:', err);
});
}
// 倒计时逻辑
private startCountdown() {
this.isCounting = true;
const timer = setInterval(() => {
if (this.countdown <= 0) {
clearInterval(timer);
this.isCounting = false;
this.countdown = 60;
return;
}
this.countdown--;
}, 1000);
}
// 手机号+验证码登录
private loginWithPhone() {
const auth = require('@hw-agconnect/auth-ohos').default;
const agconnect = require('@hw-agconnect/core-ohos').default;
const credential = auth.PhoneAuthProvider.credentialWithVerifyCode(
this.phoneNumber,
'',
this.verifyCode
);
auth.getInstance(agconnect.instance())
.signIn(credential)
.then((user: any) => {
console.info('登录成功:', user);
router.replace({ url: 'pages/Home' });
})
.catch((err: Error) => {
console.error('登录失败:', err);
});
}
}
四、赛事管理模块开发
赛事管理是体育类应用的核心功能,我们将使用AppGallery Connect的云数据库来存储赛事数据。
1. 创建数据模型
在AppGallery Connect控制台创建matches
集合,包含以下字段:
- matchId: 字符串,主键
- homeTeam: 字符串,主队名称
- awayTeam: 字符串,客队名称
- startTime: 时间戳,比赛开始时间
- location: 字符串,比赛地点
- status: 数字,比赛状态(0未开始,1进行中,2已结束)
2. 实现赛事列表页面
// pages/Matches.ets
import { CloudDBZoneWrapper } from '../model/CloudDBZoneWrapper';
import router from '@ohos.router';
@Entry
@Component
struct MatchesPage {
private cloudDBZoneWrapper: CloudDBZoneWrapper = new CloudDBZoneWrapper();
@State matches: Array<any> = [];
@State isLoading: boolean = true;
aboutToAppear() {
this.queryMatches();
}
build() {
Column() {
// 标题栏
Row() {
Text('赛事管理')
.fontSize(20)
.fontWeight(FontWeight.Bold)
Blank()
Button('+')
.type(ButtonType.Circle)
.width(40)
.height(40)
.onClick(() => {
router.push({ url: 'pages/AddMatch' });
})
}
.width('90%')
.margin({ top: 15, bottom: 15 })
// 加载状态
if (this.isLoading) {
LoadingProgress()
.color(Color.Blue)
.margin({ top: 50 })
}
// 赛事列表
List({ space: 10 }) {
ForEach(this.matches, (match: any) => {
ListItem() {
MatchItem({ match: match })
}
}, (match: any) => match.matchId)
}
.width('100%')
.layoutWeight(1)
.divider({ strokeWidth: 1, color: '#F1F1F1' })
}
.width('100%')
.height('100%')
}
// 查询赛事数据
private queryMatches() {
this.cloudDBZoneWrapper.queryMatches()
.then((matches: Array<any>) => {
this.matches = matches;
this.isLoading = false;
})
.catch((err: Error) => {
console.error('查询赛事失败:', err);
this.isLoading = false;
});
}
}
// 赛事项组件
@Component
struct MatchItem {
private match: any;
build() {
Row() {
Column() {
Text(`${this.match.homeTeam} vs ${this.match.awayTeam}`)
.fontSize(18)
.fontWeight(FontWeight.Bold)
Text(`时间: ${new Date(this.match.startTime).toLocaleString()}`)
.fontSize(14)
.margin({ top: 5 })
Text(`地点: ${this.match.location}`)
.fontSize(14)
.margin({ top: 2 })
}
.layoutWeight(1)
// 根据状态显示不同标签
if (this.match.status === 0) {
Text('未开始')
.fontColor('#666')
} else if (this.match.status === 1) {
Text('进行中')
.fontColor('#FF9900')
} else {
Text('已结束')
.fontColor('#999')
}
}
.padding(15)
.width('100%')
.onClick(() => {
router.push({ url: 'pages/MatchDetail', params: { matchId: this.match.matchId } });
})
}
}
3. 实现云数据库操作类
// model/CloudDBZoneWrapper.ts
import { cloud } from '@hw-agconnect/database-ohos';
import agconnect from '@hw-agconnect/core-ohos';
export class CloudDBZoneWrapper {
private cloudDBZone: cloud.CloudDBZone;
constructor() {
// 初始化云数据库区域
const config = {
name: 'BasketballDBZone', // 自定义区域名称
persistenceEnabled: true, // 启用持久化
encryptionKey: '' // 加密密钥(可选)
};
const agcCloudDB = cloud.CloudDBZoneManager.getInstance(agconnect.instance());
this.cloudDBZone = agcCloudDB.openCloudDBZone(config);
}
// 查询所有赛事
queryMatches(): Promise<Array<any>> {
return new Promise((resolve, reject) => {
const query = cloud.CloudDBZoneQuery.where('matches')
.orderByDesc('startTime')
.limit(100);
this.cloudDBZone.executeQuery(query)
.then((snapshot: cloud.CloudDBZoneSnapshot) => {
const matches: Array<any> = [];
while (snapshot.hasNext()) {
matches.push(snapshot.next());
}
resolve(matches);
})
.catch((err: Error) => {
reject(err);
});
});
}
// 添加新赛事
addMatch(match: any): Promise<void> {
return new Promise((resolve, reject) => {
this.cloudDBZone.executeUpsert([match])
.then(() => {
resolve();
})
.catch((err: Error) => {
reject(err);
});
});
}
// 更新赛事状态
updateMatchStatus(matchId: string, status: number): Promise<void> {
return new Promise((resolve, reject) => {
const query = cloud.CloudDBZoneQuery.where('matches')
.equalTo('matchId', matchId);
this.cloudDBZone.executeQuery(query)
.then((snapshot: cloud.CloudDBZoneSnapshot) => {
if (snapshot.hasNext()) {
const match = snapshot.next();
match.status = status;
return this.cloudDBZone.executeUpsert([match]);
} else {
throw new Error('未找到对应赛事');
}
})
.then(() => {
resolve();
})
.catch((err: Error) => {
reject(err);
});
});
}
}
五、数据统计与分析
体育类应用需要对比赛数据进行统计分析。我们将使用AppGallery Connect的分析服务来实现这一功能。
1. 配置分析服务
在AppGallery Connect控制台启用分析服务,创建自定义事件:
- match_view: 赛事查看
- stat_record: 数据记录
- player_performance: 球员表现
2. 实现数据统计功能
// utils/AnalyticsUtil.ts
import agconnect from '@hw-agconnect/core-ohos';
export class AnalyticsUtil {
private static instance: AnalyticsUtil;
private analytics: any;
private constructor() {
this.analytics = require('@hw-agconnect/analytics-ohos').default;
}
public static getInstance(): AnalyticsUtil {
if (!AnalyticsUtil.instance) {
AnalyticsUtil.instance = new AnalyticsUtil();
}
return AnalyticsUtil.instance;
}
// 记录赛事查看事件
public logMatchView(matchId: string) {
const eventData = {
match_id: matchId,
timestamp: new Date().getTime()
};
this.analytics.instance(agconnect.instance())
.onEvent('match_view', eventData);
}
// 记录比赛数据
public logMatchStats(matchId: string, stats: any) {
const eventData = {
match_id: matchId,
...stats
};
this.analytics.instance(agconnect.instance())
.onEvent('stat_record', eventData);
}
// 记录球员表现
public logPlayerPerformance(playerId: string, performance: any) {
const eventData = {
player_id: playerId,
...performance
};
this.analytics.instance(agconnect.instance())
.onEvent('player_performance', eventData);
}
// 获取热门赛事数据
public getPopularMatches(): Promise<Array<any>> {
return new Promise((resolve, reject) => {
// 这里可以调用分析服务的API获取数据
// 实际开发中需要根据分析服务的具体API实现
resolve([]);
});
}
}
3. 在赛事详情页使用分析服务
// pages/MatchDetail.ets
import { AnalyticsUtil } from '../utils/AnalyticsUtil';
import router from '@ohos.router';
@Entry
@Component
struct MatchDetailPage {
@State match: any = {};
@State isLoading: boolean = true;
aboutToAppear() {
const params = router.getParams() as Record<string, string>;
const matchId = params['matchId'];
if (matchId) {
this.fetchMatchDetail(matchId);
// 记录赛事查看事件
AnalyticsUtil.getInstance().logMatchView(matchId);
}
}
build() {
Column() {
// 页面内容...
}
}
private fetchMatchDetail(matchId: string) {
// 获取赛事详情逻辑...
}
}
六、应用打包与发布
完成开发后,我们需要将应用打包并发布到AppGallery。
1. 配置应用签名
在DevEco Studio中:
- 选择"File" > "Project Structure" > "Project" > "Signing Configs"
- 配置签名证书信息
- 勾选"Automatically generate signing"
2. 构建发布版本
- 选择"Build" > "Build Haps"
- 选择"Release"模式
- 等待构建完成
3. 上传到AppGallery Connect
- 登录AppGallery Connect控制台
- 选择"我的应用" > "添加应用"
- 填写应用信息并上传构建好的HAP文件
- 提交审核
七、总结与扩展
通过本教程,我们完成了一个基于HarmonyOS Next的篮球赛事管理系统的核心功能开发。系统包含了用户认证、赛事管理、数据统计等体育类应用的典型功能模块。
扩展建议:
- 可以集成华为地图服务,实现比赛地点的精确定位和导航
- 添加直播功能,使用华为的视频服务实现比赛直播
- 开发穿戴设备版本,实时监测运动员的运动数据
- 使用华为的机器学习服务,对比赛数据进行分析预测
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。