mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 15:00:40 +00:00
implemeted permissions check (wip)
This commit is contained in:
parent
f420ddc186
commit
7460f12211
16 changed files with 331 additions and 64 deletions
|
@ -32,4 +32,7 @@
|
|||
android:name="flutterEmbedding"
|
||||
android:value="2" />
|
||||
</application>
|
||||
|
||||
<uses-permission android:name="android.permission.CAMERA" />
|
||||
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||
</manifest>
|
||||
|
|
53
ios/Podfile
Normal file
53
ios/Podfile
Normal file
|
@ -0,0 +1,53 @@
|
|||
# Uncomment this line to define a global platform for your project
|
||||
# platform :ios, '11.0'
|
||||
|
||||
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
|
||||
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
|
||||
|
||||
project 'Runner', {
|
||||
'Debug' => :debug,
|
||||
'Profile' => :release,
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
use_frameworks!
|
||||
use_modular_headers!
|
||||
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
flutter_additional_ios_build_settings(target)
|
||||
|
||||
# Start of the permission_handler configuration
|
||||
target.build_configurations.each do |config|
|
||||
# Preprocessor definitions can be found in: https://github.com/Baseflow/flutter-permission-handler/blob/master/permission_handler_apple/ios/Classes/PermissionHandlerEnums.h
|
||||
config.build_settings['GCC_PREPROCESSOR_DEFINITIONS'] ||= [
|
||||
'$(inherited)',
|
||||
'PERMISSION_CAMERA=1',
|
||||
|
||||
## dart: PermissionGroup.sensors
|
||||
# 'PERMISSION_SENSORS=1',
|
||||
]
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,49 +1,51 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true/>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Lightmeter</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>lightmeter</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true/>
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
||||
<dict>
|
||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||
<true />
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>$(DEVELOPMENT_LANGUAGE)</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>Lightmeter</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>lightmeter</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>$(FLUTTER_BUILD_NAME)</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>$(FLUTTER_BUILD_NUMBER)</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true />
|
||||
<key>UIApplicationSupportsIndirectInputEvents</key>
|
||||
<true />
|
||||
<key>UILaunchStoryboardName</key>
|
||||
<string>LaunchScreen</string>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
</array>
|
||||
<key>UISupportedInterfaceOrientations~ipad</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
<string>UIInterfaceOrientationLandscapeLeft</string>
|
||||
<string>UIInterfaceOrientationLandscapeRight</string>
|
||||
</array>
|
||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||
<false />
|
||||
<key>NSCameraUsageDescription</key>
|
||||
<string>Provide camera permissions in order to make measurements</string>
|
||||
</dict>
|
||||
</plist>
|
7
lib/data/permissions_service.dart
Normal file
7
lib/data/permissions_service.dart
Normal file
|
@ -0,0 +1,7 @@
|
|||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
class PermissionsService {
|
||||
Future<PermissionStatus> checkCameraPermission() async => await Permission.camera.status;
|
||||
|
||||
Future<PermissionStatus> requestCameraPermission() async => Permission.camera.request();
|
||||
}
|
|
@ -27,6 +27,11 @@ class MessageLookup extends MessageLookupByLibrary {
|
|||
"haptics": MessageLookupByLibrary.simpleMessage("Haptics"),
|
||||
"keepsScreenOn":
|
||||
MessageLookupByLibrary.simpleMessage("Keeps screen on"),
|
||||
"openSettings": MessageLookupByLibrary.simpleMessage("Open settings"),
|
||||
"permissionNeeded":
|
||||
MessageLookupByLibrary.simpleMessage("Permission needed"),
|
||||
"permissionNeededMessage": MessageLookupByLibrary.simpleMessage(
|
||||
"To use Lightmeter, turn on Camera permissions."),
|
||||
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
|
||||
"slowestExposurePair": MessageLookupByLibrary.simpleMessage("Slowest")
|
||||
};
|
||||
|
|
|
@ -50,6 +50,36 @@ class S {
|
|||
return Localizations.of<S>(context, S);
|
||||
}
|
||||
|
||||
/// `Permission needed`
|
||||
String get permissionNeeded {
|
||||
return Intl.message(
|
||||
'Permission needed',
|
||||
name: 'permissionNeeded',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `To use Lightmeter, turn on Camera permissions.`
|
||||
String get permissionNeededMessage {
|
||||
return Intl.message(
|
||||
'To use Lightmeter, turn on Camera permissions.',
|
||||
name: 'permissionNeededMessage',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Open settings`
|
||||
String get openSettings {
|
||||
return Intl.message(
|
||||
'Open settings',
|
||||
name: 'openSettings',
|
||||
desc: '',
|
||||
args: [],
|
||||
);
|
||||
}
|
||||
|
||||
/// `Fastest`
|
||||
String get fastestExposurePair {
|
||||
return Intl.message(
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
{
|
||||
"@@locale": "en",
|
||||
"permissionNeeded": "Permission needed",
|
||||
"permissionNeededMessage": "To use Lightmeter, turn on Camera permissions.",
|
||||
"openSettings": "Open settings",
|
||||
"fastestExposurePair": "Fastest",
|
||||
"slowestExposurePair": "Slowest",
|
||||
"settings": "Settings",
|
||||
|
|
|
@ -2,14 +2,16 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||
import 'package:lightmeter/data/permissions_service.dart';
|
||||
import 'package:lightmeter/screens/settings/settings_page_route_builder.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'generated/l10n.dart';
|
||||
import 'models/photography_value.dart';
|
||||
import 'res/dimens.dart';
|
||||
import 'res/theme.dart';
|
||||
import 'screens/metering/metering_bloc.dart';
|
||||
import 'screens/metering/metering_screen.dart';
|
||||
import 'screens/permissions_check/flow_permissions_check.dart';
|
||||
import 'utils/stop_type_provider.dart';
|
||||
|
||||
void main() {
|
||||
|
@ -57,23 +59,27 @@ class _ApplicationState extends State<Application> with TickerProviderStateMixin
|
|||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return StopTypeProvider(
|
||||
child: BlocProvider(
|
||||
create: (context) => MeteringBloc(context.read<StopType>()),
|
||||
child: MaterialApp(
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: lightColorScheme,
|
||||
return Provider(
|
||||
create: (context) => PermissionsService(),
|
||||
child: StopTypeProvider(
|
||||
child: BlocProvider(
|
||||
create: (context) => MeteringBloc(context.read<StopType>()),
|
||||
child: MaterialApp(
|
||||
theme: ThemeData(
|
||||
useMaterial3: true,
|
||||
colorScheme: lightColorScheme,
|
||||
),
|
||||
navigatorObservers: [_settingsRouteObserver],
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
home: const PermissionsCheckFlow(),
|
||||
//home: MeteringScreen(animationController: _animationController),
|
||||
),
|
||||
navigatorObservers: [_settingsRouteObserver],
|
||||
localizationsDelegates: const [
|
||||
S.delegate,
|
||||
GlobalMaterialLocalizations.delegate,
|
||||
GlobalWidgetsLocalizations.delegate,
|
||||
GlobalCupertinoLocalizations.delegate,
|
||||
],
|
||||
supportedLocales: S.delegate.supportedLocales,
|
||||
home: MeteringScreen(animationController: _animationController),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
|
|
@ -8,8 +8,10 @@ class Dimens {
|
|||
static const double grid8 = 8;
|
||||
static const double grid16 = 16;
|
||||
static const double grid24 = 24;
|
||||
static const double grid168 = 168;
|
||||
|
||||
static const double paddingM = 16;
|
||||
static const double paddingL = 24;
|
||||
|
||||
static const Duration durationS = Duration(milliseconds: 100);
|
||||
static const Duration durationSM = Duration(milliseconds: 150);
|
||||
|
|
46
lib/screens/permissions_check/bloc_permissions_check.dart
Normal file
46
lib/screens/permissions_check/bloc_permissions_check.dart
Normal file
|
@ -0,0 +1,46 @@
|
|||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/permissions_service.dart';
|
||||
import 'package:permission_handler/permission_handler.dart';
|
||||
|
||||
import 'event_permissions_check.dart';
|
||||
import 'state_permissions_check.dart';
|
||||
|
||||
class PermissionsCheckBloc extends Bloc<PermissionsCheckEvent, PermissionsCheckState> {
|
||||
final PermissionsService _permissionsService;
|
||||
|
||||
PermissionsCheckBloc(this._permissionsService) : super(const LoadingState()) {
|
||||
on<PermissionsGrantedEvent>((event, emit) => emit(const PermissionsGrantedState()));
|
||||
on<PermissionsDeniedEvent>((event, emit) => emit(const PermissionsDeniedState()));
|
||||
_checkAndRequestPermissions();
|
||||
}
|
||||
|
||||
Future<void> _checkAndRequestPermissions() async {
|
||||
_permissionsService.checkCameraPermission().then((value) {
|
||||
switch (value) {
|
||||
case PermissionStatus.permanentlyDenied:
|
||||
case PermissionStatus.restricted:
|
||||
add(const PermissionsDeniedEvent());
|
||||
break;
|
||||
case PermissionStatus.denied:
|
||||
_permissionsService.requestCameraPermission().then((value) {
|
||||
switch (value) {
|
||||
case PermissionStatus.permanentlyDenied:
|
||||
case PermissionStatus.restricted:
|
||||
case PermissionStatus.denied:
|
||||
add(const PermissionsDeniedEvent());
|
||||
break;
|
||||
case PermissionStatus.limited:
|
||||
case PermissionStatus.granted:
|
||||
add(const PermissionsGrantedEvent());
|
||||
break;
|
||||
}
|
||||
});
|
||||
break;
|
||||
case PermissionStatus.limited:
|
||||
case PermissionStatus.granted:
|
||||
add(const PermissionsGrantedEvent());
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
11
lib/screens/permissions_check/event_permissions_check.dart
Normal file
11
lib/screens/permissions_check/event_permissions_check.dart
Normal file
|
@ -0,0 +1,11 @@
|
|||
abstract class PermissionsCheckEvent {
|
||||
const PermissionsCheckEvent();
|
||||
}
|
||||
|
||||
class PermissionsDeniedEvent extends PermissionsCheckEvent {
|
||||
const PermissionsDeniedEvent();
|
||||
}
|
||||
|
||||
class PermissionsGrantedEvent extends PermissionsCheckEvent {
|
||||
const PermissionsGrantedEvent();
|
||||
}
|
18
lib/screens/permissions_check/flow_permissions_check.dart
Normal file
18
lib/screens/permissions_check/flow_permissions_check.dart
Normal file
|
@ -0,0 +1,18 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/data/permissions_service.dart';
|
||||
import 'package:lightmeter/screens/permissions_check/screen_permissions_check.dart';
|
||||
|
||||
import 'bloc_permissions_check.dart';
|
||||
|
||||
class PermissionsCheckFlow extends StatelessWidget {
|
||||
const PermissionsCheckFlow({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return BlocProvider(
|
||||
create: (context) => PermissionsCheckBloc(context.read<PermissionsService>()),
|
||||
child: const PermissionsCheckScreen(),
|
||||
);
|
||||
}
|
||||
}
|
65
lib/screens/permissions_check/screen_permissions_check.dart
Normal file
65
lib/screens/permissions_check/screen_permissions_check.dart
Normal file
|
@ -0,0 +1,65 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||
import 'package:lightmeter/generated/l10n.dart';
|
||||
import 'package:lightmeter/res/dimens.dart';
|
||||
import 'package:lightmeter/screens/settings/settings_screen.dart';
|
||||
|
||||
import 'bloc_permissions_check.dart';
|
||||
import 'state_permissions_check.dart';
|
||||
|
||||
class PermissionsCheckScreen extends StatelessWidget {
|
||||
const PermissionsCheckScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
backgroundColor: Theme.of(context).colorScheme.surface,
|
||||
body: SafeArea(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(Dimens.paddingM * 2),
|
||||
child: Center(
|
||||
child: BlocConsumer<PermissionsCheckBloc, PermissionsCheckState>(
|
||||
listener: (context, state) {
|
||||
if (state is PermissionsGrantedState) {
|
||||
Navigator.of(context).pushReplacement(MaterialPageRoute(builder: (_) => SettingsScreen()));
|
||||
}
|
||||
},
|
||||
builder: (context, state) {
|
||||
return AnimatedSwitcher(
|
||||
duration: Dimens.durationS,
|
||||
child: state is LoadingState
|
||||
? const CircularProgressIndicator()
|
||||
: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Text(
|
||||
S.of(context).permissionNeeded,
|
||||
style: Theme.of(context).textTheme.headlineLarge,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: Dimens.grid16),
|
||||
Text(
|
||||
S.of(context).permissionNeededMessage,
|
||||
style: Theme.of(context).textTheme.bodyLarge,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
const SizedBox(height: Dimens.grid24),
|
||||
ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Theme.of(context).colorScheme.primary,
|
||||
foregroundColor: Theme.of(context).colorScheme.onPrimary,
|
||||
),
|
||||
onPressed: () {},
|
||||
child: Text(S.of(context).openSettings),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
15
lib/screens/permissions_check/state_permissions_check.dart
Normal file
15
lib/screens/permissions_check/state_permissions_check.dart
Normal file
|
@ -0,0 +1,15 @@
|
|||
abstract class PermissionsCheckState {
|
||||
const PermissionsCheckState();
|
||||
}
|
||||
|
||||
class LoadingState extends PermissionsCheckState {
|
||||
const LoadingState();
|
||||
}
|
||||
|
||||
class PermissionsGrantedState extends PermissionsCheckState {
|
||||
const PermissionsGrantedState();
|
||||
}
|
||||
|
||||
class PermissionsDeniedState extends PermissionsCheckState {
|
||||
const PermissionsDeniedState();
|
||||
}
|
|
@ -17,7 +17,7 @@ class SettingsScreen extends StatelessWidget {
|
|||
SliverAppBar(
|
||||
pinned: true,
|
||||
automaticallyImplyLeading: false,
|
||||
expandedHeight: 160.0,
|
||||
expandedHeight: Dimens.grid168,
|
||||
flexibleSpace: FlexibleSpaceBar(
|
||||
centerTitle: false,
|
||||
titlePadding: const EdgeInsets.all(Dimens.paddingM),
|
||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
|||
sdk: flutter
|
||||
intl: ^0.17.0
|
||||
material_color_utilities: ^0.2.0
|
||||
permission_handler: 10.2.0
|
||||
provider: ^6.0.4
|
||||
|
||||
dev_dependencies:
|
||||
|
|
Loading…
Reference in a new issue