@capgo/camera-preview 7.21.10 → 7.22.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -308,6 +308,8 @@ Documentation for the [uploader](https://github.com/Cap-go/capacitor-uploader)
308
308
  * [`getAspectRatio()`](#getaspectratio)
309
309
  * [`setGridMode(...)`](#setgridmode)
310
310
  * [`getGridMode()`](#getgridmode)
311
+ * [`checkPermissions(...)`](#checkpermissions)
312
+ * [`requestPermissions(...)`](#requestpermissions)
311
313
  * [`getHorizontalFov()`](#gethorizontalfov)
312
314
  * [`getSupportedPictureSizes()`](#getsupportedpicturesizes)
313
315
  * [`setFlashMode(...)`](#setflashmode)
@@ -503,6 +505,46 @@ Gets the current grid mode of the camera preview overlay.
503
505
  --------------------
504
506
 
505
507
 
508
+ ### checkPermissions(...)
509
+
510
+ ```typescript
511
+ checkPermissions(options?: Pick<PermissionRequestOptions, "disableAudio"> | undefined) => Promise<CameraPermissionStatus>
512
+ ```
513
+
514
+ Checks the current camera (and optionally microphone) permission status without prompting the system dialog.
515
+
516
+ | Param | Type | Description |
517
+ | ------------- | ----------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
518
+ | **`options`** | <code><a href="#pick">Pick</a>&lt;<a href="#permissionrequestoptions">PermissionRequestOptions</a>, 'disableAudio'&gt;</code> | Set `disableAudio` to `false` to also include microphone status (defaults to `true`). |
519
+
520
+ **Returns:** <code>Promise&lt;<a href="#camerapermissionstatus">CameraPermissionStatus</a>&gt;</code>
521
+
522
+ **Since:** 8.7.0
523
+
524
+ --------------------
525
+
526
+
527
+ ### requestPermissions(...)
528
+
529
+ ```typescript
530
+ requestPermissions(options?: PermissionRequestOptions | undefined) => Promise<CameraPermissionStatus>
531
+ ```
532
+
533
+ Requests camera (and optional microphone) permissions. If permissions are already granted or denied,
534
+ the current status is returned without prompting. When `showSettingsAlert` is true and permissions are denied,
535
+ a platform specific alert guiding the user to the app settings will be presented.
536
+
537
+ | Param | Type | Description |
538
+ | ------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------- |
539
+ | **`options`** | <code><a href="#permissionrequestoptions">PermissionRequestOptions</a></code> | - Configuration for the permission request behaviour. |
540
+
541
+ **Returns:** <code>Promise&lt;<a href="#camerapermissionstatus">CameraPermissionStatus</a>&gt;</code>
542
+
543
+ **Since:** 8.7.0
544
+
545
+ --------------------
546
+
547
+
506
548
  ### getHorizontalFov()
507
549
 
508
550
  ```typescript
@@ -1050,6 +1092,26 @@ Defines the options for capturing a sample frame from the camera preview.
1050
1092
  | **`quality`** | <code>number</code> | The quality of the captured sample, from 0 to 100. | <code>85</code> |
1051
1093
 
1052
1094
 
1095
+ #### CameraPermissionStatus
1096
+
1097
+ | Prop | Type |
1098
+ | ---------------- | ----------------------------------------------------------- |
1099
+ | **`camera`** | <code><a href="#permissionstate">PermissionState</a></code> |
1100
+ | **`microphone`** | <code><a href="#permissionstate">PermissionState</a></code> |
1101
+
1102
+
1103
+ #### PermissionRequestOptions
1104
+
1105
+ | Prop | Type |
1106
+ | ----------------------------- | -------------------- |
1107
+ | **`disableAudio`** | <code>boolean</code> |
1108
+ | **`showSettingsAlert`** | <code>boolean</code> |
1109
+ | **`title`** | <code>string</code> |
1110
+ | **`message`** | <code>string</code> |
1111
+ | **`openSettingsButtonTitle`** | <code>string</code> |
1112
+ | **`cancelButtonTitle`** | <code>string</code> |
1113
+
1114
+
1053
1115
  #### SupportedPictureSizes
1054
1116
 
1055
1117
  Represents the supported picture sizes for a camera facing a certain direction.
@@ -1170,6 +1232,18 @@ The available flash modes for the camera.
1170
1232
  <code>"off" | "on" | "auto" | "torch"</code>
1171
1233
 
1172
1234
 
1235
+ #### PermissionState
1236
+
1237
+ <code>'prompt' | 'prompt-with-rationale' | 'granted' | 'denied'</code>
1238
+
1239
+
1240
+ #### Pick
1241
+
1242
+ From T, pick a set of properties whose keys are in the union K
1243
+
1244
+ <code>{
1173
1245
  [P in K]: T[P];
1174
1246
  }</code>
1247
+
1248
+
1175
1249
  #### FlashMode
1176
1250
 
1177
1251
  <code><a href="#camerapreviewflashmode">CameraPreviewFlashMode</a></code>
@@ -5,6 +5,8 @@ import static android.Manifest.permission.RECORD_AUDIO;
5
5
 
6
6
  import android.Manifest;
7
7
  import android.annotation.SuppressLint;
8
+ import android.app.Activity;
9
+ import android.content.Intent;
8
10
  import android.content.pm.ActivityInfo;
9
11
  import android.content.pm.PackageManager;
10
12
  import android.content.res.Configuration;
@@ -13,6 +15,7 @@ import android.graphics.drawable.ColorDrawable;
13
15
  import android.graphics.drawable.Drawable;
14
16
  import android.location.Location;
15
17
  import android.net.Uri;
18
+ import android.provider.Settings;
16
19
  import android.util.DisplayMetrics;
17
20
  import android.util.Log;
18
21
  import android.util.Size;
@@ -21,6 +24,7 @@ import android.view.View;
21
24
  import android.view.ViewGroup;
22
25
  import android.webkit.WebView;
23
26
  import androidx.annotation.RequiresPermission;
27
+ import androidx.appcompat.app.AlertDialog;
24
28
  import androidx.core.app.ActivityCompat;
25
29
  import androidx.core.graphics.Insets;
26
30
  import androidx.core.view.ViewCompat;
@@ -63,6 +67,10 @@ import org.json.JSONObject;
63
67
  },
64
68
  alias = CameraPreview.CAMERA_WITH_LOCATION_PERMISSION_ALIAS
65
69
  ),
70
+ @Permission(
71
+ strings = { RECORD_AUDIO },
72
+ alias = CameraPreview.MICROPHONE_ONLY_PERMISSION_ALIAS
73
+ ),
66
74
  }
67
75
  )
68
76
  public class CameraPreview
@@ -110,6 +118,7 @@ public class CameraPreview
110
118
  static final String CAMERA_ONLY_PERMISSION_ALIAS = "cameraOnly";
111
119
  static final String CAMERA_WITH_LOCATION_PERMISSION_ALIAS =
112
120
  "cameraWithLocation";
121
+ static final String MICROPHONE_ONLY_PERMISSION_ALIAS = "microphoneOnly";
113
122
 
114
123
  private String captureCallbackId = "";
115
124
  private String sampleCallbackId = "";
@@ -127,6 +136,7 @@ public class CameraPreview
127
136
  private String lastOrientationStr = "unknown";
128
137
  private boolean lastDisableAudio = true;
129
138
  private Drawable originalWindowBackground;
139
+ private boolean isCameraPermissionDialogShowing = false;
130
140
 
131
141
  @PluginMethod
132
142
  public void getExposureModes(PluginCall call) {
@@ -738,6 +748,207 @@ public class CameraPreview
738
748
  call.resolve(jsObject);
739
749
  }
740
750
 
751
+ private void showCameraPermissionDialog(
752
+ String title,
753
+ String message,
754
+ String openSettingsText,
755
+ String cancelText,
756
+ Runnable completion
757
+ ) {
758
+ Activity activity = getActivity();
759
+ if (activity == null) {
760
+ if (completion != null) {
761
+ completion.run();
762
+ }
763
+ return;
764
+ }
765
+
766
+ activity.runOnUiThread(() -> {
767
+ if (activity.isFinishing()) {
768
+ if (completion != null) {
769
+ completion.run();
770
+ }
771
+ return;
772
+ }
773
+
774
+ if (isCameraPermissionDialogShowing) {
775
+ if (completion != null) {
776
+ completion.run();
777
+ }
778
+ return;
779
+ }
780
+
781
+ AlertDialog dialog = new AlertDialog.Builder(activity)
782
+ .setTitle(title)
783
+ .setMessage(message)
784
+ .setNegativeButton(cancelText, (d, which) -> {
785
+ d.dismiss();
786
+ isCameraPermissionDialogShowing = false;
787
+ })
788
+ .setPositiveButton(openSettingsText, (d, which) -> {
789
+ Intent intent = new Intent(
790
+ Settings.ACTION_APPLICATION_DETAILS_SETTINGS
791
+ );
792
+ Uri uri = Uri.fromParts("package", activity.getPackageName(), null);
793
+ intent.setData(uri);
794
+ activity.startActivity(intent);
795
+ isCameraPermissionDialogShowing = false;
796
+ })
797
+ .setOnDismissListener(d -> isCameraPermissionDialogShowing = false)
798
+ .create();
799
+
800
+ isCameraPermissionDialogShowing = true;
801
+ dialog.show();
802
+ if (completion != null) {
803
+ completion.run();
804
+ }
805
+ });
806
+ }
807
+
808
+ private String mapPermissionState(PermissionState state) {
809
+ if (state == null) {
810
+ return PermissionState.PROMPT.toString();
811
+ }
812
+
813
+ return state.toString();
814
+ }
815
+
816
+ @PluginMethod
817
+ public void checkPermissions(PluginCall call) {
818
+ boolean disableAudio = call.getBoolean("disableAudio") != null
819
+ ? Boolean.TRUE.equals(call.getBoolean("disableAudio"))
820
+ : true;
821
+
822
+ PermissionState cameraState = getPermissionState(
823
+ CAMERA_ONLY_PERMISSION_ALIAS
824
+ );
825
+
826
+ JSObject result = new JSObject();
827
+ result.put("camera", mapPermissionState(cameraState));
828
+
829
+ if (!disableAudio) {
830
+ PermissionState audioState = getPermissionState(
831
+ MICROPHONE_ONLY_PERMISSION_ALIAS
832
+ );
833
+ result.put("microphone", mapPermissionState(audioState));
834
+ }
835
+
836
+ call.resolve(result);
837
+ }
838
+
839
+ @Override
840
+ @PluginMethod
841
+ public void requestPermissions(PluginCall call) {
842
+ Boolean disableAudioOption = call.getBoolean("disableAudio");
843
+ boolean disableAudio = disableAudioOption == null
844
+ ? true
845
+ : Boolean.TRUE.equals(disableAudioOption);
846
+ this.lastDisableAudio = disableAudio;
847
+
848
+ String permissionAlias = disableAudio
849
+ ? CAMERA_ONLY_PERMISSION_ALIAS
850
+ : CAMERA_WITH_AUDIO_PERMISSION_ALIAS;
851
+
852
+ boolean cameraGranted = PermissionState.GRANTED.equals(
853
+ getPermissionState(CAMERA_ONLY_PERMISSION_ALIAS)
854
+ );
855
+ boolean audioGranted =
856
+ disableAudio ||
857
+ PermissionState.GRANTED.equals(
858
+ getPermissionState(MICROPHONE_ONLY_PERMISSION_ALIAS)
859
+ );
860
+
861
+ if (cameraGranted && audioGranted) {
862
+ JSObject result = new JSObject();
863
+ result.put("camera", mapPermissionState(PermissionState.GRANTED));
864
+ if (!disableAudio) {
865
+ result.put("microphone", mapPermissionState(PermissionState.GRANTED));
866
+ }
867
+ call.resolve(result);
868
+ return;
869
+ }
870
+
871
+ requestPermissionForAlias(
872
+ permissionAlias,
873
+ call,
874
+ "handleRequestPermissionsResult"
875
+ );
876
+ }
877
+
878
+ @PermissionCallback
879
+ private void handleRequestPermissionsResult(PluginCall call) {
880
+ Boolean disableAudioOption = call.getBoolean("disableAudio");
881
+ boolean disableAudio = disableAudioOption == null
882
+ ? true
883
+ : Boolean.TRUE.equals(disableAudioOption);
884
+ this.lastDisableAudio = disableAudio;
885
+
886
+ PermissionState cameraState = getPermissionState(
887
+ CAMERA_ONLY_PERMISSION_ALIAS
888
+ );
889
+ JSObject result = new JSObject();
890
+ result.put("camera", mapPermissionState(cameraState));
891
+
892
+ if (!disableAudio) {
893
+ PermissionState audioState = getPermissionState(
894
+ CAMERA_WITH_AUDIO_PERMISSION_ALIAS
895
+ );
896
+ result.put("microphone", mapPermissionState(audioState));
897
+ }
898
+
899
+ boolean showSettingsAlert = call.getBoolean("showSettingsAlert") != null
900
+ ? Boolean.TRUE.equals(call.getBoolean("showSettingsAlert"))
901
+ : false;
902
+
903
+ String cameraStateString = result.getString("camera");
904
+ boolean cameraNeedsSettings =
905
+ "denied".equals(cameraStateString) ||
906
+ "prompt-with-rationale".equals(cameraStateString);
907
+
908
+ boolean microphoneNeedsSettings = false;
909
+ if (result.has("microphone")) {
910
+ String micStateString = result.getString("microphone");
911
+ microphoneNeedsSettings =
912
+ "denied".equals(micStateString) ||
913
+ "prompt-with-rationale".equals(micStateString);
914
+ }
915
+
916
+ boolean shouldShowAlert =
917
+ showSettingsAlert && (cameraNeedsSettings || microphoneNeedsSettings);
918
+
919
+ if (shouldShowAlert) {
920
+ Activity activity = getActivity();
921
+ if (activity == null) {
922
+ call.resolve(result);
923
+ return;
924
+ }
925
+
926
+ String title = call.getString("title", "Camera Permission Needed");
927
+ String message = call.getString(
928
+ "message",
929
+ "Enable camera access in Settings to use the preview."
930
+ );
931
+ String openSettingsText = call.getString(
932
+ "openSettingsButtonTitle",
933
+ "Open Settings"
934
+ );
935
+ String cancelText = call.getString(
936
+ "cancelButtonTitle",
937
+ activity.getString(android.R.string.cancel)
938
+ );
939
+
940
+ showCameraPermissionDialog(
941
+ title,
942
+ message,
943
+ openSettingsText,
944
+ cancelText,
945
+ () -> call.resolve(result)
946
+ );
947
+ } else {
948
+ call.resolve(result);
949
+ }
950
+ }
951
+
741
952
  @PermissionCallback
742
953
  private void handleCameraPermissionResult(PluginCall call) {
743
954
  if (
@@ -750,7 +961,10 @@ public class CameraPreview
750
961
  ) {
751
962
  startCamera(call);
752
963
  } else {
753
- call.reject("Permission failed");
964
+ call.reject(
965
+ "camera permission denied. enable camera access in Settings.",
966
+ "cameraPermissionDenied"
967
+ );
754
968
  }
755
969
  }
756
970
 
@@ -2016,6 +2230,7 @@ public class CameraPreview
2016
2230
  boolean disableAudio = call.getBoolean("disableAudio") != null
2017
2231
  ? Boolean.TRUE.equals(call.getBoolean("disableAudio"))
2018
2232
  : this.lastDisableAudio;
2233
+ this.lastDisableAudio = disableAudio;
2019
2234
  String permissionAlias = disableAudio
2020
2235
  ? CAMERA_ONLY_PERMISSION_ALIAS
2021
2236
  : CAMERA_WITH_AUDIO_PERMISSION_ALIAS;
@@ -2097,7 +2312,10 @@ public class CameraPreview
2097
2312
  call.reject("Failed to start video recording: " + e.getMessage());
2098
2313
  }
2099
2314
  } else {
2100
- call.reject("Permission denied for video recording");
2315
+ call.reject(
2316
+ "camera permission denied. enable camera access in Settings.",
2317
+ "cameraPermissionDenied"
2318
+ );
2101
2319
  }
2102
2320
  }
2103
2321
 
package/dist/docs.json CHANGED
@@ -247,6 +247,71 @@
247
247
  ],
248
248
  "slug": "getgridmode"
249
249
  },
250
+ {
251
+ "name": "checkPermissions",
252
+ "signature": "(options?: Pick<PermissionRequestOptions, \"disableAudio\"> | undefined) => Promise<CameraPermissionStatus>",
253
+ "parameters": [
254
+ {
255
+ "name": "options",
256
+ "docs": "Set `disableAudio` to `false` to also include microphone status (defaults to `true`).",
257
+ "type": "Pick<PermissionRequestOptions, 'disableAudio'> | undefined"
258
+ }
259
+ ],
260
+ "returns": "Promise<CameraPermissionStatus>",
261
+ "tags": [
262
+ {
263
+ "name": "param",
264
+ "text": "options Set `disableAudio` to `false` to also include microphone status (defaults to `true`)."
265
+ },
266
+ {
267
+ "name": "returns",
268
+ "text": "A promise resolving to the current authorization states."
269
+ },
270
+ {
271
+ "name": "since",
272
+ "text": "8.7.0"
273
+ }
274
+ ],
275
+ "docs": "Checks the current camera (and optionally microphone) permission status without prompting the system dialog.",
276
+ "complexTypes": [
277
+ "CameraPermissionStatus",
278
+ "Pick",
279
+ "PermissionRequestOptions"
280
+ ],
281
+ "slug": "checkpermissions"
282
+ },
283
+ {
284
+ "name": "requestPermissions",
285
+ "signature": "(options?: PermissionRequestOptions | undefined) => Promise<CameraPermissionStatus>",
286
+ "parameters": [
287
+ {
288
+ "name": "options",
289
+ "docs": "- Configuration for the permission request behaviour.",
290
+ "type": "PermissionRequestOptions | undefined"
291
+ }
292
+ ],
293
+ "returns": "Promise<CameraPermissionStatus>",
294
+ "tags": [
295
+ {
296
+ "name": "param",
297
+ "text": "options - Configuration for the permission request behaviour."
298
+ },
299
+ {
300
+ "name": "returns",
301
+ "text": "A promise resolving to the final authorization states."
302
+ },
303
+ {
304
+ "name": "since",
305
+ "text": "8.7.0"
306
+ }
307
+ ],
308
+ "docs": "Requests camera (and optional microphone) permissions. If permissions are already granted or denied,\nthe current status is returned without prompting. When `showSettingsAlert` is true and permissions are denied,\na platform specific alert guiding the user to the app settings will be presented.",
309
+ "complexTypes": [
310
+ "CameraPermissionStatus",
311
+ "PermissionRequestOptions"
312
+ ],
313
+ "slug": "requestpermissions"
314
+ },
250
315
  {
251
316
  "name": "getHorizontalFov",
252
317
  "signature": "() => Promise<{ result: number; }>",
@@ -1504,6 +1569,84 @@
1504
1569
  }
1505
1570
  ]
1506
1571
  },
1572
+ {
1573
+ "name": "CameraPermissionStatus",
1574
+ "slug": "camerapermissionstatus",
1575
+ "docs": "",
1576
+ "tags": [],
1577
+ "methods": [],
1578
+ "properties": [
1579
+ {
1580
+ "name": "camera",
1581
+ "tags": [],
1582
+ "docs": "",
1583
+ "complexTypes": [
1584
+ "PermissionState"
1585
+ ],
1586
+ "type": "PermissionState"
1587
+ },
1588
+ {
1589
+ "name": "microphone",
1590
+ "tags": [],
1591
+ "docs": "",
1592
+ "complexTypes": [
1593
+ "PermissionState"
1594
+ ],
1595
+ "type": "PermissionState"
1596
+ }
1597
+ ]
1598
+ },
1599
+ {
1600
+ "name": "PermissionRequestOptions",
1601
+ "slug": "permissionrequestoptions",
1602
+ "docs": "",
1603
+ "tags": [],
1604
+ "methods": [],
1605
+ "properties": [
1606
+ {
1607
+ "name": "disableAudio",
1608
+ "tags": [],
1609
+ "docs": "",
1610
+ "complexTypes": [],
1611
+ "type": "boolean | undefined"
1612
+ },
1613
+ {
1614
+ "name": "showSettingsAlert",
1615
+ "tags": [],
1616
+ "docs": "",
1617
+ "complexTypes": [],
1618
+ "type": "boolean | undefined"
1619
+ },
1620
+ {
1621
+ "name": "title",
1622
+ "tags": [],
1623
+ "docs": "",
1624
+ "complexTypes": [],
1625
+ "type": "string | undefined"
1626
+ },
1627
+ {
1628
+ "name": "message",
1629
+ "tags": [],
1630
+ "docs": "",
1631
+ "complexTypes": [],
1632
+ "type": "string | undefined"
1633
+ },
1634
+ {
1635
+ "name": "openSettingsButtonTitle",
1636
+ "tags": [],
1637
+ "docs": "",
1638
+ "complexTypes": [],
1639
+ "type": "string | undefined"
1640
+ },
1641
+ {
1642
+ "name": "cancelButtonTitle",
1643
+ "tags": [],
1644
+ "docs": "",
1645
+ "complexTypes": [],
1646
+ "type": "string | undefined"
1647
+ }
1648
+ ]
1649
+ },
1507
1650
  {
1508
1651
  "name": "SupportedPictureSizes",
1509
1652
  "slug": "supportedpicturesizes",
@@ -1909,6 +2052,44 @@
1909
2052
  }
1910
2053
  ]
1911
2054
  },
2055
+ {
2056
+ "name": "PermissionState",
2057
+ "slug": "permissionstate",
2058
+ "docs": "",
2059
+ "types": [
2060
+ {
2061
+ "text": "'prompt'",
2062
+ "complexTypes": []
2063
+ },
2064
+ {
2065
+ "text": "'prompt-with-rationale'",
2066
+ "complexTypes": []
2067
+ },
2068
+ {
2069
+ "text": "'granted'",
2070
+ "complexTypes": []
2071
+ },
2072
+ {
2073
+ "text": "'denied'",
2074
+ "complexTypes": []
2075
+ }
2076
+ ]
2077
+ },
2078
+ {
2079
+ "name": "Pick",
2080
+ "slug": "pick",
2081
+ "docs": "From T, pick a set of properties whose keys are in the union K",
2082
+ "types": [
2083
+ {
2084
+ "text": "{\r\n [P in K]: T[P];\r\n}",
2085
+ "complexTypes": [
2086
+ "K",
2087
+ "T",
2088
+ "P"
2089
+ ]
2090
+ }
2091
+ ]
2092
+ },
1912
2093
  {
1913
2094
  "name": "FlashMode",
1914
2095
  "slug": "flashmode",
@@ -1,8 +1,20 @@
1
- import type { PluginListenerHandle } from "@capacitor/core";
1
+ import type { PermissionState, PluginListenerHandle } from "@capacitor/core";
2
2
  export type CameraPosition = "rear" | "front";
3
3
  export type FlashMode = CameraPreviewFlashMode;
4
4
  export type GridMode = "none" | "3x3" | "4x4";
5
5
  export type CameraPositioning = "center" | "top" | "bottom";
6
+ export interface CameraPermissionStatus {
7
+ camera: PermissionState;
8
+ microphone?: PermissionState;
9
+ }
10
+ export interface PermissionRequestOptions {
11
+ disableAudio?: boolean;
12
+ showSettingsAlert?: boolean;
13
+ title?: string;
14
+ message?: string;
15
+ openSettingsButtonTitle?: string;
16
+ cancelButtonTitle?: string;
17
+ }
6
18
  export declare enum DeviceType {
7
19
  ULTRA_WIDE = "ultraWide",
8
20
  WIDE_ANGLE = "wideAngle",
@@ -443,6 +455,24 @@ export interface CameraPreviewPlugin {
443
455
  getGridMode(): Promise<{
444
456
  gridMode: GridMode;
445
457
  }>;
458
+ /**
459
+ * Checks the current camera (and optionally microphone) permission status without prompting the system dialog.
460
+ *
461
+ * @param options Set `disableAudio` to `false` to also include microphone status (defaults to `true`).
462
+ * @returns {Promise<CameraPermissionStatus>} A promise resolving to the current authorization states.
463
+ * @since 8.7.0
464
+ */
465
+ checkPermissions(options?: Pick<PermissionRequestOptions, "disableAudio">): Promise<CameraPermissionStatus>;
466
+ /**
467
+ * Requests camera (and optional microphone) permissions. If permissions are already granted or denied,
468
+ * the current status is returned without prompting. When `showSettingsAlert` is true and permissions are denied,
469
+ * a platform specific alert guiding the user to the app settings will be presented.
470
+ *
471
+ * @param {PermissionRequestOptions} options - Configuration for the permission request behaviour.
472
+ * @returns {Promise<CameraPermissionStatus>} A promise resolving to the final authorization states.
473
+ * @since 8.7.0
474
+ */
475
+ requestPermissions(options?: PermissionRequestOptions): Promise<CameraPermissionStatus>;
446
476
  /**
447
477
  * Gets the horizontal field of view (FoV) for the active camera.
448
478
  * Note: This can be an estimate on some devices.