) => {
+ result.success(results);
+ }
+ } as ESObject, {
+ onError: (errorCode: string, errorDescription: string) => {
+ result.error(errorCode, errorDescription, null);
+ }
+ } as ESObject);
+ break;
+ case 'shouldShowRequestPermissionRationale':
+ let showShowPermission: number = call.args;
+ this.permissionManager.shouldShowRequestPermissionRationale(showShowPermission, {
+ onSuccess : (isShow: boolean) => {
+ result.success(isShow);
+ }
+ } as ESObject, {
+ onError: (errorCode: string, errorDescription: string) => {
+ result.error(errorCode, errorDescription, null);
+ }
+ } as ESObject);
+ break;
+ case 'openAppSettings':
+ this.appSettingManager.openAppSettings(this.ability, {
+ onSuccess: (isSuccess: boolean) => {
+ result.success(isSuccess)
+ }
+ } as ESObject, {
+ onError: (errorCode: string, errorDescription: string) => {
+ result.error(errorCode, errorDescription, null);
+ }
+ } as ESObject);
+ break;
+ default:
+ result.notImplemented();
+ break;
+ }
+ }
+}
diff --git a/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionConstants.ets b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionConstants.ets
new file mode 100644
index 0000000000000000000000000000000000000000..d79a42fedc1e0039d068489898518d1c3d33f318
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionConstants.ets
@@ -0,0 +1,82 @@
+/*
+ * 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.
+ */
+
+export default class PermissionConstants {
+ static LOG_TAG: string = 'permission_handler';
+ static PERMISSION_CODE: number = 24;
+ static PERMISSION_CODE_IGNORE_BATTERY_OPTIMIZATIONS: number = 209;
+ static PERMISSION_CODE_MANAGE_EXTERNAL_STORAGE: number = 210;
+ static PERMISSION_CODE_SYSTEM_ALERT_WINDOW: number = 211;
+ static PERMISSION_CODE_REQUEST_INSTALL_PACKAGES: number = 212;
+ static PERMISSION_CODE_ACCESS_NOTIFICATION_POLICY: number = 213;
+ static PERMISSION_CODE_SCHEDULE_EXACT_ALARM = 214;
+
+ //PERMISSION_GROUP
+ // Deprecated in favor of PERMISSION_GROUP_CALENDAR_WRITE_ONLY and
+ // PERMISSION_GROUP_CALENDAR_FULL_ACCESS.
+ static PERMISSION_GROUP_CALENDAR: number = 0;
+ static PERMISSION_GROUP_CAMERA: number = 1;
+ static PERMISSION_GROUP_CONTACTS: number = 2;
+ static PERMISSION_GROUP_LOCATION: number = 3;
+ static PERMISSION_GROUP_LOCATION_ALWAYS: number = 4;
+ static PERMISSION_GROUP_LOCATION_WHEN_IN_USE: number = 5;
+ static PERMISSION_GROUP_MEDIA_LIBRARY: number = 6;
+ static PERMISSION_GROUP_MICROPHONE: number = 7;
+ static PERMISSION_GROUP_PHONE: number = 8;
+ static PERMISSION_GROUP_PHOTOS: number = 9;
+ static PERMISSION_GROUP_PHOTOS_ADD_ONLY: number = 10;
+ static PERMISSION_GROUP_REMINDERS: number = 11;
+ static PERMISSION_GROUP_SENSORS: number = 12;
+ static PERMISSION_GROUP_SMS: number = 13;
+ static PERMISSION_GROUP_SPEECH: number = 14;
+ static PERMISSION_GROUP_STORAGE: number = 15;
+ static PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS: number = 16;
+ static PERMISSION_GROUP_NOTIFICATION: number = 17;
+ static PERMISSION_GROUP_ACCESS_MEDIA_LOCATION: number = 18;
+ static PERMISSION_GROUP_ACTIVITY_RECOGNITION: number = 19;
+ static PERMISSION_GROUP_UNKNOWN: number = 20;
+ static PERMISSION_GROUP_BLUETOOTH: number = 21;
+ static PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE: number = 22;
+ static PERMISSION_GROUP_SYSTEM_ALERT_WINDOW: number = 23;
+ static PERMISSION_GROUP_REQUEST_INSTALL_PACKAGES: number = 24;
+ static PERMISSION_GROUP_APP_TRACK_TRANSPARENCY: number = 25;
+ static PERMISSION_GROUP_CRITICAL_ALERTS: number = 26;
+ static PERMISSION_GROUP_ACCESS_NOTIFICATION_POLICY: number = 27;
+ static PERMISSION_GROUP_BLUETOOTH_SCAN: number = 28;
+ static PERMISSION_GROUP_BLUETOOTH_ADVERTISE: number = 29;
+ static PERMISSION_GROUP_BLUETOOTH_CONNECT: number = 30;
+ static PERMISSION_GROUP_NEARBY_WIFI_DEVICES: number = 31;
+ static PERMISSION_GROUP_VIDEOS: number = 32;
+ static PERMISSION_GROUP_AUDIO: number = 33;
+ static PERMISSION_GROUP_SCHEDULE_EXACT_ALARM: number = 34;
+ static PERMISSION_GROUP_SENSORS_ALWAYS: number = 35;
+ static PERMISSION_GROUP_CALENDAR_WRITE_ONLY = 36;
+ static PERMISSION_GROUP_CALENDAR_FULL_ACCESS = 37;
+ static PERMISSION_GROUP_ASSISTANT = 38;
+ static PERMISSION_GROUP_BACKGROUND_REFRESH = 39;
+
+ //PERMISSION_STATUS
+ static PERMISSION_STATUS_DENIED: number = 0;
+ static PERMISSION_STATUS_GRANTED: number = 1;
+ static PERMISSION_STATUS_RESTRICTED: number = 2;
+ static PERMISSION_STATUS_LIMITED: number = 3;
+ static PERMISSION_STATUS_NEVER_ASK_AGAIN: number = 4;
+
+ //SERVICE_STATUS
+ static SERVICE_STATUS_DISABLED: number = 0;
+ static SERVICE_STATUS_ENABLED: number = 1;
+ static SERVICE_STATUS_NOT_APPLICABLE: number = 2;
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionHandlerPlugin.ets b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionHandlerPlugin.ets
new file mode 100644
index 0000000000000000000000000000000000000000..1697ddd9900fdfc1f7ae880a1412e290ef3d5598
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionHandlerPlugin.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 common from '@ohos.app.ability.common';
+import UIAbility from '@ohos.app.ability.UIAbility';
+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 Log from '@ohos/flutter_ohos/src/main/ets/util/Log';
+import { BinaryMessenger } from '@ohos/flutter_ohos/src/main/ets/plugin/common/BinaryMessenger';
+import MethodChannel from '@ohos/flutter_ohos/src/main/ets/plugin/common/MethodChannel';
+import StandardMethodCodec from '@ohos/flutter_ohos/src/main/ets/plugin/common/StandardMethodCodec';
+import { AppSettingManager } from './AppSettingManager';
+import { MethodCallHandlerImpl } from './MethodCallHandlerImpl';
+import { PermissionManager } from './PermissionManager';
+import { ServiceManager } from './ServiceManager';
+
+
+const TAG: string = 'PermissionHandlerPlugin';
+
+/**
+ * Platform implementation of the permission_handler Flutter plugin.
+ *
+ * Instantiate this in an add to app scenario to gracefully handle ability and context changes.
+ * See {@code com.example.permissionhandlerexample.MainAbility} for an example.
+ *
+ */
+export default class PermissionHandlerPlugin implements FlutterPlugin, AbilityAware {
+ private permissionManager: PermissionManager;
+ private methodChannel: MethodChannel | null = null;
+ private methodCallHandler: MethodCallHandlerImpl | null = null;
+ private pluginBinding: AbilityPluginBinding | null = null;
+
+ constructor() {
+ this.permissionManager = new PermissionManager();
+ }
+
+ onAttachedToAbility(binding: AbilityPluginBinding): void {
+ this.pluginBinding = binding;
+ this.startListeningToAbility(this.pluginBinding.getAbility());
+ }
+
+ onDetachedFromAbility(): void {
+ this.stopListeningToAbility();
+ }
+
+ getUniqueClassName(): string {
+ return TAG;
+ }
+
+ onAttachedToEngine(binding: FlutterPluginBinding): void {
+ Log.i(TAG, 'onAttachedToEngine');
+ this.startListening(binding?.getApplicationContext(), binding?.getBinaryMessenger());
+ }
+
+ onDetachedFromEngine(binding: FlutterPluginBinding): void {
+ this.stopListening();
+ }
+
+ private startListening(context: common.Context, message: BinaryMessenger): void {
+ this.methodChannel = new MethodChannel(message, 'flutter.baseflow.com/permissions/methods', StandardMethodCodec.INSTANCE);
+ this.methodCallHandler = new MethodCallHandlerImpl(context, new AppSettingManager(),
+ this.permissionManager, new ServiceManager());
+ this.methodChannel.setMethodCallHandler(this.methodCallHandler);
+ }
+
+ private stopListening(): void {
+ this.methodChannel?.setMethodCallHandler(null);
+ this.methodChannel = null;
+ this.methodCallHandler = null;
+ }
+
+ private startListeningToAbility(ability: UIAbility): void {
+ if (this.methodCallHandler != null) {
+ this.methodCallHandler.setAbility(ability);
+ }
+ }
+
+ private stopListeningToAbility(): void {
+ if (this.methodCallHandler != null) {
+ this.methodCallHandler.setAbility(null);
+ }
+ }
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionManager.ets b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionManager.ets
new file mode 100644
index 0000000000000000000000000000000000000000..970b8cf6935cee49471de62e2e19d878547b9da0
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionManager.ets
@@ -0,0 +1,320 @@
+/*
+ * 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 common from '@ohos.app.ability.common';
+import PermissionConstants from './PermissionConstants';
+import abilityAccessCtrl, { Permissions } from '@ohos.abilityAccessCtrl';
+import bundleManager from '@ohos.bundle.bundleManager';
+import PermissionUtils from './PermissionUtils';
+import Log from '@ohos/flutter_ohos/src/main/ets/util/Log';
+import UIAbility from '@ohos.app.ability.UIAbility';
+import ArrayList from '@ohos.util.ArrayList';
+import { ErrorCallback } from './ErrorCallback';
+import { BusinessError, Callback } from '@ohos.base';
+import { notificationManager } from '@kit.NotificationKit';
+
+export class PermissionManager {
+ private tokenId: number | null = null;
+
+ private atManager: abilityAccessCtrl.AtManager;
+
+ private ongoing: boolean = false;
+
+ private ability: UIAbility | null = null;
+
+ private successCallback: RequestPermissionsSuccessCallback | null = null;
+
+ private requestResults:Map | null = null;
+
+ constructor() {
+ this.atManager = abilityAccessCtrl.createAtManager();
+ }
+
+ /**
+ * 检测权限状态
+ *
+ * @param permission 权限
+ * @param context 上下文
+ * @param successCallback 回调结果
+ */
+ public checkPermissionStatus(permission: number, context: common.Context,
+ successCallback: CheckPermissionSuccessCallback): void {
+ this.determinePermissionStatus(permission, successCallback);
+ }
+
+ private determinePermissionStatus(permission: number, successCallback: CheckPermissionSuccessCallback): void {
+ if (permission == PermissionConstants.PERMISSION_GROUP_NOTIFICATION) {
+ let enabled = notificationManager.isNotificationEnabledSync();
+ if (enabled) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ } else {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
+ }
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_BLUETOOTH) {
+ this.checkBluetoothPermissionStatus(successCallback);
+ return;
+ }
+ PermissionUtils.getManifestNames(permission, (names: ArrayList) => {
+ if (names == null || names == undefined) {
+ Log.d(PermissionConstants.LOG_TAG, "No specific permissions needed for: " + permission);
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ return;
+ }
+ if (names.length == 0) {
+ Log.d(PermissionConstants.LOG_TAG, "No permissions found in manifest for: " + names + permission);
+ if (permission == PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ return;
+ }
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
+ return;
+ }
+ for (let name of names) {
+ if (permission == PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_SYSTEM_ALERT_WINDOW) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_REQUEST_INSTALL_PACKAGES) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ return;
+ }
+ if (this.tokenId == null || this.tokenId == undefined) {
+ let bundleInfo = bundleManager.getBundleInfoForSelfSync(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
+ this.tokenId = bundleInfo.appInfo.accessTokenId;
+ }
+ let status: abilityAccessCtrl.GrantStatus = this.atManager.verifyAccessTokenSync(this.tokenId, name as Permissions);
+ if (status != abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
+ return;
+ }
+ }
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ });
+ }
+
+ requestPermissions(permissions: ArrayList, ability: UIAbility,
+ successCallback: RequestPermissionsSuccessCallback, errorCallback: ErrorCallback ): void {
+ if (this.ongoing) {
+ errorCallback.onError( "PermissionHandler.PermissionManager",
+ "A request for permissions is already running, please wait for it to finish before doing another request (note that you can request multiple permissions at the same time).");
+ return;
+ }
+ if (ability == null) {
+ Log.d(PermissionConstants.LOG_TAG, "Unable to detect current Activity.");
+ errorCallback.onError(
+ "PermissionHandler.PermissionManager",
+ "Unable to detect current Ohos Activity.");
+ return;
+ }
+ this.successCallback = successCallback;
+ this.ability = ability;
+ this.requestResults = new Map();
+ this.getPermissionToRequest(permissions, (permissionsToRequest: ESObject) => {
+ if (permissionsToRequest?.length > 0) {
+ try {
+ this.atManager.requestPermissionsFromUser(ability.context, permissionsToRequest.convertToArray(), (error, result) => {
+ this.ongoing = false;
+ let grant: Array = result.authResults;
+ let permissionNames: Array = result.permissions;
+ // Calendar permissions are split between WRITE and READ in Android, and split between WRITE
+ // and FULL ACCESS in the plugin. We need special logic for this translation.
+ let calendarWriteIndex: number = permissionNames.indexOf('ohos.permission.WRITE_CALENDAR');
+ // WRITE -> WRITE.
+ if (calendarWriteIndex >= 0) {
+ let authResult: number = grant[calendarWriteIndex];
+ let writeStatus: number = PermissionUtils.toPermissionStatus(authResult);
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_CALENDAR_WRITE_ONLY, writeStatus);
+
+ // WRITE + READ -> FULL ACCESS.
+ let calendarReadIndex: number = permissionNames.indexOf('ohos.permission.READ_CALENDAR');
+ if (calendarReadIndex >= 0) {
+ let readGrantResult: number = grant[calendarReadIndex];
+ let readStatus: number = PermissionUtils.toPermissionStatus(readGrantResult);
+ let fullAccessStatus = PermissionUtils.strictestStatusFromTwo(writeStatus, readStatus);
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_CALENDAR_FULL_ACCESS, fullAccessStatus);
+ // Support deprecated CALENDAR permission.
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_CALENDAR, fullAccessStatus);
+ }
+ }
+
+ for (let i = 0; i < permissionNames.length; i++) {
+ let permissionName: string = permissionNames[i];
+ let authResult: number = grant[i];
+ let permission: number = PermissionUtils.parseOhosName(permissionName);
+ // WRITE_CALENDAR and READ_CALENDAR permission results have already been handled.
+ if ((permissionName == 'ohos.permission.WRITE_CALENDAR') || (permissionName == 'ohos.permission.READ_CALENDAR')) {
+ continue;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_UNKNOWN)
+ continue;
+ if (permission == PermissionConstants.PERMISSION_GROUP_NOTIFICATION) {
+ notificationManager.requestEnableNotification(this.ability?.context).then(() => {
+ let enabled = notificationManager.isNotificationEnabledSync();
+ if (enabled) {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_NOTIFICATION, PermissionConstants.PERMISSION_STATUS_GRANTED);
+ } else {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_NOTIFICATION, PermissionConstants.PERMISSION_STATUS_DENIED);
+ }
+ this.successCallback?.onSuccess(this.requestResults as Map);
+ }).catch((err: BusinessError) => {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_NOTIFICATION, PermissionConstants.PERMISSION_STATUS_DENIED);
+ this.successCallback?.onSuccess(this.requestResults as Map);
+ });
+ return;
+ } else if (permission == PermissionConstants.PERMISSION_GROUP_MICROPHONE) {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_MICROPHONE, PermissionUtils.toPermissionStatus(authResult));
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_SPEECH, PermissionUtils.toPermissionStatus(authResult));
+ } else if (permission == PermissionConstants.PERMISSION_GROUP_LOCATION_ALWAYS) {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_LOCATION_ALWAYS, PermissionUtils.toPermissionStatus(authResult));
+ } else if (permission == PermissionConstants.PERMISSION_GROUP_LOCATION) {
+
+ if (permissionName == 'ohos.permission.APPROXIMATELY_LOCATION') {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_LOCATION_WHEN_IN_USE, PermissionUtils.toPermissionStatus(authResult));
+ }
+ if (permissionName == 'ohos.permission.LOCATION') {
+ this.requestResults?.set(PermissionConstants.PERMISSION_GROUP_LOCATION, PermissionUtils.toPermissionStatus(authResult));
+ }
+
+ } else {
+ this.requestResults?.set(permission, PermissionUtils.toPermissionStatus(authResult));
+ }
+ PermissionUtils.updatePermissionShouldShowStatus(permission);
+ }
+ this.successCallback?.onSuccess(this.requestResults as Map);
+ });
+ } catch (error) {
+ this.ongoing = false;
+ this.successCallback?.onSuccess(this.requestResults as Map);
+ }
+ } else {
+ this.ongoing = false;
+ this.successCallback?.onSuccess(this.requestResults as Map);
+ }
+ });
+ }
+
+ private getPermissionToRequest(permissions: ArrayList, callback: Callback>): void {
+ let permissionsToRequest: ArrayList = new ArrayList();
+ let size: number = permissions.length;
+ for (let permission of permissions) {
+ this.determinePermissionStatus(permission, {
+ onSuccess : (permissionStatus:ESObject) => {
+ if (permissionStatus == PermissionConstants.PERMISSION_STATUS_GRANTED) {
+ if (!this.requestResults?.has(permission)) {
+ this.requestResults?.set(permission, PermissionConstants.PERMISSION_STATUS_GRANTED);
+ }
+ size -= 1;
+ if (size == 0) {
+ callback(permissionsToRequest);
+ }
+ return;
+ }
+ PermissionUtils.getManifestNames(permission, (names:ArrayList) => {
+ if (names == null || names.length == 0) {
+ if (this.requestResults && !this.requestResults.has(permission)) {
+ if (permission == PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS) {
+ this.requestResults.set(permission, PermissionConstants.PERMISSION_STATUS_DENIED);
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE) {
+ this.requestResults.set(permission, PermissionConstants.PERMISSION_STATUS_GRANTED);
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_SYSTEM_ALERT_WINDOW) {
+ this.requestResults.set(permission, PermissionConstants.PERMISSION_STATUS_GRANTED);
+ }
+ }
+ size -= 1;
+ if (size == 0) {
+ callback(permissionsToRequest);
+ }
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS) {
+ // don't support
+ } else if (permission == PermissionConstants.PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE) {
+ // don't support
+ } else if (permission == PermissionConstants.PERMISSION_GROUP_SYSTEM_ALERT_WINDOW) {
+ // don't support
+ } else {
+ for (let name of names) {
+ permissionsToRequest.add(name);
+ }
+ }
+ size -= 1;
+ if (size == 0) {
+ callback(permissionsToRequest);
+ }
+ });
+ }
+ } as ESObject);
+ }
+ }
+
+ private checkBluetoothPermissionStatus(successCallback: CheckPermissionSuccessCallback): void {
+ PermissionUtils.getManifestNames(PermissionConstants.PERMISSION_GROUP_BLUETOOTH, (permissions: ESObject) => {
+ let missingInManifest: boolean = permissions == null || permissions.isEmpty();
+ if (missingInManifest) {
+ Log.d(PermissionConstants.LOG_TAG, "Bluetooth permission missing in manifest");
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_DENIED);
+ } else {
+ successCallback.onSuccess(PermissionConstants.PERMISSION_STATUS_GRANTED);
+ }
+ });
+ }
+
+ private checkPermission(successCallback: CheckPermissionSuccessCallback, permissionName: Permissions): void {
+ if (this.tokenId == null || this.tokenId == undefined) {
+ bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION)
+ .then((bundleInfo)=> {
+ this.tokenId = bundleInfo.appInfo.accessTokenId;
+ successCallback.onSuccess(this.atManager.verifyAccessTokenSync(this.tokenId, permissionName));
+ });
+ } else {
+ successCallback.onSuccess(this.atManager.verifyAccessTokenSync(this.tokenId, permissionName));
+ }
+ }
+
+ shouldShowRequestPermissionRationale(permission: number,
+ callback: ShouldShowRequestPermissionRationaleSuccessCallback, errorCallback: ErrorCallback): void {
+ callback?.onSuccess(false);
+ }
+}
+
+export interface CheckPermissionSuccessCallback {
+ onSuccess(permissionStatus: number): void;
+}
+
+export interface RequestPermissionsSuccessCallback {
+ onSuccess(results: Map ) : void;
+}
+
+export interface ShouldShowRequestPermissionRationaleSuccessCallback {
+ onSuccess(shouldShowRequestPermissionRationale: boolean): void;
+}
+
diff --git a/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionUtils.ets b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionUtils.ets
new file mode 100644
index 0000000000000000000000000000000000000000..a4a77612e5bc974f0514d3dc34438230d140ed45
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/PermissionUtils.ets
@@ -0,0 +1,346 @@
+/*
+ * 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 bundleManager from '@ohos.bundle.bundleManager';
+import ArrayList from '@ohos.util.ArrayList';
+import { Callback } from '@ohos.base';
+import Log from '@ohos/flutter_ohos/src/main/ets/util/Log';
+import PermissionConstants from './PermissionConstants';
+import { PermissionRequestResult } from '@kit.AbilityKit';
+
+const TAG: string = 'PermissionUtils';
+
+export default class PermissionUtils {
+ static parseOhosName(permission: String): number {
+ switch (permission) {
+ case 'ohos.permission.WRITE_CALENDAR':
+ return PermissionConstants.PERMISSION_GROUP_CALENDAR_WRITE_ONLY;
+ case 'ohos.permission.WRITE_CALENDAR':
+ case 'ohos.permission.READ_CALENDAR':
+ return PermissionConstants.PERMISSION_GROUP_CALENDAR_FULL_ACCESS;
+ case 'ohos.permission.READ_CALENDAR':
+ case 'ohos.permission.WRITE_CALENDAR':
+ return PermissionConstants.PERMISSION_GROUP_CALENDAR;
+ case 'ohos.permission.CAMERA':
+ return PermissionConstants.PERMISSION_GROUP_CAMERA;
+ case 'ohos.permission.READ_CONTACTS':
+ case 'ohos.permission.WRITE_CONTACTS':
+ // case 'ohos.permission.GET_LOCAL_ACCOUNTS':
+ return PermissionConstants.PERMISSION_GROUP_CONTACTS;
+ case 'ohos.permission.LOCATION_IN_BACKGROUND':
+ return PermissionConstants.PERMISSION_GROUP_LOCATION_ALWAYS;
+ case 'ohos.permission.LOCATION':
+ case 'ohos.permission.APPROXIMATELY_LOCATION':
+ return PermissionConstants.PERMISSION_GROUP_LOCATION;
+ case 'ohos.permission.MICROPHONE':
+ return PermissionConstants.PERMISSION_GROUP_MICROPHONE;
+ case 'ohos.permission.SET_TELEPHONY_STATE':
+ case 'ohos.permission.GET_TELEPHONY_STATE':
+ case 'ohos.permission.PLACE_CALL':
+ case 'ohos.permission.ANSWER_CALL':
+ case 'ohos.permission.READ_CALL_LOG':
+ case 'ohos.permission.WRITE_CALL_LOG':
+ case 'ohos.permission.CONNECT_CELLULAR_CALL_SERVICE':
+ case 'ohos.permission.MANAGE_VOICEMAIL':
+ return PermissionConstants.PERMISSION_GROUP_PHONE;
+ case 'ohos.permission.READ_HEALTH_DATA':
+ return PermissionConstants.PERMISSION_GROUP_SENSORS;
+ case 'ohos.permission.RECEIVE_SMS':
+ case 'ohos.permission.RECEIVE_WAP_MESSAGES':
+ case 'ohos.permission.RECEIVE_MMS':
+ return PermissionConstants.PERMISSION_GROUP_SMS;
+ case 'ohos.permission.READ_EXTERNAL_STORAGE':
+ case 'ohos.permission.WRITE_EXTERNAL_STORAGE':
+ return PermissionConstants.PERMISSION_GROUP_STORAGE;
+ case 'ohos.permission.MEDIA_LOCATION':
+ return PermissionConstants.PERMISSION_GROUP_ACCESS_MEDIA_LOCATION;
+ case 'ohos.permission.ACTIVITY_MOTION':
+ return PermissionConstants.PERMISSION_GROUP_ACTIVITY_RECOGNITION;
+ case 'ohos.permission.MANAGE_EXTERNAL_STORAGE':
+ return PermissionConstants.PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE;
+ case 'ohos.permission.SYSTEM_ALERT_WINDOW':
+ return PermissionConstants.PERMISSION_GROUP_SYSTEM_ALERT_WINDOW;
+ case 'ohos.permission.INSTALL_BUNDLE':
+ return PermissionConstants.PERMISSION_GROUP_REQUEST_INSTALL_PACKAGES;
+ case 'ohos.permission.ACCESS_NOTIFICATION_POLICY':
+ return PermissionConstants.PERMISSION_GROUP_ACCESS_NOTIFICATION_POLICY;
+ case 'ohos.permission.USE_BLUETOOTH':
+ return PermissionConstants.PERMISSION_GROUP_BLUETOOTH_SCAN;
+ case 'ohos.permission.DISCOVER_BLUETOOTH':
+ return PermissionConstants.PERMISSION_GROUP_BLUETOOTH_ADVERTISE;
+ case 'ohos.permission.MANAGE_BLUETOOTH':
+ case 'ohos.permission.ACCESS_BLUETOOTH':
+ return PermissionConstants.PERMISSION_GROUP_BLUETOOTH_CONNECT;
+ case 'ohos.permission.NOTIFICATION_CONTROLLER':
+ return PermissionConstants.PERMISSION_GROUP_NOTIFICATION;
+ case 'ohos.permission.GET_WIFI_INFO':
+ case 'ohos.permission.SET_WIFI_INFO':
+ return PermissionConstants.PERMISSION_GROUP_NEARBY_WIFI_DEVICES;
+ case 'ohos.permission.READ_MEDIA':
+ return PermissionConstants.PERMISSION_GROUP_AUDIO;
+ case 'ohos.permission.READ_IMAGEVIDEO':
+ case 'ohos.permission.WRITE_IMAGEVIDEO':
+ return PermissionConstants.PERMISSION_GROUP_PHOTOS;
+ case 'ohos.permission.SCHEDULE_EXACT_ALARM':
+ return PermissionConstants.PERMISSION_GROUP_SCHEDULE_EXACT_ALARM;
+ default:
+ return PermissionConstants.PERMISSION_GROUP_UNKNOWN;
+ }
+ }
+
+ static hasPermissionInManifest(confirmedPermission: ArrayList, permission: string, callback: Callback): void {
+ try {
+ if (confirmedPermission != null) {
+ for (let confirmed of confirmedPermission) {
+ if (confirmed == permission) {
+ callback(true);
+ return;
+ }
+ }
+ }
+ bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION)
+ .then((bundleInfo) => {
+ for (let requestedPermission of bundleInfo.reqPermissionDetails) {
+ if (requestedPermission?.name == permission) {
+ callback(true);
+ return;
+ }
+ }
+ callback(false);
+ })
+ } catch (e) {
+ Log.i(TAG, 'hasPermissionInManifest exception : ' + e);
+ callback(false);
+ }
+ }
+
+ static getRequestPermission(permissions: ArrayList, callback: Callback>): void {
+ let permissionNames: ArrayList = new ArrayList();
+ try {
+ bundleManager.getBundleInfoForSelf(bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_REQUESTED_PERMISSION)
+ .then((bundleInfo) => {
+ for (let requestedPermission of bundleInfo.reqPermissionDetails) {
+ if (permissions.has(requestedPermission.name)) {
+ permissionNames.add(requestedPermission.name);
+ }
+ }
+ // 不用经过getBundleInfo校验直接返回进行授权因此直接使用permissions
+ callback(permissionNames);
+ })
+ } catch (e) {
+ Log.i(TAG, 'getRequestPermission exception : ' + e);
+ }
+ }
+
+ static getManifestNames(permission: number, callback: ESObject): void {
+ let permissionNames: ArrayList = new ArrayList();
+ switch (permission) {
+ case PermissionConstants.PERMISSION_GROUP_CALENDAR_WRITE_ONLY:
+ let calendarNamesWriteOnly: ArrayList = new ArrayList();
+ calendarNamesWriteOnly.add('ohos.permission.WRITE_CALENDAR');
+ PermissionUtils.getRequestPermission(calendarNamesWriteOnly, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_CALENDAR_FULL_ACCESS:
+ case PermissionConstants.PERMISSION_GROUP_CALENDAR:
+ let calendarNames: ArrayList = new ArrayList();
+ calendarNames.add('ohos.permission.READ_CALENDAR');
+ calendarNames.add('ohos.permission.WRITE_CALENDAR');
+ PermissionUtils.getRequestPermission(calendarNames, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_CAMERA:
+ PermissionUtils.hasPermissionInManifest(permissionNames, 'ohos.permission.CAMERA', (camera) => {
+ if (camera) {
+ permissionNames.add('ohos.permission.CAMERA');
+ }
+ callback(permissionNames);
+ });
+ break;
+ case PermissionConstants.PERMISSION_GROUP_CONTACTS:
+ let contracts: ArrayList = new ArrayList();
+ contracts.add('ohos.permission.READ_CONTACTS');
+ contracts.add('ohos.permission.WRITE_CONTACTS');
+ // contracts.add('ohos.permission.GET_LOCAL_ACCOUNTS');
+ callback(contracts);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_LOCATION_ALWAYS:
+ let location: ArrayList = new ArrayList();
+ location.add('ohos.permission.LOCATION_IN_BACKGROUND');
+ PermissionUtils.getRequestPermission(location, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_LOCATION_WHEN_IN_USE:
+ case PermissionConstants.PERMISSION_GROUP_LOCATION:
+ let locationGroup: ArrayList = new ArrayList();
+ locationGroup.add('ohos.permission.LOCATION');
+ locationGroup.add('ohos.permission.APPROXIMATELY_LOCATION');
+ PermissionUtils.getRequestPermission(locationGroup, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_SPEECH:
+ case PermissionConstants.PERMISSION_GROUP_MICROPHONE:
+ let microphone: ArrayList = new ArrayList();
+ microphone.add('ohos.permission.MICROPHONE');
+ PermissionUtils.getRequestPermission(microphone, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_PHONE:
+ let phone: ArrayList = new ArrayList();
+ phone.add('ohos.permission.SET_TELEPHONY_STATE');
+ phone.add('ohos.permission.GET_TELEPHONY_STATE');
+ phone.add('ohos.permission.PLACE_CALL');
+ phone.add('ohos.permission.ANSWER_CALL');
+ phone.add('ohos.permission.READ_CALL_LOG');
+ phone.add('ohos.permission.WRITE_CALL_LOG');
+ // phone.add('ohos.permission.CONNECT_CELLULAR_CALL_SERVICE');
+ phone.add('ohos.permission.MANAGE_VOICEMAIL');
+ callback(phone);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_SENSORS:
+ case PermissionConstants.PERMISSION_GROUP_SENSORS_ALWAYS:
+ let sensor: ArrayList = new ArrayList();
+ sensor.add('ohos.permission.READ_HEALTH_DATA');
+ callback(sensor);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_SMS:
+ let sms: ArrayList = new ArrayList();
+ sms.add('ohos.permission.RECEIVE_SMS');
+ sms.add('ohos.permission.RECEIVE_WAP_MESSAGES');
+ sms.add('ohos.permission.RECEIVE_MMS');
+ callback(sms);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_STORAGE:
+ callback(permissionNames);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS:
+ callback(permissionNames);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_ACCESS_MEDIA_LOCATION:
+ let mediaLocation: ArrayList = new ArrayList();
+ mediaLocation.add('ohos.permission.MEDIA_LOCATION');
+ PermissionUtils.getRequestPermission(mediaLocation, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_ACTIVITY_RECOGNITION:
+ let motion: ArrayList = new ArrayList();
+ motion.add('ohos.permission.ACTIVITY_MOTION');
+ callback(motion);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_BLUETOOTH:
+ let bluetooth: ArrayList = new ArrayList();
+ bluetooth.add('ohos.permission.ACCESS_BLUETOOTH');
+ PermissionUtils.getRequestPermission(bluetooth, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_MANAGE_EXTERNAL_STORAGE:
+ callback(permissionNames);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_SYSTEM_ALERT_WINDOW:
+ callback(permissionNames);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_REQUEST_INSTALL_PACKAGES:
+ let installBundle: ArrayList = new ArrayList();
+ installBundle.add('ohos.permission.INSTALL_BUNDLE');
+ callback(installBundle);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_ACCESS_NOTIFICATION_POLICY:
+ let policy: ArrayList = new ArrayList();
+ policy.add('ohos.permission.ACCESS_NOTIFICATION_POLICY');
+ callback(policy);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_BLUETOOTH_SCAN:
+ let bluetoothScan: ArrayList = new ArrayList();
+ bluetoothScan.add('ohos.permission.USE_BLUETOOTH');
+ callback(bluetoothScan);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_BLUETOOTH_ADVERTISE:
+ let bluetoothDiscover: ArrayList = new ArrayList();
+ bluetoothDiscover.add('ohos.permission.DISCOVER_BLUETOOTH');
+ callback(bluetoothDiscover);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_BLUETOOTH_CONNECT:
+ let bluetoothConnect: ArrayList = new ArrayList();
+ bluetoothConnect.add('ohos.permission.MANAGE_BLUETOOTH');
+ bluetoothConnect.add('ohos.permission.ACCESS_BLUETOOTH');
+ callback(bluetoothConnect);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_NOTIFICATION:
+ let postNotification: ArrayList = new ArrayList();
+ postNotification.add('ohos.permission.NOTIFICATION_CONTROLLER');
+ callback(postNotification);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_NEARBY_WIFI_DEVICES:
+ callback(permissionNames);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_PHOTOS:
+ case PermissionConstants.PERMISSION_GROUP_VIDEOS:
+ let photosVideos: ArrayList = new ArrayList();
+ photosVideos.add('ohos.permission.READ_IMAGEVIDEO');
+ photosVideos.add('ohos.permission.WRITE_IMAGEVIDEO');
+ PermissionUtils.getRequestPermission(photosVideos, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_AUDIO:
+ let media: ArrayList = new ArrayList();
+ media.add('ohos.permission.READ_MEDIA');
+ PermissionUtils.getRequestPermission(media, callback);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_SCHEDULE_EXACT_ALARM:
+ let exactAlarm: ArrayList = new ArrayList();
+ exactAlarm.add('ohos.permission.SCHEDULE_EXACT_ALARM');
+ callback(permissionNames);
+ break;
+ case PermissionConstants.PERMISSION_GROUP_MEDIA_LIBRARY:
+ case PermissionConstants.PERMISSION_GROUP_REMINDERS:
+ case PermissionConstants.PERMISSION_GROUP_UNKNOWN:
+ callback(null);
+ break;
+ default:
+ callback(permissionNames);
+ break;
+ }
+ }
+
+ static toPermissionStatus(authResult: number): number {
+ if (authResult == -1 || authResult == 2) {
+ return PermissionConstants.PERMISSION_STATUS_DENIED;
+ }
+ return PermissionConstants.PERMISSION_STATUS_GRANTED;
+ }
+
+ static updatePermissionShouldShowStatus(permission: number): void {
+ }
+
+ static strictestStatus(statuses: Set): number {
+ if (statuses.has(PermissionConstants.PERMISSION_STATUS_NEVER_ASK_AGAIN)) {
+ return PermissionConstants.PERMISSION_STATUS_NEVER_ASK_AGAIN;
+ }
+ if (statuses.has(PermissionConstants.PERMISSION_STATUS_RESTRICTED)) {
+ return PermissionConstants.PERMISSION_STATUS_RESTRICTED;
+ }
+ if (statuses.has(PermissionConstants.PERMISSION_STATUS_DENIED)) {
+ return PermissionConstants.PERMISSION_STATUS_DENIED;
+ }
+ if (statuses.has(PermissionConstants.PERMISSION_STATUS_LIMITED)) {
+ return PermissionConstants.PERMISSION_STATUS_LIMITED;
+ }
+ return PermissionConstants.PERMISSION_STATUS_GRANTED;
+ }
+
+ static strictestStatusFromTwo(statusA?: PermissionConstants, statusB?: PermissionConstants): number {
+ const statuses = new Set();
+ if (statusA !== undefined) {
+ statuses.add(statusA);
+ }
+ if (statusB !== undefined) {
+ statuses.add(statusB);
+ }
+ return PermissionUtils.strictestStatus(statuses);
+ }
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/ServiceManager.ets b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/ServiceManager.ets
new file mode 100644
index 0000000000000000000000000000000000000000..9983699871cf5755195fdfcf878931483be2d20c
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/ets/com/baseflow/permissionhandler/ServiceManager.ets
@@ -0,0 +1,85 @@
+/*
+ * 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 common from '@ohos.app.ability.common';
+import { ErrorCallback } from './ErrorCallback';
+import PermissionConstants from './PermissionConstants';
+import locationManager from '@ohos.geoLocationManager';
+import bluetoothManager from '@ohos.bluetoothManager';
+import sim from '@ohos.telephony.sim';
+
+export class ServiceManager {
+ checkServiceStatus(permission: number, context: common.Context,
+ successCallback: SuccessCallback, errorCallback: ErrorCallback): void {
+ if (permission == PermissionConstants.PERMISSION_GROUP_LOCATION ||
+ permission == PermissionConstants.PERMISSION_GROUP_LOCATION_ALWAYS ||
+ permission == PermissionConstants.PERMISSION_GROUP_LOCATION_WHEN_IN_USE) {
+ successCallback.onSuccess(this.isLocationServiceEnable()
+ ? PermissionConstants.SERVICE_STATUS_ENABLED : PermissionConstants.SERVICE_STATUS_DISABLED);
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_BLUETOOTH) {
+ successCallback.onSuccess(this.isBluetoothServiceEnable()
+ ? PermissionConstants.SERVICE_STATUS_ENABLED : PermissionConstants.SERVICE_STATUS_DISABLED);
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_PHONE) {
+ try {
+ sim.getSimState(0).then((state) => {
+ if (state == sim.SimState.SIM_STATE_READY) {
+ successCallback.onSuccess(PermissionConstants.SERVICE_STATUS_ENABLED);
+ return;
+ }
+ sim.getSimState(1).then((stateSimTwo) => {
+ if (stateSimTwo == sim.SimState.SIM_STATE_READY) {
+ successCallback.onSuccess(PermissionConstants.SERVICE_STATUS_ENABLED);
+ return;
+ }
+ successCallback.onSuccess(PermissionConstants.SERVICE_STATUS_DISABLED);
+ });
+ });
+ } catch (error) {
+ successCallback.onSuccess(PermissionConstants.SERVICE_STATUS_DISABLED);
+ }
+ return;
+ }
+ if (permission == PermissionConstants.PERMISSION_GROUP_IGNORE_BATTERY_OPTIMIZATIONS) {
+ successCallback.onSuccess(PermissionConstants.SERVICE_STATUS_DISABLED);
+ return;
+ }
+ successCallback.onSuccess(PermissionConstants.SERVICE_STATUS_NOT_APPLICABLE);
+ }
+
+ private isLocationServiceEnable(): boolean {
+ try {
+ return locationManager.isLocationEnabled();
+ } catch (error) {
+ return false;
+ }
+ }
+
+ private isBluetoothServiceEnable(): boolean {
+ try {
+ return bluetoothManager.getState() == bluetoothManager.BluetoothState.STATE_ON;
+ } catch (error) {
+ return false;
+ }
+ }
+}
+
+export interface SuccessCallback {
+ onSuccess(serviceStatus: number): void;
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/module.json5 b/permission_handler_ohos/ohos/src/main/module.json5
new file mode 100644
index 0000000000000000000000000000000000000000..fe2c21ee331547585cd9f5daf83ad9eb4f78ccf7
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/module.json5
@@ -0,0 +1,25 @@
+/*
+* Copyright (c) 2023 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.
+*/
+
+{
+ "module": {
+ "name": "permission_handler_ohos",
+ "type": "har",
+ "deviceTypes": [
+ "phone",
+ "tablet"
+ ],
+ }
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/resources/base/element/color.json b/permission_handler_ohos/ohos/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..3c712962da3c2751c2b9ddb53559afcbd2b54a02
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "start_window_background",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/resources/base/element/string.json b/permission_handler_ohos/ohos/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..873ab82052a1996280005200b7dc1883c0c123f3
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "PermissionhandlerAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "PermissionhandlerAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/resources/base/media/icon.png b/permission_handler_ohos/ohos/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/permission_handler_ohos/ohos/src/main/resources/base/media/icon.png differ
diff --git a/permission_handler_ohos/ohos/src/main/resources/base/profile/main_pages.json b/permission_handler_ohos/ohos/src/main/resources/base/profile/main_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..1898d94f58d6128ab712be2c68acc7c98e9ab9ce
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/resources/base/profile/main_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "pages/Index"
+ ]
+}
diff --git a/permission_handler_ohos/ohos/src/main/resources/en_US/element/string.json b/permission_handler_ohos/ohos/src/main/resources/en_US/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..873ab82052a1996280005200b7dc1883c0c123f3
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/resources/en_US/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "module description"
+ },
+ {
+ "name": "PermissionhandlerAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "PermissionhandlerAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/main/resources/zh_CN/element/string.json b/permission_handler_ohos/ohos/src/main/resources/zh_CN/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..602d4f1d86041f786b089100db594b118df4aa8c
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/main/resources/zh_CN/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "module_desc",
+ "value": "模块描述"
+ },
+ {
+ "name": "PermissionhandlerAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "PermissionhandlerAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/test/List.test.ets b/permission_handler_ohos/ohos/src/test/List.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..0db841ed9cff9fdea904b802e68d01f1d9b2b36a
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/test/List.test.ets
@@ -0,0 +1,20 @@
+/*
+* Copyright (c) 2023 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 localUnitTest from './LocalUnit.test';
+
+export default function testsuite() {
+ localUnitTest()
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/ohos/src/test/LocalUnit.test.ets b/permission_handler_ohos/ohos/src/test/LocalUnit.test.ets
new file mode 100644
index 0000000000000000000000000000000000000000..f3517276bcfc5453175c8f9b532d32b71e7d0e76
--- /dev/null
+++ b/permission_handler_ohos/ohos/src/test/LocalUnit.test.ets
@@ -0,0 +1,48 @@
+/*
+* Copyright (c) 2023 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 { describe, beforeAll, beforeEach, afterEach, afterAll, it, expect } from '@ohos/hypium';
+
+export default function localUnitTest() {
+ describe('localUnitTest', function () {
+ // Defines a test suite. Two parameters are supported: test suite name and test suite function.
+ beforeAll(function () {
+ // Presets an action, which is performed only once before all test cases of the test suite start.
+ // This API supports only one parameter: preset action function.
+ });
+ beforeEach(function () {
+ // Presets an action, which is performed before each unit test case starts.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: preset action function.
+ });
+ afterEach(function () {
+ // Presets a clear action, which is performed after each unit test case ends.
+ // The number of execution times is the same as the number of test cases defined by **it**.
+ // This API supports only one parameter: clear action function.
+ });
+ afterAll(function () {
+ // Presets a clear action, which is performed after all test cases of the test suite end.
+ // This API supports only one parameter: clear action function.
+ });
+ it('assertContain', 0, function () {
+ // Defines a test case. This API supports three parameters: test case name, filter parameter, and test case function.
+ let a = 'abc';
+ let b = 'b';
+ // Defines a variety of assertion methods, which are used to declare expected boolean conditions.
+ expect(a).assertContain(b);
+ expect(a).assertEqual(a);
+ });
+ });
+}
\ No newline at end of file
diff --git a/permission_handler_ohos/pubspec.yaml b/permission_handler_ohos/pubspec.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..df485b4c7ba24138de18479388b165e952ea84d8
--- /dev/null
+++ b/permission_handler_ohos/pubspec.yaml
@@ -0,0 +1,38 @@
+# Copyright (c) 2023 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.
+
+name: permission_handler_ohos
+description: Permission plugin for Flutter. This plugin provides the Ohos API to request and check permissions.
+homepage: https://gitee.com/openharmony-sig/flutter_permission_handler
+version: 10.3.2
+
+environment:
+ sdk: ">=2.15.0 <4.0.0"
+ flutter: ">=2.8.0"
+
+flutter:
+ plugin:
+ implements: permission_handler
+ platforms:
+ ohos:
+ package: com.baseflow.permissionhandler
+ pluginClass: PermissionHandlerPlugin
+
+dependencies:
+ flutter:
+ sdk: flutter
+ permission_handler_platform_interface: ^4.2.0
+
+dev_dependencies:
+ flutter_lints: ^1.0.4
+ plugin_platform_interface: ^2.0.0