Skip to content
This repository was archived by the owner on Feb 22, 2023. It is now read-only.

[camera] Return all possible cameras on Android #6091

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion packages/camera/camera_android/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
## NEXT
## 0.9.9

* Fixes getAvailableCameras to return all possible cameras.
* Ignores missing return warnings in preparation for [upcoming analysis changes](https://github.com/flutter/flutter/issues/105750).

## 0.9.8+3
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import android.hardware.camera2.CameraMetadata;
import io.flutter.embedding.engine.systemchannels.PlatformChannel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -94,8 +95,27 @@ static PlatformChannel.DeviceOrientation deserializeDeviceOrientation(String ori
public static List<Map<String, Object>> getAvailableCameras(Activity activity)
throws CameraAccessException {
CameraManager cameraManager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
String[] cameraNames = cameraManager.getCameraIdList();

List<String> cameraNames = new ArrayList<>(Arrays.asList(cameraManager.getCameraIdList()));
List<Map<String, Object>> cameras = new ArrayList<>();

boolean expectingCamera = true;
int i = 0;

while (expectingCamera) {
try {
String cameraName = String.valueOf(i);
cameraNames.remove(cameraName);
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraName);
Map<String, Object> details = serializeCameraCharacteristics(cameraName, characteristics);
cameras.add(details);
i++;
} catch (Exception e) {
// retrieving Camera failed, most probably there is no other physical non-removable camera.
expectingCamera = false;
}
}

for (String cameraName : cameraNames) {
int cameraId;
try {
Expand All @@ -107,26 +127,31 @@ public static List<Map<String, Object>> getAvailableCameras(Activity activity)
continue;
}

HashMap<String, Object> details = new HashMap<>();
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(cameraName);
details.put("name", cameraName);
int sensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
details.put("sensorOrientation", sensorOrientation);

int lensFacing = characteristics.get(CameraCharacteristics.LENS_FACING);
switch (lensFacing) {
case CameraMetadata.LENS_FACING_FRONT:
details.put("lensFacing", "front");
break;
case CameraMetadata.LENS_FACING_BACK:
details.put("lensFacing", "back");
break;
case CameraMetadata.LENS_FACING_EXTERNAL:
details.put("lensFacing", "external");
break;
}
Map<String, Object> details = serializeCameraCharacteristics(cameraName, characteristics);
cameras.add(details);
}
return cameras;
}

private static Map<String, Object> serializeCameraCharacteristics(
String name, CameraCharacteristics cameraCharacteristics) {
HashMap<String, Object> details = new HashMap<>();
details.put("name", name);
int sensorOrientation = cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
details.put("sensorOrientation", sensorOrientation);
int lensFacing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
switch (lensFacing) {
case CameraMetadata.LENS_FACING_FRONT:
details.put("lensFacing", "front");
break;
case CameraMetadata.LENS_FACING_BACK:
details.put("lensFacing", "back");
break;
case CameraMetadata.LENS_FACING_EXTERNAL:
details.put("lensFacing", "external");
break;
}
return details;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ android {
defaultConfig {
applicationId "io.flutter.plugins.cameraexample"
minSdkVersion 21
targetSdkVersion 28
targetSdkVersion 31
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
android:icon="@mipmap/ic_launcher"
android:label="camera_example">
<activity
android:exported="true"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection"
android:hardwareAccelerated="true"
android:launchMode="singleTop"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ buildscript {
}

dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
classpath 'com.android.tools.build:gradle:7.2.1'
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4.2-bin.zip
17 changes: 10 additions & 7 deletions packages/camera/camera_android/example/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -158,12 +158,15 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
),
_captureControlRowWidget(),
_modeControlRowWidget(),
Padding(
Container(
width: double.infinity,
padding: const EdgeInsets.all(5.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.start,
height: 50,
child: ListView(
shrinkWrap: true,
scrollDirection: Axis.horizontal,
children: <Widget>[
_cameraTogglesRowWidget(),
..._cameraTogglesRowWidget(),
_thumbnailWidget(),
],
),
Expand Down Expand Up @@ -586,7 +589,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
}

/// Display a row of toggle to select the camera (or a message if no camera is available).
Widget _cameraTogglesRowWidget() {
List<Widget> _cameraTogglesRowWidget() {
final List<Widget> toggles = <Widget>[];

void onChanged(CameraDescription? description) {
Expand All @@ -601,7 +604,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
_ambiguate(SchedulerBinding.instance)?.addPostFrameCallback((_) async {
showInSnackBar('No camera found.');
});
return const Text('None');
return <Widget>[const Text('None')];
} else {
for (final CameraDescription cameraDescription in _cameras) {
toggles.add(
Expand All @@ -621,7 +624,7 @@ class _CameraExampleHomeState extends State<CameraExampleHome>
}
}

return Row(children: toggles);
return toggles;
}

String timestamp() => DateTime.now().millisecondsSinceEpoch.toString();
Expand Down
2 changes: 1 addition & 1 deletion packages/camera/camera_android/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: camera_android
description: Android implementation of the camera plugin.
repository: https://github.com/flutter/plugins/tree/main/packages/camera/camera_android
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+camera%22
version: 0.9.8+3
version: 0.9.9

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down