Ionic设备功能 #
一、相机功能 #
1.1 安装与配置 #
bash
npm install @capacitor/camera
npx cap sync
iOS配置(Info.plist):
xml
<key>NSCameraUsageDescription</key>
<string>需要访问相机以拍照</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>需要访问相册以选择照片</string>
Android配置(AndroidManifest.xml):
xml
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
1.2 相机服务 #
typescript
// services/camera.service.ts
import { Injectable } from '@angular/core';
import {
Camera,
CameraResultType,
CameraSource,
Photo
} from '@capacitor/camera';
@Injectable({
providedIn: 'root'
})
export class CameraService {
async takePhoto(): Promise<string | null> {
try {
const photo = await Camera.getPicture({
quality: 90,
allowEditing: true,
resultType: CameraResultType.Uri,
source: CameraSource.Camera,
saveToGallery: true
});
return photo.webPath;
} catch (error) {
console.error('拍照失败:', error);
return null;
}
}
async pickFromGallery(): Promise<string | null> {
try {
const photo = await Camera.getPicture({
quality: 90,
allowEditing: true,
resultType: CameraResultType.Uri,
source: CameraSource.Photos
});
return photo.webPath;
} catch (error) {
console.error('选择照片失败:', error);
return null;
}
}
async checkPermissions(): Promise<boolean> {
const permissions = await Camera.checkPermissions();
return permissions.camera === 'granted' && permissions.photos === 'granted';
}
async requestPermissions(): Promise<boolean> {
const permissions = await Camera.requestPermissions();
return permissions.camera === 'granted';
}
}
1.3 使用示例 #
typescript
import { Component } from '@angular/core';
import { CameraService } from './camera.service';
import { ActionSheetController } from '@ionic/angular';
@Component({
selector: 'app-profile',
templateUrl: 'profile.page.html'
})
export class ProfilePage {
avatar: string | null = null;
constructor(
private camera: CameraService,
private actionSheetCtrl: ActionSheetController
) {}
async selectAvatar() {
const actionSheet = await this.actionSheetCtrl.create({
header: '选择头像',
buttons: [
{
text: '拍照',
handler: async () => {
this.avatar = await this.camera.takePhoto();
}
},
{
text: '从相册选择',
handler: async () => {
this.avatar = await this.camera.pickFromGallery();
}
},
{
text: '取消',
role: 'cancel'
}
]
});
await actionSheet.present();
}
}
二、地理位置 #
2.1 安装与配置 #
bash
npm install @capacitor/geolocation
npx cap sync
iOS配置(Info.plist):
xml
<key>NSLocationWhenInUseUsageDescription</key>
<string>需要获取您的位置以提供更好的服务</string>
<key>NSLocationAlwaysUsageDescription</key>
<string>需要持续获取您的位置以提供导航服务</string>
Android配置(AndroidManifest.xml):
xml
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
2.2 位置服务 #
typescript
// services/location.service.ts
import { Injectable } from '@angular/core';
import { Geolocation, Position } from '@capacitor/geolocation';
import { BehaviorSubject, Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class LocationService {
private positionSubject = new BehaviorSubject<Position | null>(null);
private watchId: string | null = null;
position$ = this.positionSubject.asObservable();
async getCurrentPosition(): Promise<Position | null> {
try {
const position = await Geolocation.getCurrentPosition({
enableHighAccuracy: true,
timeout: 10000
});
this.positionSubject.next(position);
return position;
} catch (error) {
console.error('获取位置失败:', error);
return null;
}
}
async startWatching(): Promise<void> {
this.watchId = await Geolocation.watchPosition({
enableHighAccuracy: true,
timeout: 10000
}, (position, error) => {
if (error) {
console.error('位置监听错误:', error);
return;
}
this.positionSubject.next(position);
});
}
async stopWatching(): Promise<void> {
if (this.watchId) {
await Geolocation.clearWatch({ id: this.watchId });
this.watchId = null;
}
}
async checkPermissions(): Promise<boolean> {
const permissions = await Geolocation.checkPermissions();
return permissions.location === 'granted';
}
async requestPermissions(): Promise<boolean> {
const permissions = await Geolocation.requestPermissions();
return permissions.location === 'granted';
}
// 计算两点距离(米)
calculateDistance(
lat1: number, lon1: number,
lat2: number, lon2: number
): number {
const R = 6371e3;
const φ1 = lat1 * Math.PI / 180;
const φ2 = lat2 * Math.PI / 180;
const Δφ = (lat2 - lat1) * Math.PI / 180;
const Δλ = (lon2 - lon1) * Math.PI / 180;
const a = Math.sin(Δφ / 2) * Math.sin(Δφ / 2) +
Math.cos(φ1) * Math.cos(φ2) *
Math.sin(Δλ / 2) * Math.sin(Δλ / 2);
const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
return R * c;
}
}
三、推送通知 #
3.1 安装与配置 #
bash
npm install @capacitor/push-notifications
npx cap sync
3.2 推送服务 #
typescript
// services/push.service.ts
import { Injectable } from '@angular/core';
import { PushNotifications, PushNotificationSchema } from '@capacitor/push-notifications';
import { Router } from '@angular/router';
@Injectable({
providedIn: 'root'
})
export class PushService {
constructor(private router: Router) {}
async init(): Promise<void> {
// 请求权限
const result = await PushNotifications.requestPermissions();
if (result.receive === 'granted') {
// 注册推送
await PushNotifications.register();
// 监听事件
this.listenEvents();
}
}
private listenEvents(): void {
// 注册成功
PushNotifications.addListener('registration', (token) => {
console.log('推送token:', token.value);
// 发送token到服务器
});
// 注册失败
PushNotifications.addListener('registrationError', (error) => {
console.error('推送注册失败:', error);
});
// 收到推送
PushNotifications.addListener('pushNotificationReceived', (notification) => {
console.log('收到推送:', notification);
});
// 点击推送
PushNotifications.addListener('pushNotificationActionPerformed', (action) => {
console.log('点击推送:', action);
// 处理跳转
const data = action.notification.data;
if (data?.url) {
this.router.navigate([data.url]);
}
});
}
async getDeliveredNotifications(): Promise<PushNotificationSchema[]> {
const result = await PushNotifications.getDeliveredNotifications();
return result.notifications;
}
async removeAllDeliveredNotifications(): Promise<void> {
await PushNotifications.removeAllDeliveredNotifications();
}
}
四、传感器 #
4.1 加速度计 #
bash
npm install @capacitor/motion
npx cap sync
typescript
import { Motion } from '@capacitor/motion';
async watchAcceleration() {
await Motion.addListener('accel', (event) => {
console.log('加速度:', event.acceleration);
});
}
async stopWatching() {
await Motion.removeAllListeners();
}
4.2 指南针 #
typescript
import { DeviceOrientation } from '@capacitor/device-orientation';
async watchOrientation() {
await DeviceOrientation.addListener('orientation', (event) => {
console.log('方向:', event.alpha, event.beta, event.gamma);
});
}
五、其他设备功能 #
5.1 振动 #
typescript
import { Haptics, ImpactStyle } from '@capacitor/haptics';
// 轻触
async lightImpact() {
await Haptics.impact({ style: ImpactStyle.Light });
}
// 中等触感
async mediumImpact() {
await Haptics.impact({ style: ImpactStyle.Medium });
}
// 重触感
async heavyImpact() {
await Haptics.impact({ style: ImpactStyle.Heavy });
}
// 振动
async vibrate() {
await Haptics.vibrate();
}
5.2 屏幕方向 #
typescript
import { ScreenOrientation } from '@capacitor/screen-orientation';
// 锁定横屏
async lockLandscape() {
await ScreenOrientation.lock({ orientation: 'landscape' });
}
// 锁定竖屏
async lockPortrait() {
await ScreenOrientation.lock({ orientation: 'portrait' });
}
// 解锁
async unlock() {
await ScreenOrientation.unlock();
}
// 获取当前方向
async getOrientation() {
const { type } = await ScreenOrientation.orientation();
return type;
}
5.3 应用信息 #
typescript
import { App } from '@capacitor/app';
// 获取应用信息
async getAppInfo() {
const info = await App.getInfo();
console.log('应用信息:', info);
}
// 获取应用状态
App.addListener('appStateChange', (state) => {
console.log('应用状态:', state.isActive);
});
// 返回按钮处理
App.addListener('backButton', (event) => {
console.log('返回按钮按下');
});
六、最佳实践 #
6.1 权限检查 #
typescript
async function checkAndRequestPermissions() {
// 检查权限
const hasPermission = await checkPermission();
if (!hasPermission) {
// 请求权限
const granted = await requestPermission();
if (!granted) {
// 引导用户到设置页面
showPermissionAlert();
return false;
}
}
return true;
}
6.2 错误处理 #
typescript
async function useDeviceFeature() {
try {
const result = await deviceFeature();
return result;
} catch (error) {
if (error.message.includes('permission')) {
// 权限错误
showPermissionAlert();
} else if (error.message.includes('not available')) {
// 功能不可用
showFeatureNotAvailableAlert();
} else {
// 其他错误
showGenericError();
}
return null;
}
}
七、总结 #
7.1 设备功能要点 #
| 功能 | 插件 | 用途 |
|---|---|---|
| 相机 | @capacitor/camera | 拍照、选择照片 |
| 位置 | @capacitor/geolocation | 获取位置 |
| 推送 | @capacitor/push-notifications | 推送通知 |
| 振动 | @capacitor/haptics | 触感反馈 |
| 屏幕 | @capacitor/screen-orientation | 屏幕方向 |
7.2 下一步 #
掌握了设备功能后,接下来让我们学习 原生插件,了解如何开发自定义插件!
最后更新:2026-03-28