screen_pinning 1.0.0
screen_pinning: ^1.0.0 copied to clipboard
Flutter plugin for Android screen pinning, kiosk mode, and lock task mode. Supports both managed (device owner/admin) and unmanaged devices. Uses native Android app pinning and lock task features for [...]
example/lib/main.dart
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:screen_pinning/screen_pinning.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
// Example: Initialize with configuration
final config = ScreenPinningConfig(
keepScreenOn: true, // Keep screen always on
immersiveMode: true, // Hide system UI
autoStart: false, // Don't auto-start (demo app)
preventScreenshots: false,
preferredOrientations: null, // Allow all orientations
);
await ScreenPinningHelper().initialize(config);
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Screen Pinning Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
useMaterial3: true,
),
home: const ScreenPinningDemo(),
);
}
}
class ScreenPinningDemo extends StatefulWidget {
const ScreenPinningDemo({super.key});
@override
State<ScreenPinningDemo> createState() => _ScreenPinningDemoState();
}
class _ScreenPinningDemoState extends State<ScreenPinningDemo> {
final helper = ScreenPinningHelper();
bool _isLoading = false;
bool _isDeviceOwner = false;
@override
void initState() {
super.initState();
_initialize();
}
Future<void> _initialize() async {
final isOwner = await helper.isDeviceOwner();
if (mounted) {
setState(() {
_isDeviceOwner = isOwner;
});
}
}
Future<void> _toggleScreenPinning() async {
if (helper.isScreenPinningEnabled) {
// Stop screen pinning
setState(() => _isLoading = true);
await helper.stopScreenPinning();
if (mounted) {
setState(() => _isLoading = false);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Screen pinning disabled'),
backgroundColor: Colors.blue,
),
);
}
} else {
// Start screen pinning
final confirmed = await ScreenPinningHelper.showConfirmationDialog(context);
if (confirmed && mounted) {
setState(() => _isLoading = true);
await helper.startScreenPinning();
if (mounted) {
setState(() => _isLoading = false);
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Text('Screen pinning dialog shown. Please confirm.'),
backgroundColor: Colors.blue,
),
);
}
}
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Screen Pinning Demo'),
centerTitle: true,
),
body: Padding(
padding: const EdgeInsets.all(24.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
// Status Card
Card(
elevation: 4,
child: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
children: [
Icon(
helper.isScreenPinningEnabled ? Icons.lock : Icons.lock_open,
size: 64,
color: helper.isScreenPinningEnabled ? Colors.green : Colors.grey,
),
const SizedBox(height: 16),
Text(
'Screen Pinning',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: 8),
Text(
helper.isScreenPinningEnabled ? 'ENABLED' : 'DISABLED',
style: Theme.of(context).textTheme.headlineSmall?.copyWith(
color: helper.isScreenPinningEnabled ? Colors.green : Colors.grey,
fontWeight: FontWeight.bold,
),
),
],
),
),
),
const SizedBox(height: 24),
// Feature Status Cards
Card(
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Plugin Features Status',
style: Theme.of(context).textTheme.titleMedium?.copyWith(
fontWeight: FontWeight.bold,
),
),
const SizedBox(height: 12),
_buildFeatureRow('Keep Screen On', helper.isKeepScreenOnEnabled),
const Divider(),
_buildFeatureRow('Immersive Mode', helper.isImmersiveModeEnabled),
const Divider(),
_buildFeatureRow('Screen Pinned', helper.isPinned),
],
),
),
),
const SizedBox(height: 16),
// Device Owner Status
Container(
padding: const EdgeInsets.all(16),
decoration: BoxDecoration(
color: _isDeviceOwner ? Colors.green.shade50 : Colors.orange.shade50,
borderRadius: BorderRadius.circular(8),
border: Border.all(
color: _isDeviceOwner ? Colors.green.shade200 : Colors.orange.shade200,
),
),
child: Row(
children: [
Icon(
_isDeviceOwner ? Icons.verified : Icons.info_outline,
color: _isDeviceOwner ? Colors.green : Colors.orange,
),
const SizedBox(width: 12),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
_isDeviceOwner ? 'Device Owner' : 'Not Device Owner',
style: const TextStyle(fontWeight: FontWeight.bold),
),
Text(
_isDeviceOwner
? 'Full lock task mode available'
: 'Using screen pinning mode',
style: const TextStyle(fontSize: 12),
),
],
),
),
],
),
),
const SizedBox(height: 32),
// Toggle Button
ElevatedButton.icon(
onPressed: _isLoading ? null : _toggleScreenPinning,
icon: _isLoading
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(strokeWidth: 2),
)
: Icon(
helper.isScreenPinningEnabled ? Icons.lock_open : Icons.lock,
),
label: Text(
helper.isScreenPinningEnabled
? 'Stop Screen Pinning'
: 'Start Screen Pinning',
),
style: ElevatedButton.styleFrom(
padding: const EdgeInsets.symmetric(vertical: 16),
backgroundColor: helper.isScreenPinningEnabled
? Colors.red
: Colors.green,
foregroundColor: Colors.white,
),
),
const SizedBox(height: 16),
// Info Text
Text(
helper.isScreenPinningEnabled
? 'To exit: Hold Back + Recent Apps buttons'
: 'Tap button above to pin this screen',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.bodySmall,
),
],
),
),
);
}
Widget _buildFeatureRow(String label, bool enabled) {
return Padding(
padding: const EdgeInsets.symmetric(vertical: 4.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(label),
Row(
children: [
Icon(
enabled ? Icons.check_circle : Icons.cancel,
color: enabled ? Colors.green : Colors.grey,
size: 20,
),
const SizedBox(width: 8),
Text(
enabled ? 'ON' : 'OFF',
style: TextStyle(
color: enabled ? Colors.green : Colors.grey,
fontWeight: FontWeight.bold,
),
),
],
),
],
),
);
}
}