add button settings, and no sleep for devices

This commit is contained in:
Samsularifin01 2026-06-11 23:09:39 +07:00
parent eb3fd7aca3
commit 30321e051c
3 changed files with 138 additions and 2 deletions

View File

@ -5,12 +5,14 @@ import android.os.Build
import android.os.VibrationEffect import android.os.VibrationEffect
import android.os.Vibrator import android.os.Vibrator
import android.os.VibratorManager import android.os.VibratorManager
import android.view.WindowManager
import io.flutter.embedding.android.FlutterActivity import io.flutter.embedding.android.FlutterActivity
import io.flutter.embedding.engine.FlutterEngine import io.flutter.embedding.engine.FlutterEngine
import io.flutter.plugin.common.MethodChannel import io.flutter.plugin.common.MethodChannel
class MainActivity : FlutterActivity() { class MainActivity : FlutterActivity() {
private val vibrationChannel = "smart_vision_assist/vibration" private val vibrationChannel = "smart_vision_assist/vibration"
private val screenChannel = "smart_vision_assist/screen"
override fun configureFlutterEngine(flutterEngine: FlutterEngine) { override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
super.configureFlutterEngine(flutterEngine) super.configureFlutterEngine(flutterEngine)
@ -31,6 +33,30 @@ class MainActivity : FlutterActivity() {
else -> result.notImplemented() else -> result.notImplemented()
} }
} }
MethodChannel(
flutterEngine.dartExecutor.binaryMessenger,
screenChannel
).setMethodCallHandler { call, result ->
when (call.method) {
"setKeepScreenOn" -> {
val enabled = call.argument<Boolean>("enabled") ?: false
setKeepScreenOn(enabled)
result.success(null)
}
else -> result.notImplemented()
}
}
}
private fun setKeepScreenOn(enabled: Boolean) {
runOnUiThread {
if (enabled) {
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} else {
window.clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}
}
} }
private fun vibrate(milliseconds: Long): Boolean { private fun vibrate(milliseconds: Long): Boolean {

View File

@ -5,6 +5,7 @@ import 'dart:ui' as ui;
import 'package:camera/camera.dart'; import 'package:camera/camera.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../services/tts_service.dart'; import '../services/tts_service.dart';
@ -19,7 +20,10 @@ class CameraScreen extends StatefulWidget {
State<CameraScreen> createState() => _CameraScreenState(); State<CameraScreen> createState() => _CameraScreenState();
} }
class _CameraScreenState extends State<CameraScreen> { class _CameraScreenState extends State<CameraScreen> with WidgetsBindingObserver {
static const MethodChannel _screenChannel =
MethodChannel("smart_vision_assist/screen");
CameraController? controller; CameraController? controller;
List<CameraDescription>? cameras; List<CameraDescription>? cameras;
@ -36,15 +40,31 @@ class _CameraScreenState extends State<CameraScreen> {
Timer? _vibrationTimer; Timer? _vibrationTimer;
bool _isLoggingOut = false; bool _isLoggingOut = false;
bool _isStatusActive = true;
String _lastSpokenMessage = ""; String _lastSpokenMessage = "";
DateTime? _lastSpokenAt; DateTime? _lastSpokenAt;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
WidgetsBinding.instance.addObserver(this);
unawaited(_setKeepScreenOn(true));
initCamera(); initCamera();
} }
Future<void> _setKeepScreenOn(bool enabled) async {
try {
await _screenChannel.invokeMethod<void>(
"setKeepScreenOn",
{"enabled": enabled},
);
} on MissingPluginException {
// Platform selain Android boleh mengabaikan fitur ini.
} catch (_) {
// Jangan sampai kegagalan wakelock mengganggu kamera.
}
}
Future<void> initCamera() async { Future<void> initCamera() async {
try { try {
cameras = await availableCameras(); cameras = await availableCameras();
@ -281,15 +301,91 @@ class _CameraScreenState extends State<CameraScreen> {
await _tts.speak(message); await _tts.speak(message);
} }
Future<bool> _confirmDeactivateAccount() async {
final bool? confirmed = await showDialog<bool>(
context: context,
builder: (BuildContext confirmationContext) {
return AlertDialog(
title: const Text("Konfirmasi"),
content: const Text("Apakah anda yakin menonaktifkan akun ini?"),
actions: [
TextButton(
onPressed: () => Navigator.of(confirmationContext).pop(false),
child: const Text("Tidak"),
),
TextButton(
onPressed: () => Navigator.of(confirmationContext).pop(true),
child: const Text("Ya"),
),
],
);
},
);
return confirmed ?? false;
}
void _showSettings() {
showDialog<void>(
context: context,
builder: (BuildContext dialogContext) {
return StatefulBuilder(
builder: (BuildContext context, StateSetter setDialogState) {
return AlertDialog(
title: const Text("Setting"),
content: SwitchListTile(
contentPadding: EdgeInsets.zero,
title: const Text("Status"),
subtitle: Text(_isStatusActive ? "Aktif" : "Nonaktif"),
value: _isStatusActive,
onChanged: (bool value) async {
if (!value) {
final bool isConfirmed =
await _confirmDeactivateAccount();
if (!isConfirmed || !mounted) {
return;
}
}
setState(() {
_isStatusActive = value;
});
setDialogState(() {});
},
),
actions: [
TextButton(
onPressed: () => Navigator.of(dialogContext).pop(),
child: const Text("Tutup"),
),
],
);
},
);
},
);
}
@override @override
void dispose() { void dispose() {
_detectionTimer?.cancel(); _detectionTimer?.cancel();
_vibrationTimer?.cancel(); _vibrationTimer?.cancel();
WidgetsBinding.instance.removeObserver(this);
unawaited(_setKeepScreenOn(false));
unawaited(_vibrationService.stop()); unawaited(_vibrationService.stop());
controller?.dispose(); controller?.dispose();
super.dispose(); super.dispose();
} }
@override
void didChangeAppLifecycleState(AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
unawaited(_setKeepScreenOn(true));
} else {
unawaited(_setKeepScreenOn(false));
}
}
Widget buildCameraPreview() { Widget buildCameraPreview() {
final Size? previewSize = controller?.value.previewSize; final Size? previewSize = controller?.value.previewSize;
if (previewSize == null) { if (previewSize == null) {
@ -421,6 +517,20 @@ class _CameraScreenState extends State<CameraScreen> {
), ),
), ),
), ),
Positioned(
bottom: 40,
left: MediaQuery.of(context).size.width / 2 - 130,
child: Semantics(
label: "Buka setting",
button: true,
child: FloatingActionButton(
heroTag: "camera_settings",
backgroundColor: Colors.black,
onPressed: _showSettings,
child: const Icon(Icons.settings, color: Colors.white),
),
),
),
], ],
), ),
), ),

View File

@ -5,7 +5,7 @@ class ApiConfig {
static const bool useAndroidEmulator = false; static const bool useAndroidEmulator = false;
// Ganti IP ini dengan IP laptop/PC Anda saat menggunakan HP fisik (ADB). // Ganti IP ini dengan IP laptop/PC Anda saat menggunakan HP fisik (ADB).
static const String deviceHost = "192.168.110.147:8000"; static const String deviceHost = "192.168.0.31:8000";
static String get baseUrl { static String get baseUrl {
if (Platform.isAndroid && useAndroidEmulator) { if (Platform.isAndroid && useAndroidEmulator) {