From ff484f92dce4e87585bcc61497008eef63607196 Mon Sep 17 00:00:00 2001 From: Mikhail Zotyev Date: Tue, 20 Dec 2022 12:08:18 +0100 Subject: [PATCH 1/5] Fix: if we don't have a profile, using the legacy way to detect dimensions. --- .../camera/camera_android/android/build.gradle | 2 +- .../features/resolution/ResolutionFeature.java | 17 ++++++++++------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/packages/camera/camera_android/android/build.gradle b/packages/camera/camera_android/android/build.gradle index 4fbb2270b556..b50c53f0d7dd 100644 --- a/packages/camera/camera_android/android/build.gradle +++ b/packages/camera/camera_android/android/build.gradle @@ -27,7 +27,7 @@ project.getTasks().withType(JavaCompile){ apply plugin: 'com.android.library' android { - compileSdkVersion 31 + compileSdk 31 defaultConfig { targetSdkVersion 31 diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java index afbd7c3758a6..73afe2f8c48a 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java @@ -114,19 +114,22 @@ static Size computeBestPreviewSize(int cameraId, ResolutionPreset preset) if (preset.ordinal() > ResolutionPreset.high.ordinal()) { preset = ResolutionPreset.high; } + if (Build.VERSION.SDK_INT >= 31) { EncoderProfiles profile = - getBestAvailableCamcorderProfileForResolutionPreset(cameraId, preset); + getBestAvailableCamcorderProfileForResolutionPreset(cameraId, preset); List videoProfiles = profile.getVideoProfiles(); EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0); - return new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight()); - } else { - @SuppressWarnings("deprecation") - CamcorderProfile profile = - getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, preset); - return new Size(profile.videoFrameWidth, profile.videoFrameHeight); + if (defaultVideoProfile != null) { + return new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight()); + } } + + @SuppressWarnings("deprecation") + CamcorderProfile profile = + getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, preset); + return new Size(profile.videoFrameWidth, profile.videoFrameHeight); } /** From 5c15870673b7ed9a4f4af22b2b15e22a577586a0 Mon Sep 17 00:00:00 2001 From: Mikhail Zotyev Date: Tue, 20 Dec 2022 13:15:16 +0100 Subject: [PATCH 2/5] Feat: increase the sdk version for the camera example application. --- packages/camera/camera/example/android/app/build.gradle | 4 ++-- .../camera/example/android/app/src/main/AndroidManifest.xml | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/packages/camera/camera/example/android/app/build.gradle b/packages/camera/camera/example/android/app/build.gradle index 5d6af5887012..79bce4ba5614 100644 --- a/packages/camera/camera/example/android/app/build.gradle +++ b/packages/camera/camera/example/android/app/build.gradle @@ -25,7 +25,7 @@ apply plugin: 'com.android.application' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 31 + compileSdkVersion 33 lintOptions { disable 'InvalidPackage' @@ -34,7 +34,7 @@ android { defaultConfig { applicationId "io.flutter.plugins.cameraexample" minSdkVersion 21 - targetSdkVersion 28 + targetSdkVersion 33 versionCode flutterVersionCode.toInteger() versionName flutterVersionName testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" diff --git a/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml b/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml index cef23162ddb6..3dc46712b0da 100644 --- a/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml +++ b/packages/camera/camera/example/android/app/src/main/AndroidManifest.xml @@ -10,7 +10,8 @@ android:launchMode="singleTop" android:name="io.flutter.embedding.android.FlutterActivity" android:theme="@style/LaunchTheme" - android:windowSoftInputMode="adjustResize"> + android:windowSoftInputMode="adjustResize" + android:exported="true"> From 64804933de27164aaad4aed3058ccfdb30dfac99 Mon Sep 17 00:00:00 2001 From: Mikhail Zotyev Date: Tue, 20 Dec 2022 15:23:51 +0100 Subject: [PATCH 3/5] Fix: use legacy when newest profiles are not exist. --- .../resolution/ResolutionFeature.java | 17 ++++--- .../camera/media/MediaRecorderBuilder.java | 45 ++++++++++++------- 2 files changed, 41 insertions(+), 21 deletions(-) diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java index 73afe2f8c48a..699a931cf705 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/features/resolution/ResolutionFeature.java @@ -238,20 +238,25 @@ private void configureResolution(ResolutionPreset resolutionPreset, int cameraId return; } + captureSize = null; + if (Build.VERSION.SDK_INT >= 31) { recordingProfile = - getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset); + getBestAvailableCamcorderProfileForResolutionPreset(cameraId, resolutionPreset); List videoProfiles = recordingProfile.getVideoProfiles(); EncoderProfiles.VideoProfile defaultVideoProfile = videoProfiles.get(0); - captureSize = new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight()); - } else { + if (defaultVideoProfile != null) { + captureSize = new Size(defaultVideoProfile.getWidth(), defaultVideoProfile.getHeight()); + } + } + + if (captureSize == null) { @SuppressWarnings("deprecation") CamcorderProfile camcorderProfile = - getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, resolutionPreset); + getBestAvailableCamcorderProfileForResolutionPresetLegacy(cameraId, resolutionPreset); recordingProfileLegacy = camcorderProfile; - captureSize = - new Size(recordingProfileLegacy.videoFrameWidth, recordingProfileLegacy.videoFrameHeight); + captureSize = new Size(recordingProfileLegacy.videoFrameWidth, recordingProfileLegacy.videoFrameHeight); } previewSize = computeBestPreviewSize(cameraId, resolutionPreset); diff --git a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java index 0aebfee39e0a..cfc80dac9adf 100644 --- a/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java +++ b/packages/camera/camera_android/android/src/main/java/io/flutter/plugins/camera/media/MediaRecorderBuilder.java @@ -75,33 +75,48 @@ public MediaRecorder build() throws IOException, NullPointerException, IndexOutO if (enableAudio) mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); mediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE); - if (Build.VERSION.SDK_INT >= 31) { + boolean isFormatNeedSetup = true; + boolean isAudioNeedSetup = enableAudio; + boolean isVideoNeedSetup = true; + + if (Build.VERSION.SDK_INT >= 31 && encoderProfiles != null) { EncoderProfiles.VideoProfile videoProfile = encoderProfiles.getVideoProfiles().get(0); EncoderProfiles.AudioProfile audioProfile = encoderProfiles.getAudioProfiles().get(0); mediaRecorder.setOutputFormat(encoderProfiles.getRecommendedFileFormat()); - if (enableAudio) { + isFormatNeedSetup = false; + + if (isAudioNeedSetup && audioProfile != null) { mediaRecorder.setAudioEncoder(audioProfile.getCodec()); mediaRecorder.setAudioEncodingBitRate(audioProfile.getBitrate()); mediaRecorder.setAudioSamplingRate(audioProfile.getSampleRate()); + isAudioNeedSetup = false; } - mediaRecorder.setVideoEncoder(videoProfile.getCodec()); - mediaRecorder.setVideoEncodingBitRate(videoProfile.getBitrate()); - mediaRecorder.setVideoFrameRate(videoProfile.getFrameRate()); - mediaRecorder.setVideoSize(videoProfile.getWidth(), videoProfile.getHeight()); - mediaRecorder.setVideoSize(videoProfile.getWidth(), videoProfile.getHeight()); - } else { - mediaRecorder.setOutputFormat(camcorderProfile.fileFormat); - if (enableAudio) { - mediaRecorder.setAudioEncoder(camcorderProfile.audioCodec); - mediaRecorder.setAudioEncodingBitRate(camcorderProfile.audioBitRate); - mediaRecorder.setAudioSamplingRate(camcorderProfile.audioSampleRate); + if (videoProfile != null) { + mediaRecorder.setVideoEncoder(videoProfile.getCodec()); + mediaRecorder.setVideoEncodingBitRate(videoProfile.getBitrate()); + mediaRecorder.setVideoFrameRate(videoProfile.getFrameRate()); + mediaRecorder.setVideoSize(videoProfile.getWidth(), videoProfile.getHeight()); + mediaRecorder.setVideoSize(videoProfile.getWidth(), videoProfile.getHeight()); + isVideoNeedSetup = false; } + } + + if (isFormatNeedSetup && camcorderProfile != null) { + mediaRecorder.setOutputFormat(camcorderProfile.fileFormat); + } + + if (isAudioNeedSetup && camcorderProfile != null) { + mediaRecorder.setAudioEncoder(camcorderProfile.audioCodec); + mediaRecorder.setAudioEncodingBitRate(camcorderProfile.audioBitRate); + mediaRecorder.setAudioSamplingRate(camcorderProfile.audioSampleRate); + } + + if (isVideoNeedSetup && camcorderProfile != null) { mediaRecorder.setVideoEncoder(camcorderProfile.videoCodec); mediaRecorder.setVideoEncodingBitRate(camcorderProfile.videoBitRate); mediaRecorder.setVideoFrameRate(camcorderProfile.videoFrameRate); - mediaRecorder.setVideoSize( - camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight); + mediaRecorder.setVideoSize(camcorderProfile.videoFrameWidth, camcorderProfile.videoFrameHeight); } mediaRecorder.setOutputFile(outputFilePath); From 80887eb69accd19919725466bf35b6bfabe217f2 Mon Sep 17 00:00:00 2001 From: Mikhail Zotyev Date: Tue, 20 Dec 2022 17:21:31 +0100 Subject: [PATCH 4/5] Chore: bump the version of the plugin. --- packages/camera/camera_android/pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/camera/camera_android/pubspec.yaml b/packages/camera/camera_android/pubspec.yaml index 7ed5077c315e..6f25af7d61fb 100644 --- a/packages/camera/camera_android/pubspec.yaml +++ b/packages/camera/camera_android/pubspec.yaml @@ -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.10.1 +version: 0.10.2 environment: sdk: ">=2.14.0 <3.0.0" From bdd7e6ad0f99a185784eaee207085f8fb032e2cc Mon Sep 17 00:00:00 2001 From: Mikhail Zotyev Date: Tue, 20 Dec 2022 17:38:47 +0100 Subject: [PATCH 5/5] Chore: add info to contributors list. --- AUTHORS | 1 + 1 file changed, 1 insertion(+) diff --git a/AUTHORS b/AUTHORS index 3112c3b3fd05..3f2a39549c11 100644 --- a/AUTHORS +++ b/AUTHORS @@ -69,3 +69,4 @@ TheOneWithTheBraid Rulong Chen(陈汝龙) Hwanseok Kang Twin Sun, LLC +Mikhail Zotyev \ No newline at end of file