mirror of
https://github.com/vodemn/m3_lightmeter.git
synced 2024-11-21 23:10: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:name="flutterEmbedding"
|
||||||
android:value="2" />
|
android:value="2" />
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
<uses-feature android:name="android.hardware.camera" android:required="true" />
|
||||||
</manifest>
|
</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
|
|
@ -45,5 +45,7 @@
|
||||||
</array>
|
</array>
|
||||||
<key>UIViewControllerBasedStatusBarAppearance</key>
|
<key>UIViewControllerBasedStatusBarAppearance</key>
|
||||||
<false />
|
<false />
|
||||||
|
<key>NSCameraUsageDescription</key>
|
||||||
|
<string>Provide camera permissions in order to make measurements</string>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</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"),
|
"haptics": MessageLookupByLibrary.simpleMessage("Haptics"),
|
||||||
"keepsScreenOn":
|
"keepsScreenOn":
|
||||||
MessageLookupByLibrary.simpleMessage("Keeps screen on"),
|
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"),
|
"settings": MessageLookupByLibrary.simpleMessage("Settings"),
|
||||||
"slowestExposurePair": MessageLookupByLibrary.simpleMessage("Slowest")
|
"slowestExposurePair": MessageLookupByLibrary.simpleMessage("Slowest")
|
||||||
};
|
};
|
||||||
|
|
|
@ -50,6 +50,36 @@ class S {
|
||||||
return Localizations.of<S>(context, 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`
|
/// `Fastest`
|
||||||
String get fastestExposurePair {
|
String get fastestExposurePair {
|
||||||
return Intl.message(
|
return Intl.message(
|
||||||
|
|
|
@ -1,5 +1,8 @@
|
||||||
{
|
{
|
||||||
"@@locale": "en",
|
"@@locale": "en",
|
||||||
|
"permissionNeeded": "Permission needed",
|
||||||
|
"permissionNeededMessage": "To use Lightmeter, turn on Camera permissions.",
|
||||||
|
"openSettings": "Open settings",
|
||||||
"fastestExposurePair": "Fastest",
|
"fastestExposurePair": "Fastest",
|
||||||
"slowestExposurePair": "Slowest",
|
"slowestExposurePair": "Slowest",
|
||||||
"settings": "Settings",
|
"settings": "Settings",
|
||||||
|
|
|
@ -2,14 +2,16 @@ import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_bloc/flutter_bloc.dart';
|
import 'package:flutter_bloc/flutter_bloc.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.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:lightmeter/screens/settings/settings_page_route_builder.dart';
|
||||||
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
import 'generated/l10n.dart';
|
import 'generated/l10n.dart';
|
||||||
import 'models/photography_value.dart';
|
import 'models/photography_value.dart';
|
||||||
import 'res/dimens.dart';
|
import 'res/dimens.dart';
|
||||||
import 'res/theme.dart';
|
import 'res/theme.dart';
|
||||||
import 'screens/metering/metering_bloc.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';
|
import 'utils/stop_type_provider.dart';
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
|
@ -57,7 +59,9 @@ class _ApplicationState extends State<Application> with TickerProviderStateMixin
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return StopTypeProvider(
|
return Provider(
|
||||||
|
create: (context) => PermissionsService(),
|
||||||
|
child: StopTypeProvider(
|
||||||
child: BlocProvider(
|
child: BlocProvider(
|
||||||
create: (context) => MeteringBloc(context.read<StopType>()),
|
create: (context) => MeteringBloc(context.read<StopType>()),
|
||||||
child: MaterialApp(
|
child: MaterialApp(
|
||||||
|
@ -73,7 +77,9 @@ class _ApplicationState extends State<Application> with TickerProviderStateMixin
|
||||||
GlobalCupertinoLocalizations.delegate,
|
GlobalCupertinoLocalizations.delegate,
|
||||||
],
|
],
|
||||||
supportedLocales: S.delegate.supportedLocales,
|
supportedLocales: S.delegate.supportedLocales,
|
||||||
home: MeteringScreen(animationController: _animationController),
|
home: const PermissionsCheckFlow(),
|
||||||
|
//home: MeteringScreen(animationController: _animationController),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
|
@ -8,8 +8,10 @@ class Dimens {
|
||||||
static const double grid8 = 8;
|
static const double grid8 = 8;
|
||||||
static const double grid16 = 16;
|
static const double grid16 = 16;
|
||||||
static const double grid24 = 24;
|
static const double grid24 = 24;
|
||||||
|
static const double grid168 = 168;
|
||||||
|
|
||||||
static const double paddingM = 16;
|
static const double paddingM = 16;
|
||||||
|
static const double paddingL = 24;
|
||||||
|
|
||||||
static const Duration durationS = Duration(milliseconds: 100);
|
static const Duration durationS = Duration(milliseconds: 100);
|
||||||
static const Duration durationSM = Duration(milliseconds: 150);
|
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(
|
SliverAppBar(
|
||||||
pinned: true,
|
pinned: true,
|
||||||
automaticallyImplyLeading: false,
|
automaticallyImplyLeading: false,
|
||||||
expandedHeight: 160.0,
|
expandedHeight: Dimens.grid168,
|
||||||
flexibleSpace: FlexibleSpaceBar(
|
flexibleSpace: FlexibleSpaceBar(
|
||||||
centerTitle: false,
|
centerTitle: false,
|
||||||
titlePadding: const EdgeInsets.all(Dimens.paddingM),
|
titlePadding: const EdgeInsets.all(Dimens.paddingM),
|
||||||
|
|
|
@ -14,6 +14,7 @@ dependencies:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
intl: ^0.17.0
|
intl: ^0.17.0
|
||||||
material_color_utilities: ^0.2.0
|
material_color_utilities: ^0.2.0
|
||||||
|
permission_handler: 10.2.0
|
||||||
provider: ^6.0.4
|
provider: ^6.0.4
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
|
|
Loading…
Reference in a new issue