diff --git a/packages/camera/camera_ohos/example/lib/fileselector/Singleton.dart b/packages/camera/camera_ohos/example/lib/fileselector/Singleton.dart new file mode 100644 index 0000000000000000000000000000000000000000..7ceadaf63547fda453b5f3c92fbd80b13ad83330 --- /dev/null +++ b/packages/camera/camera_ohos/example/lib/fileselector/Singleton.dart @@ -0,0 +1,27 @@ +class Singleton { + // 私有成员变量,用于存储单例实例 + static final Singleton _instance = Singleton._internal(); + + // 私有构造函数,防止外部创建实例 + Singleton._internal(); + + // 静态工厂构造函数,返回单例实例 + static Singleton getInstance() { + return _instance; + } + + // 或者使用 getter 来简化访问 + static Singleton get instance => _instance; + + // 定义一些属性和方法 + String? data; + + void setData(String newData) { + print('Setting data: $newData'); + data = newData; + } + + String getData() { + return data ?? 'No data'; + } +} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/lib/fileselector/camera_flutter_ohos.dart b/packages/camera/camera_ohos/example/lib/fileselector/camera_flutter_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..10df55b9bd4abaf64b5f22c879bf0a4ece53f1a1 --- /dev/null +++ b/packages/camera/camera_ohos/example/lib/fileselector/camera_flutter_ohos.dart @@ -0,0 +1,25 @@ +import 'package:flutter/widgets.dart'; +import 'camera_flutter_platform_interface_ohos.dart'; + +class QRCaptureController { + final QrcodeFlutterPlatform _platform = QrcodeFlutterPlatform.instance; + QRCaptureController(); + Widget _buildWidget() { + return _platform.buildWidget(); + } +} + +/// 使用Platform View展示相机,可在Flutter View中自定义相机显示位置 +/// Camera view +class QRCaptureView extends StatelessWidget { + /// 控制器 + final QRCaptureController controller; + /// key for Widget + /// controller 相机控制器 + const QRCaptureView({Key? key, required this.controller}) : super(key: key); + + @override + Widget build(BuildContext context) { + return controller._buildWidget(); + } +} diff --git a/packages/camera/camera_ohos/example/lib/fileselector/camera_flutter_platform_interface_ohos.dart b/packages/camera/camera_ohos/example/lib/fileselector/camera_flutter_platform_interface_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..643e5ca88f8c1f216d0998672512c26d471e3884 --- /dev/null +++ b/packages/camera/camera_ohos/example/lib/fileselector/camera_flutter_platform_interface_ohos.dart @@ -0,0 +1,29 @@ +import 'package:flutter/widgets.dart'; +import 'package:plugin_platform_interface/plugin_platform_interface.dart'; +import 'camera_video_io_ohos.dart'; + +/// 定义插件抽象 +abstract class QrcodeFlutterPlatform extends PlatformInterface { + /// Constructs a QrcodeFlutterPlatform. + QrcodeFlutterPlatform() : super(token: _token); + + static final Object _token = Object(); + + static QrcodeFlutterPlatform _instance = QRCodeFlutterIO(); + + /// The default instance of [QrcodeFlutterPlatform] to use. + /// + /// Defaults to [MethodChannelQrcodeFlutter]. + static QrcodeFlutterPlatform get instance => _instance; + + /// Platform-specific implementations should set this with their own + /// platform-specific class that extends [QrcodeFlutterPlatform] when + /// they register themselves. + static set instance(QrcodeFlutterPlatform instance) { + PlatformInterface.verifyToken(instance, _token); + _instance = instance; + } + + /// Build camera widget + Widget buildWidget(); +} diff --git a/packages/camera/camera_ohos/example/lib/fileselector/camera_video_io_ohos.dart b/packages/camera/camera_ohos/example/lib/fileselector/camera_video_io_ohos.dart new file mode 100644 index 0000000000000000000000000000000000000000..b018f918e87b6b54eb23b5f2de554793a4a168d3 --- /dev/null +++ b/packages/camera/camera_ohos/example/lib/fileselector/camera_video_io_ohos.dart @@ -0,0 +1,48 @@ +import 'dart:io'; +import 'package:flutter/widgets.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'Singleton.dart'; +import 'camera_flutter_platform_interface_ohos.dart'; + +class QRCodeFlutterIO extends QrcodeFlutterPlatform { + MethodChannel? _methodChannel; + + void _onPlatformViewCreated(int id) { + _methodChannel = MethodChannel('plugins/qr_capture/method_$id'); + _methodChannel?.setMethodCallHandler((MethodCall call) async {}); + } + + @override + Widget buildWidget() => _QrCodeView( + qrCodeFlutterIO: this, + url: '', + ); +} + +class _QrCodeView extends StatefulWidget { + final String url; + final QRCodeFlutterIO qrCodeFlutterIO; + + const _QrCodeView( + {Key? key, required this.qrCodeFlutterIO, required this.url}) + : super(key: key); + + set urlId(int urlId) {} + + @override + State<_QrCodeView> createState() => __QrCodeViewState(); +} + +class __QrCodeViewState extends State<_QrCodeView> { + @override + Widget build(BuildContext context) { + return OhosView( + key: ValueKey(Singleton.getInstance().getData()), + viewType: 'plugins/qr_capture_view', + creationParamsCodec: const StandardMessageCodec(), + onPlatformViewCreated: (id) { + widget.qrCodeFlutterIO._onPlatformViewCreated(id); + }); + } +} diff --git a/packages/camera/camera_ohos/example/lib/fileselector/file_selector.dart b/packages/camera/camera_ohos/example/lib/fileselector/file_selector.dart deleted file mode 100644 index 693746d50a8b05eedaa34aa3052d19524bf82ec0..0000000000000000000000000000000000000000 --- a/packages/camera/camera_ohos/example/lib/fileselector/file_selector.dart +++ /dev/null @@ -1,33 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import 'file_selector_api.dart'; - -class FileSelector { - FileSelector({ FileSelectorApi? api}) - : _api = api ?? FileSelectorApi(); - - final FileSelectorApi _api; - - /// Registers this class as the implementation of the file_selector platform interface. - /// - @override - Future openFileByPath(String path) async { - final int? fd = await _api.openFileByPath(path); - print("openfile#"); - print(fd); - return fd; - } -} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/lib/fileselector/file_selector_api.dart b/packages/camera/camera_ohos/example/lib/fileselector/file_selector_api.dart deleted file mode 100644 index 8ff6df7c6fb327a85e179edab359cc7d4ca3d3ed..0000000000000000000000000000000000000000 --- a/packages/camera/camera_ohos/example/lib/fileselector/file_selector_api.dart +++ /dev/null @@ -1,142 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import 'dart:async'; -import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer; -import 'package:flutter/services.dart'; - -class FileResponse { - FileResponse({ - required this.path, - this.name, - required this.fd, - }); - - String path; - - String? name; - - int fd; - - Object encode() { - return [ - path, - name, - fd, - ]; - } - - static FileResponse decode(Object result) { - result as List; - return FileResponse( - path: result[0]! as String, - name: result[1] as String?, - fd: result[2]! as int, - ); - } -} - -class FileTypes { - FileTypes({ - required this.mimeTypes, - required this.extensions, - }); - - List mimeTypes; - - List extensions; - - Object encode() { - return [ - mimeTypes, - extensions, - ]; - } - - static FileTypes decode(Object result) { - result as List; - return FileTypes( - mimeTypes: (result[0] as List?)!.cast(), - extensions: (result[1] as List?)!.cast(), - ); - } -} - -class _FileSelectorApiCodec extends StandardMessageCodec { - const _FileSelectorApiCodec(); - @override - void writeValue(WriteBuffer buffer, Object? value) { - if (value is FileResponse) { - buffer.putUint8(128); - writeValue(buffer, value.encode()); - } else if (value is FileTypes) { - buffer.putUint8(129); - writeValue(buffer, value.encode()); - } else { - super.writeValue(buffer, value); - } - } - - @override - Object? readValueOfType(int type, ReadBuffer buffer) { - switch (type) { - case 128: - return FileResponse.decode(readValue(buffer)!); - case 129: - return FileTypes.decode(readValue(buffer)!); - default: - return super.readValueOfType(type, buffer); - } - } -} - -/// An API to call to native code to select files or directories. -class FileSelectorApi { - /// Constructor for [FileSelectorApi]. The [binaryMessenger] named argument is - /// available for dependency injection. If it is left null, the default - /// BinaryMessenger will be used which routes to the host platform. - FileSelectorApi({BinaryMessenger? binaryMessenger}) - : _binaryMessenger = binaryMessenger; - final BinaryMessenger? _binaryMessenger; - - static const MessageCodec codec = _FileSelectorApiCodec(); - - /// Opens a file dialog for loading files and returns a file path. - /// - /// Returns `null` if user cancels the operation. - Future openFileByPath(String path) async { - final BasicMessageChannel channel = BasicMessageChannel( - 'dev.flutter.FileSelectorApi.openFileByPath', codec, - binaryMessenger: _binaryMessenger); - final List? replyList = - await channel.send([path]) - as List?; - if (replyList == null) { - throw PlatformException( - code: 'channel-error', - message: 'Unable to establish connection on channel.', - ); - } else if (replyList.length > 1) { - throw PlatformException( - code: replyList[0]! as String, - message: replyList[1] as String?, - details: replyList[2], - ); - } else { - return (replyList[0] as int?); - } - } - -} diff --git a/packages/camera/camera_ohos/example/lib/main.dart b/packages/camera/camera_ohos/example/lib/main.dart index 8d4b760a6d6cca948d59f3dc51cf05f7d614b953..42a21fc274eab214c7a05ae0a71664c8ea0d8e72 100644 --- a/packages/camera/camera_ohos/example/lib/main.dart +++ b/packages/camera/camera_ohos/example/lib/main.dart @@ -5,8 +5,7 @@ import 'dart:async'; import 'dart:io'; import 'dart:math'; - -import 'package:camera_ohos/camera_ohos.dart'; +import 'fileselector/Singleton.dart'; import 'package:camera_platform_interface/camera_platform_interface.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; @@ -15,7 +14,7 @@ import 'package:video_player/video_player.dart'; import 'camera_controller.dart'; import 'camera_preview.dart'; -import 'fileselector/file_selector.dart'; +import 'fileselector/camera_flutter_ohos.dart'; /// Camera example home widget. class CameraExampleHome extends StatefulWidget { @@ -70,7 +69,7 @@ class _CameraExampleHomeState extends State double _maxAvailableZoom = 1.0; double _currentScale = 1.0; double _baseScale = 1.0; - + bool isStartVideoPlayer = false; // Counting pointers (number of user fingers on screen) int _pointers = 0; @@ -144,9 +143,9 @@ class _CameraExampleHomeState extends State color: Colors.black, border: Border.all( color: - controller != null && controller!.value.isRecordingVideo - ? Colors.redAccent - : Colors.grey, + controller != null && controller!.value.isRecordingVideo + ? Colors.redAccent + : Colors.grey, width: 3.0, ), ), @@ -195,14 +194,14 @@ class _CameraExampleHomeState extends State controller!, child: LayoutBuilder( builder: (BuildContext context, BoxConstraints constraints) { - return GestureDetector( - behavior: HitTestBehavior.opaque, - onScaleStart: _handleScaleStart, - onScaleUpdate: _handleScaleUpdate, - onTapDown: (TapDownDetails details) => - onViewFinderTap(details, constraints), - ); - }), + return GestureDetector( + behavior: HitTestBehavior.opaque, + onScaleStart: _handleScaleStart, + onScaleUpdate: _handleScaleUpdate, + onTapDown: (TapDownDetails details) => + onViewFinderTap(details, constraints), + ); + }), ), ); } @@ -227,39 +226,34 @@ class _CameraExampleHomeState extends State /// Display the thumbnail of the captured image or video. Widget _thumbnailWidget() { - final VideoPlayerController? localVideoController = videoController; - + QRCaptureController _controller = QRCaptureController(); return Expanded( child: Align( alignment: Alignment.centerRight, child: Row( mainAxisSize: MainAxisSize.min, children: [ - if (localVideoController == null && imageFile == null) + if (!isStartVideoPlayer && imageFile == null ) Container() else SizedBox( width: 64.0, height: 64.0, - child: (localVideoController == null) + child: (!isStartVideoPlayer || imageFile != null) ? ( - // The captured image on the web contains a network-accessible URL - // pointing to a location within the browser. It may be displayed - // either with Image.network or Image.memory after loading the image - // bytes to memory. - kIsWeb - ? Image.network(imageFile!.path) - : Image.file(File(imageFile!.path))) + // The captured image on the web contains a network-accessible URL + // pointing to a location within the browser. It may be displayed + // either with Image.network or Image.memory after loading the image + // bytes to memory. + kIsWeb + ? Image.network(imageFile!.path) + : QRCaptureView(controller: _controller)) : Container( - decoration: BoxDecoration( - border: Border.all(color: Colors.pink)), - child: Center( - child: AspectRatio( - aspectRatio: - localVideoController.value.aspectRatio, - child: VideoPlayer(localVideoController)), - ), - ), + decoration: BoxDecoration( + border: Border.all(color: Colors.pink)), + child: Center( + child: QRCaptureView(controller: _controller) + ) ), ), ], ), @@ -282,20 +276,20 @@ class _CameraExampleHomeState extends State // The exposure and focus mode are currently not supported on the web. ...!kIsWeb ? [ - IconButton( - icon: const Icon(Icons.exposure), - color: Colors.blue, - onPressed: controller != null - ? onExposureModeButtonPressed - : null, - ), - IconButton( - icon: const Icon(Icons.filter_center_focus), - color: Colors.blue, - onPressed: - controller != null ? onFocusModeButtonPressed : null, - ) - ] + IconButton( + icon: const Icon(Icons.exposure), + color: Colors.blue, + onPressed: controller != null + ? onExposureModeButtonPressed + : null, + ), + IconButton( + icon: const Icon(Icons.filter_center_focus), + color: Colors.blue, + onPressed: + controller != null ? onFocusModeButtonPressed : null, + ) + ] : [], IconButton( icon: Icon(enableAudio ? Icons.volume_up : Icons.volume_mute), @@ -398,7 +392,7 @@ class _CameraExampleHomeState extends State style: styleAuto, onPressed: controller != null ? () => - onSetExposureModeButtonPressed(ExposureMode.auto) + onSetExposureModeButtonPressed(ExposureMode.auto) : null, onLongPress: () { if (controller != null) { @@ -413,7 +407,7 @@ class _CameraExampleHomeState extends State style: styleLocked, onPressed: controller != null ? () => - onSetExposureModeButtonPressed(ExposureMode.locked) + onSetExposureModeButtonPressed(ExposureMode.locked) : null, child: const Text('LOCKED'), ), @@ -439,7 +433,7 @@ class _CameraExampleHomeState extends State max: _maxAvailableExposureOffset, label: _currentExposureOffset.toString(), onChanged: _minAvailableExposureOffset == - _maxAvailableExposureOffset + _maxAvailableExposureOffset ? null : setExposureOffset, ), @@ -519,8 +513,8 @@ class _CameraExampleHomeState extends State icon: const Icon(Icons.camera_alt), color: Colors.blue, onPressed: cameraController != null && - cameraController.value.isInitialized && - !cameraController.value.isRecordingVideo + cameraController.value.isInitialized && + !cameraController.value.isRecordingVideo ? onTakePictureButtonPressed : null, ), @@ -528,43 +522,43 @@ class _CameraExampleHomeState extends State icon: const Icon(Icons.videocam), color: Colors.blue, onPressed: cameraController != null && - cameraController.value.isInitialized && - !cameraController.value.isRecordingVideo + cameraController.value.isInitialized && + !cameraController.value.isRecordingVideo ? onVideoRecordButtonPressed : null, ), IconButton( icon: cameraController != null && - (!cameraController.value.isRecordingVideo || - cameraController.value.isRecordingPaused) + (!cameraController.value.isRecordingVideo || + cameraController.value.isRecordingPaused) ? const Icon(Icons.play_arrow) : const Icon(Icons.pause), color: Colors.blue, onPressed: cameraController != null && - cameraController.value.isInitialized && - cameraController.value.isRecordingVideo + cameraController.value.isInitialized && + cameraController.value.isRecordingVideo ? (cameraController.value.isRecordingPaused) - ? onResumeButtonPressed - : onPauseButtonPressed + ? onResumeButtonPressed + : onPauseButtonPressed : null, ), IconButton( icon: const Icon(Icons.stop), color: Colors.red, onPressed: cameraController != null && - cameraController.value.isInitialized && - cameraController.value.isRecordingVideo + cameraController.value.isInitialized && + cameraController.value.isRecordingVideo ? onStopButtonPressed : null, ), IconButton( icon: const Icon(Icons.pause_presentation), color: - cameraController != null && cameraController.value.isPreviewPaused - ? Colors.red - : Colors.blue, + cameraController != null && cameraController.value.isPreviewPaused + ? Colors.red + : Colors.blue, onPressed: - cameraController == null ? null : onPausePreviewButtonPressed, + cameraController == null ? null : onPausePreviewButtonPressed, ), ], ); @@ -660,14 +654,14 @@ class _CameraExampleHomeState extends State // The exposure mode is currently not supported on the web. ...!kIsWeb ? >[ - CameraPlatform.instance - .getMinExposureOffset(cameraController.cameraId) - .then( - (double value) => _minAvailableExposureOffset = value), - CameraPlatform.instance - .getMaxExposureOffset(cameraController.cameraId) - .then((double value) => _maxAvailableExposureOffset = value) - ] + CameraPlatform.instance + .getMinExposureOffset(cameraController.cameraId) + .then( + (double value) => _minAvailableExposureOffset = value), + CameraPlatform.instance + .getMaxExposureOffset(cameraController.cameraId) + .then((double value) => _maxAvailableExposureOffset = value) + ] : >[], CameraPlatform.instance .getMaxZoomLevel(cameraController.cameraId) @@ -682,26 +676,26 @@ class _CameraExampleHomeState extends State showInSnackBar('You have denied camera access.'); break; case 'CameraAccessDeniedWithoutPrompt': - // iOS only + // iOS only showInSnackBar('Please go to Settings app to enable camera access.'); break; case 'CameraAccessRestricted': - // iOS only + // iOS only showInSnackBar('Camera access is restricted.'); break; case 'AudioAccessDenied': showInSnackBar('You have denied audio access.'); break; case 'AudioAccessDeniedWithoutPrompt': - // iOS only + // iOS only showInSnackBar('Please go to Settings app to enable audio access.'); break; case 'AudioAccessRestricted': - // iOS only + // iOS only showInSnackBar('Audio access is restricted.'); break; case 'cameraPermission': - // Android & web only + // Android & web only showInSnackBar('Unknown permission error.'); break; default: @@ -720,8 +714,7 @@ class _CameraExampleHomeState extends State if (mounted) { setState(() { imageFile = file; - videoController?.dispose(); - videoController = null; + Singleton.getInstance().setData(imageFile?.path ?? ''); }); if (file != null) { showInSnackBar('Picture saved to ${file.path}'); @@ -828,6 +821,8 @@ class _CameraExampleHomeState extends State if (file != null) { showInSnackBar('Video recorded to ${file.path}'); videoFile = file; + + Singleton.getInstance().setData(file.path); _startVideoPlayer(); } }); @@ -992,39 +987,8 @@ class _CameraExampleHomeState extends State } Future _startVideoPlayer() async { - if (videoFile == null) { - return; - } - final VideoPlayerController vController; - if (Platform.operatingSystem == 'ohos') { - final FileSelector instance = FileSelector(); - int? fileFd = await instance.openFileByPath(videoFile!.path); - vController = VideoPlayerController.fileFd(fileFd!); - } else { - vController = kIsWeb? VideoPlayerController.network(videoFile!.path) - : VideoPlayerController.file(File(videoFile!.path)); - } - videoPlayerListener = () { - if (videoController != null) { - // Refreshing the state to update video player with the correct ratio. - if (mounted) { - setState(() {}); - } - videoController!.removeListener(videoPlayerListener!); - } - }; - vController.addListener(videoPlayerListener!); - await vController.setLooping(true); - await vController.initialize(); - await videoController?.dispose(); - if (mounted) { - setState(() { - imageFile = null; - videoController = vController; - }); - } - await vController.play(); - print("========_startVideoPlayer end: "+videoFile!.path); + isStartVideoPlayer = true; + setState((){}); } Future takePicture() async { diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets index 4520247a1c52b3c076a58b949a2ad69f0d2bc652..aecbcae34b76c68601420d2635c0ab5183944af1 100644 --- a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/entryability/EntryAbility.ets @@ -16,12 +16,12 @@ import { FlutterAbility } from '@ohos/flutter_ohos' import { GeneratedPluginRegistrant } from '../plugins/GeneratedPluginRegistrant'; import FlutterEngine from '@ohos/flutter_ohos/src/main/ets/embedding/engine/FlutterEngine'; -import FileSelectorOhosPlugin from '../fileselector/FileSelectorOhosPlugin'; +import VideoPlayerFlutterPlugin from '../fileselector/VideoPlayerFlutterPlugin'; export default class EntryAbility extends FlutterAbility { configureFlutterEngine(flutterEngine: FlutterEngine) { super.configureFlutterEngine(flutterEngine) GeneratedPluginRegistrant.registerWith(flutterEngine) - this.addPlugin(new FileSelectorOhosPlugin()); + this.addPlugin(new VideoPlayerFlutterPlugin()); } } diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/ChannelDelegateImpl.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/ChannelDelegateImpl.ets new file mode 100644 index 0000000000000000000000000000000000000000..1098cbbe3fbefb323a29f0f2f9b6807febaf27f9 --- /dev/null +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/ChannelDelegateImpl.ets @@ -0,0 +1,40 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { MethodCall, MethodChannel } from '@ohos/flutter_ohos'; +import { MethodResult } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; +import { MethodCallHandler } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; + +export default class ChannelDelegateImpl implements MethodCallHandler { + private channel: MethodChannel | null; + + constructor(channel: MethodChannel) { + this.channel = channel; + this.channel.setMethodCallHandler(this); + } + + getChannel(): MethodChannel { + return this.channel! + } + + dispose(): void { + if (this.channel != null) { + this.channel.setMethodCallHandler(null); + this.channel = null; + } + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + } +} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/FileSelector.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/FileSelector.ets deleted file mode 100644 index 87268e044bc48aaeeed5de5fc005b7fe0d328d16..0000000000000000000000000000000000000000 --- a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/FileSelector.ets +++ /dev/null @@ -1,82 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import fs from '@ohos.file.fs'; -import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; -import { Result, FileSelectorApiCodec} from './GeneratedFileSelectorApi' -import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger'; -import MessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/MessageCodec'; -import BasicMessageChannel, { Reply } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BasicMessageChannel'; -import { AbilityPluginBinding } from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; -import ArrayList from '@ohos.util.ArrayList'; - -const TAG = "FileSelector"; -export class FileSelector { - - binding: AbilityPluginBinding; - - constructor(binding: AbilityPluginBinding) { - this.binding = binding; - } - - async openFileByPath(path: string, result: Result): Promise { - try { - let file = await fs.open(path); - result.success(file.fd); - } catch (err) { - Log.e(TAG, 'open file failed with err: ' + err); - result.error(new Error("Failed to read file")); - } - } - - static getCodec(): MessageCodec { - return FileSelectorApiCodec.INSTANCE; - } - - setup(binaryMessenger: BinaryMessenger, abilityPluginBinding: AbilityPluginBinding): void { - let api = this; - { - this.binding = abilityPluginBinding; - const channel: BasicMessageChannel = new BasicMessageChannel( - binaryMessenger, "dev.flutter.FileSelectorApi.openFileByPath", FileSelector.getCodec()); - channel.setMessageHandler({ - onMessage(msg: ESObject, reply: Reply): void { - Log.d(TAG, 'onMessage reply:' + reply) - const wrapped: Array = new Array(); - const args: Array = msg as Array; - const path = args[0] as string; - const resultCallback: Result = new ResultBuilder((result: number): void => { - wrapped.push(result); - reply.reply(wrapped); - },(error: Error): void => { - const wrappedError: ArrayList = msg.wrapError(error); - reply.reply(wrappedError); - }) - api.openFileByPath(path, resultCallback); - } - }); - } - } -} - -class ResultBuilder{ - success : (result: number)=>void - error: (error: Error) =>void - - constructor(success:ESObject , error:ESObject) { - this.success = success - this.error = error - } -} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/FileSelectorOhosPlugin.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/FileSelectorOhosPlugin.ets deleted file mode 100644 index 2b3e4179eb15ee6291caecba078dccb65346ca16..0000000000000000000000000000000000000000 --- a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/FileSelectorOhosPlugin.ets +++ /dev/null @@ -1,56 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import AbilityAware from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityAware'; -import { - AbilityPluginBinding -} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/ability/AbilityPluginBinding'; -import { - FlutterPlugin, - FlutterPluginBinding -} from '@ohos/flutter_ohos/src/main/ets/embedding/engine/plugins/FlutterPlugin'; -import { FileSelector } from './FileSelector' - -const TAG = "FileSelectorOhosPlugin" - -export default class FileSelectorOhosPlugin implements FlutterPlugin, AbilityAware { - - private pluginBinding: FlutterPluginBinding | null = null; - private fileSelectorApi: FileSelector | null = null; - - getUniqueClassName(): string { - return "FileSelectorOhosPlugin" - } - - onAttachedToAbility(binding: AbilityPluginBinding): void { - this.fileSelectorApi = new FileSelector(binding); - if (this.pluginBinding != null) { - this.fileSelectorApi.setup(this.pluginBinding.getBinaryMessenger(), binding); - } - } - - onDetachedFromAbility(): void { - this.fileSelectorApi = null; - } - - onAttachedToEngine(binding: FlutterPluginBinding): void { - console.debug(TAG, 'onAttachedToEngine file selector ') - this.pluginBinding = binding; - } - - onDetachedFromEngine(binding: FlutterPluginBinding): void { - this.pluginBinding = null; - } -} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/GeneratedFileSelectorApi.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/GeneratedFileSelectorApi.ets deleted file mode 100644 index 2d1f8cbe2e6c3fce484031fc04af8806165b2059..0000000000000000000000000000000000000000 --- a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/GeneratedFileSelectorApi.ets +++ /dev/null @@ -1,194 +0,0 @@ -/* -* Copyright (c) 2024 Hunan OpenValley Digital Industry Development Co., Ltd. -* Licensed under the Apache License, Version 2.0 (the "License"); -* you may not use this file except in compliance with the License. -* You may obtain a copy of the License at -* -* http://www.apache.org/licenses/LICENSE-2.0 -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -import { ByteBuffer } from '@ohos/flutter_ohos/src/main/ets/util/ByteBuffer'; -import StandardMessageCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMessageCodec'; -import Log from '@ohos/flutter_ohos/src/main/ets/util/Log'; - -const TAG = "GeneratedFileSelectorApi"; - -class FlutterError extends Error { - /** The error code. */ - public code: string; - - /** The error details. Must be a datatype supported by the api codec. */ - public details: ESObject; - - constructor(code: string, message: string, details: ESObject) { - super(message); - this.code = code; - this.details = details; - } -} - -export function wrapError(exception: Error): Array { - let errorList: Array = new Array(); - if (exception instanceof FlutterError) { - let error = exception as FlutterError; - errorList.push(error.code); - errorList.push(error.message); - errorList.push(error.details); - } else { - errorList.push(exception.toString()); - errorList.push(exception.name); - errorList.push( - "Cause: " + exception.message + ", Stacktrace: " + exception.stack); - } - return errorList; -} - -export class FileResponse { - private path: string; - - public getPath(): string { - return this.path; - } - - public setPath(setterArg: string): void { - if (setterArg == null) { - throw new Error('Nonnull field \'path\' is null.'); - } - this.path = setterArg; - } - - private name: string; - - public getName(): string { - return this.name; - } - - public setName(setterArg: string): void { - this.name = setterArg; - } - - private fd: number; - - public getFd(): number { - return this.fd; - } - - public setFd(setterArg: number): void { - if (setterArg == null) { - throw new Error("Nonnull field \"fd\" is null."); - } - this.fd = setterArg; - } - - constructor(path: string, name: string, fd: number) { - this.path = path; - this.name = name; - this.fd = fd; - } - - toList(): Array { - let toListResult: Array = new Array(); - toListResult.push(this.path); - toListResult.push(this.name); - toListResult.push(this.fd); - return toListResult; - } - - static fromList(list: Array): FileResponse { - let path: ESObject = list[0]; - let name: ESObject = list[1]; - let fd: ESObject = list[2]; - let response = new FileResponse(path, name, fd); - return response; - } -} - -export class FileTypes { - mimeTypes: Array = []; - - getMimeTypes(): Array { - return this.mimeTypes; - } - - setMimeTypes(setterArg: Array | null): void { - if (setterArg == null) { - throw new Error("Nonnull field \"mimeTypes\" is null."); - } - this.mimeTypes = setterArg; - } - - extensions: Array = []; - - getExtensions(): Array { - return this.extensions; - } - - setExtensions(setterArg: Array): void { - if (setterArg == null) { - throw new Error("Nonnull field \"extensions\" is null."); - } - this.extensions = setterArg; - } - - /** Constructor is non-public to enforce null safety; use Builder. */ - FileTypes() {} - - toList(): Array { - let toListResult: Array = new Array(); - toListResult.push(this.mimeTypes); - toListResult.push(this.extensions); - return toListResult; - } - - static fromList(list: Array): FileTypes { - let pigeonResult = new FileTypes(); - let mimeTypes: ESObject = list[0]; - pigeonResult.setMimeTypes(mimeTypes as Array); - let extensions: ESObject = list[1]; - pigeonResult.setExtensions(extensions as Array); - return pigeonResult; - } -} - - -export interface Result { - success(result: T): void; - error(error: Error): void; -} - -export class FileSelectorApiCodec extends StandardMessageCodec { - public static INSTANCE = new FileSelectorApiCodec(); - - readValueOfType(type: number, buffer: ByteBuffer): ESObject { - switch (type) { - case 128: - let res0 = FileResponse.fromList(super.readValue(buffer) as Array); - return res0; - case 129: - let vur: ESObject = super.readValue(buffer) - let res1 = FileTypes.fromList(vur as Array); - return res1; - default: - let res2: ESObject = super.readValueOfType(type, buffer); - return res2; - } - } - - writeValue(stream: ByteBuffer, value: ESObject): ESObject { - if (value instanceof FileResponse) { - stream.writeInt8(128); - return this.writeValue(stream, (value as FileResponse).toList()); - } else if (value instanceof FileTypes) { - stream.writeInt8(129); - return this.writeValue(stream, (value as FileTypes).toList()); - } else { - return super.writeValue(stream, value); - } - } - } diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/OhosVideoView.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/OhosVideoView.ets new file mode 100644 index 0000000000000000000000000000000000000000..f223293e719e6d78307e95b40efd269a2fe02f73 --- /dev/null +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/OhosVideoView.ets @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { scanBarcode, customScan } from '@kit.ScanKit'; +import { common, abilityAccessCtrl, Permissions } from '@kit.AbilityKit'; +import { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView'; +import { MethodResult } from '@ohos/flutter_ohos'; +import { BusinessError } from '@kit.BasicServicesKit'; +import QrCaptureView from './VideoView'; +import { fileUri } from '@kit.CoreFileKit'; +import { fileIo as fs, Filter, ListFileOptions } from '@kit.CoreFileKit'; + +const TAG: string = '[OhosView]: ' + +@Component +export struct OhosVideoView { + @State cacheDir: string = getContext(this).cacheDir + @Prop params: Params; + @State curRate: PlaybackSpeed = PlaybackSpeed.Speed_Forward_1_00_X + @State isAutoPlay: boolean = true + @State showControls: boolean = false + @State path: string = '' + @State uri: string = '' + @State isVideo: boolean = false + @State videoBorderWidth: number = 0 + controller: VideoController = new VideoController() + + async aboutToAppear() { + let listFileOption: ListFileOptions = { + recursion: false, + listNum: 0, + filter: { + suffix: [".jpg", ".mp4"], + } + } + let listFile: Array = await fs.listFile(this.cacheDir, listFileOption) + this.path = listFile[listFile.length-1] + if (this.isMp4File(this.path)) { + this.isVideo = true + this.videoBorderWidth = 1 + } + this.uri = fileUri.getUriFromPath(this.cacheDir + "/" + this.path) + } + + aboutToDisappear() { + } + + isMp4File(filename: string): boolean { + // 确保文件名不为空并且以 .mp4 结尾(忽略大小写) + return filename.trim().toLowerCase().endsWith('.mp4'); + } + + build() { + Stack() { + Column() { + if (this.isVideo) { + Video({ + src: this.uri, + currentProgressRate: this.curRate, + controller: this.controller + }) + .height(64) + .width(35) + .autoPlay(this.isAutoPlay) + .controls(this.showControls) + .loop(true) + } else { + Image(this.uri).height(64).width(35) + } + } + .border({ color: Color.Red, width: this.videoBorderWidth }) + .height(64) + .width(64) + .position({ x: 0, y: 0 }) + } + .width('100%') + .height('100%') + } +} + +@Builder +export function buildOhosView(params: Params) { + OhosVideoView({ + params: params + }) +} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoPlayerFlutterPlugin.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoPlayerFlutterPlugin.ets new file mode 100644 index 0000000000000000000000000000000000000000..a2de00e45961dac107c90e8c78b05c330d400a4f --- /dev/null +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoPlayerFlutterPlugin.ets @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { + FlutterPlugin, + FlutterPluginBinding, + MethodCall, + MethodCallHandler, + MethodChannel, + MethodResult, +} from '@ohos/flutter_ohos'; +import { AbilityAware, AbilityPluginBinding, BinaryMessenger } from '@ohos/flutter_ohos'; +import { UIAbility } from '@kit.AbilityKit'; +import { scanCore, scanBarcode, detectBarcode } from '@kit.ScanKit'; +import { BusinessError } from '@kit.BasicServicesKit'; +import { VideoViewManager } from './VideoViewManager'; +import QRCaptureViewFactory from './VideoViewFactory' +import common from '@ohos.app.ability.common'; + +const TAG = '[QrCodeFlutterPlugin] :' + +export default class VideoPlayerFlutterPlugin implements FlutterPlugin, MethodCallHandler, AbilityAware { + private channel: MethodChannel | null = null; + private applicationContext: Context | null = null; + private ability: UIAbility | null = null; + public messenger: BinaryMessenger | null = null; + private qrCodeViewManager: VideoViewManager | null = null; + private context: common.Context | null = null; + + onAttachedToAbility(binding: AbilityPluginBinding): void { + this.ability = binding.getAbility(); + } + + onDetachedFromAbility(): void { + this.ability = null; + } + + getUniqueClassName(): string { + return "VideoPlayerFlutterPlugin" + } + + onAttachedToEngine(binding: FlutterPluginBinding): void { + this.messenger = binding.getBinaryMessenger(); + this.applicationContext = binding.getApplicationContext(); + // 注册自定义视图 + const qRCaptureViewFactory = new QRCaptureViewFactory(this, this.applicationContext); + binding.getPlatformViewRegistry() + .registerViewFactory(QRCaptureViewFactory.VIEW_TYPE_ID, qRCaptureViewFactory); + this.channel = new MethodChannel(binding.getBinaryMessenger(), "plugins/qr_capture/method"); + this.channel.setMethodCallHandler(this); + this.context = binding.getApplicationContext() + } + + onDetachedFromEngine(binding: FlutterPluginBinding): void { + if (this.channel != null) { + this.channel.setMethodCallHandler(null) + } + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + } +} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoView.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoView.ets new file mode 100644 index 0000000000000000000000000000000000000000..d9099afd62f79ae118e7b481588c6ce7bec685ed --- /dev/null +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoView.ets @@ -0,0 +1,33 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { buildOhosView } from './OhosVideoView'; +import { PlatformView, } from '@ohos/flutter_ohos'; +import { Params } from '@ohos/flutter_ohos/src/main/ets/plugin/platform/PlatformView'; + +const TAG: string = "[QrCaptureView] :"; + +export default class VideoView extends PlatformView { + constructor() { + super(); + } + + getView(): WrappedBuilder<[Params]> { + return new WrappedBuilder(buildOhosView); + } + + dispose(): void { + console.info(TAG + 'dispose'); + } +} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoViewFactory.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoViewFactory.ets new file mode 100644 index 0000000000000000000000000000000000000000..c267b0ff9554651f0bcb6069d0f650df1882a562 --- /dev/null +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoViewFactory.ets @@ -0,0 +1,44 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { Any, PlatformView, PlatformViewFactory, StandardMessageCodec } from '@ohos/flutter_ohos'; +import { VideoViewManager } from './VideoViewManager'; +import QrCaptureView from './VideoView'; +import QrcodeFlutterPlugin from './VideoPlayerFlutterPlugin'; + +export default class VideoViewFactory extends PlatformViewFactory { + public static VIEW_TYPE_ID = "plugins/qr_capture_view"; + public plugin: QrcodeFlutterPlugin; + public viewId: number | null; + public qrCaptureView: QrCaptureView | null = null; + private qrCodeViewManager: VideoViewManager | null = null; + + constructor(plugin: QrcodeFlutterPlugin, context: Context) { + super(StandardMessageCodec.INSTANCE); + this.plugin = plugin; + this.viewId = null; + } + + public create(context: Context, viewId: number, args: Any): PlatformView { + this.viewId = viewId; + this.qrCaptureView = new QrCaptureView(); + // 视图桥接逻辑 + this.qrCodeViewManager = new VideoViewManager(this.plugin, this.viewId); + return new QrCaptureView(); + } + + getViewId() { + return this.viewId; + } +} \ No newline at end of file diff --git a/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoViewManager.ets b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoViewManager.ets new file mode 100644 index 0000000000000000000000000000000000000000..b36d170dfce6c21d0e8c2b5ea803b3c5cc3b86f9 --- /dev/null +++ b/packages/camera/camera_ohos/example/ohos/entry/src/main/ets/fileselector/VideoViewManager.ets @@ -0,0 +1,51 @@ +/* + * Copyright (C) 2024 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import { MethodCall, MethodChannel } from '@ohos/flutter_ohos'; +import { MethodResult } from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel'; +import QrCodeFlutterPlugin from './VideoPlayerFlutterPlugin'; +import ChannelDelegateImpl from './ChannelDelegateImpl'; +import QrCaptureView from './VideoView'; +import common from '@ohos.app.ability.common'; + +const LOG_TAG = "[VideoViewManager] :" +const METHOD_CHANNEL_NAME = "plugins/qr_capture/method" + +export class VideoViewManager extends ChannelDelegateImpl { + private plugin: QrCodeFlutterPlugin | null = null + public windowAutoincrementId: number = 0 + public debuggingEnabled = false; + public qrCaptureView: QrCaptureView | null = null; + cameraWidth: number = 0; + cameraHeight: number = 0; + + constructor(plugin: QrCodeFlutterPlugin, id: number) { + super(new MethodChannel(plugin.messenger!, METHOD_CHANNEL_NAME + '_' + id)); + this.plugin = plugin; + } + + onMethodCall(call: MethodCall, result: MethodResult): void { + const context = getContext(this) as common.UIAbilityContext; + switch (call.method) { + default: + result.notImplemented(); + break; + } + } + + public dispose(): void { + super.dispose(); + this.plugin = null; + } +} \ No newline at end of file