zo_app_blocker 0.0.3 copy "zo_app_blocker: ^0.0.3" to clipboard
zo_app_blocker: ^0.0.3 copied to clipboard

A Flutter plugin to block specific applications on Android.

example/lib/main.dart

import 'dart:io';
import 'package:flutter/material.dart';
import 'dart:typed_data';
import 'package:zo_app_blocker/zo_app_blocker.dart';

@pragma('vm:entry-point')
void onBlockScreenRequested() {
  ZoBlockScreenRunner.run(
    builder: (context) {
      return Scaffold(
        backgroundColor: Colors.black87,
        body: Center(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              if (context.appIcon != null)
                Image.memory(
                  context.appIcon!,
                  width: 100,
                  height: 100,
                ),
              const SizedBox(height: 24),
              Text(
                '${context.appName ?? 'App'} is Blocked!',
                style: const TextStyle(
                  color: Colors.white,
                  fontSize: 24,
                  fontWeight: FontWeight.bold,
                ),
              ),
              const SizedBox(height: 12),
              const Text(
                'You have customized this screen using Flutter.',
                style: TextStyle(color: Colors.white70),
              ),
              const SizedBox(height: 48),
              ElevatedButton.icon(
                onPressed: context.onDismiss,
                icon: const Icon(Icons.exit_to_app),
                label: const Text('Exit'),
              ),
              const SizedBox(height: 16),
              OutlinedButton.icon(
                onPressed: () async {
                  // In a real app, you would check coins here
                  // and deduct them if sufficient.
                  
                  // Unlock for 15 minutes
                  final granted = await context.onRequestUnlock?.call(
                        duration: const Duration(minutes: 15),
                      ) ??
                      false;
                  if (!granted) {
                    // Could show a snackbar or dialog if unlock failed
                  }
                },
                icon: const Icon(Icons.lock_open),
                label: const Text('Unlock temporarily (Cost: 50 coins)'),
                style: OutlinedButton.styleFrom(
                  foregroundColor: Colors.white,
                  side: const BorderSide(color: Colors.white70),
                ),
              ),
            ],
          ),
        ),
      );
    },
  );
}

void main() {
  WidgetsFlutterBinding.ensureInitialized();
  ZoAppBlocker.instance.initialize(
    blockScreenCallback: onBlockScreenRequested,
  );
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return const MaterialApp(home: HomeScreen());
  }
}

class HomeScreen extends StatefulWidget {
  const HomeScreen({super.key});

  @override
  State<HomeScreen> createState() => _HomeScreenState();
}

class _HomeScreenState extends State<HomeScreen> {
  final _zoAppBlockerPlugin = ZoAppBlocker.instance;
  String _permissionStatus = 'Unknown';
  List<Map<String, dynamic>> _blockedApps = [];

  @override
  void initState() {
    super.initState();
    _checkPermission();
    _loadBlockedApps();
    
    // Fallback native configuration (used if blockScreenCallback is not set)
    _zoAppBlockerPlugin.setNotificationConfig(
      notificationBannerTitle: 'Stop Right There!',
      notificationBannerDescription: 'You blocked this app. Get back to work!',
    );
  }

  Future<void> _checkPermission() async {
    final status = await _zoAppBlockerPlugin.checkAccessibilityPermission();
    setState(() {
      _permissionStatus = status;
    });
  }

  Future<void> _loadBlockedApps() async {
    final apps = await _zoAppBlockerPlugin.getBlockedApps();
    setState(() {
      _blockedApps = apps;
    });
  }

  Future<void> _requestPermissions() async {
    if (Platform.isAndroid) {
      await _zoAppBlockerPlugin.requestNotificationPermission();
      final notifStatus = await _zoAppBlockerPlugin.checkNotificationPermission();
      if (notifStatus != 'granted') {
        if (!mounted) return;
        ScaffoldMessenger.of(context).showSnackBar(
          const SnackBar(
            content: Text(
              'Notification permission is required for the background service.',
            ),
          ),
        );
      }
    }
    await _zoAppBlockerPlugin.requestAccessibilityPermission();
    _checkPermission();
  }

  Future<void> _selectAndBlockApps() async {
    try {
      final apps = await _zoAppBlockerPlugin.getApps();

      if (Platform.isIOS) {
        // iOS handles the picker UI and blocking internally
        _loadBlockedApps();
        return;
      }

      if (apps.isEmpty) return;
      if (!mounted) return;

      showModalBottomSheet(
        context: context,
        builder: (context) {
          return Column(
            children: [
              const Padding(
                padding: EdgeInsets.all(16.0),
                child: Text(
                  'Select an app to block',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
              ),
              Expanded(
                child: ListView.builder(
                  itemCount: apps.length,
                  itemBuilder: (context, index) {
                    final app = apps[index];
                    return ListTile(
                      leading: FutureBuilder<Uint8List?>(
                        future: _zoAppBlockerPlugin.getAppIcon(app['packageName'] ?? ''),
                        builder: (context, snapshot) {
                          if (snapshot.connectionState == ConnectionState.waiting) {
                            return const SizedBox(width: 40, height: 40, child: Padding(padding: EdgeInsets.all(8.0), child: CircularProgressIndicator(strokeWidth: 2)));
                          }
                          if (snapshot.hasData && snapshot.data != null) {
                            return Image.memory(snapshot.data!, width: 40, height: 40);
                          }
                          return const Icon(Icons.android, size: 40);
                        },
                      ),
                      title: Text(app['appName'] ?? ''),
                      subtitle: Text(app['packageName'] ?? ''),
                      onTap: () async {
                        final nav = Navigator.of(context);
                        final scaffold = ScaffoldMessenger.of(context);
                        await _zoAppBlockerPlugin.blockApps([
                          app['packageName'],
                        ]);
                        if (!mounted) return;
                        nav.pop();
                        scaffold.showSnackBar(
                          SnackBar(
                            content: Text('Blocked ${app['appName']}'),
                          ),
                        );
                        _loadBlockedApps();
                      },
                    );
                  },
                ),
              ),
            ],
          );
        },
      );
    } catch (e) {
      if (!mounted) return;
      ScaffoldMessenger.of(
        context,
      ).showSnackBar(SnackBar(content: Text('Error selecting apps: $e')));
    }
  }

  Future<void> _showActivityLog() async {
    final log = await _zoAppBlockerPlugin.getBlockActivityLog();
    if (!mounted) return;

    showModalBottomSheet(
      context: context,
      builder: (context) {
        return Column(
          children: [
            Padding(
              padding: const EdgeInsets.all(16.0),
              child: Row(
                mainAxisAlignment: MainAxisAlignment.spaceBetween,
                children: [
                  const Text(
                    'Block Activity Log',
                    style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                  ),
                  TextButton(
                    onPressed: () async {
                      await _zoAppBlockerPlugin.clearBlockActivityLog();
                      if (context.mounted) {
                        Navigator.pop(context);
                        _showActivityLog();
                      }
                    },
                    child: const Text('Clear'),
                  ),
                ],
              ),
            ),
            Expanded(
              child: log.isEmpty
                  ? const Center(child: Text('No activity yet.'))
                  : ListView.builder(
                      itemCount: log.length,
                      itemBuilder: (context, index) {
                        final entry = log[index];
                        final packageName = entry['packageName'] as String;
                        final timestamp = entry['timestamp'] as int;
                        final date = DateTime.fromMillisecondsSinceEpoch(timestamp);
                        return ListTile(
                          leading: FutureBuilder<Uint8List?>(
                            future: _zoAppBlockerPlugin.getAppIcon(packageName),
                            builder: (context, snapshot) {
                              if (snapshot.connectionState == ConnectionState.waiting) {
                                return const SizedBox(width: 32, height: 32, child: Padding(padding: EdgeInsets.all(4.0), child: CircularProgressIndicator(strokeWidth: 2)));
                              }
                              if (snapshot.hasData && snapshot.data != null) {
                                return Image.memory(snapshot.data!, width: 32, height: 32);
                              }
                              return const Icon(Icons.block, size: 32, color: Colors.grey);
                            },
                          ),
                          title: Text(packageName),
                          subtitle: Text('${date.toLocal()}'.split('.')[0]),
                        );
                      },
                    ),
            ),
          ],
        );
      },
    );
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Zo App Blocker Example')),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Text(
              'Permission Status: $_permissionStatus',
              style: const TextStyle(fontSize: 18),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _requestPermissions,
              child: const Text('Request Permissions (Android/iOS)'),
            ),
            const SizedBox(height: 16),
            ElevatedButton(
              onPressed: _selectAndBlockApps,
              child: const Text('Select Apps to Block'),
            ),
            const SizedBox(height: 8),
            ElevatedButton(
              onPressed: () async {
                final scaffold = ScaffoldMessenger.of(context);
                await _zoAppBlockerPlugin.unblockAll();
                if (!mounted) return;
                scaffold.showSnackBar(
                  const SnackBar(content: Text('All apps unblocked')),
                );
                _loadBlockedApps();
              },
              child: const Text('Unblock All Apps'),
            ),
            const SizedBox(height: 24),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                const Text(
                  'Currently Blocked Apps:',
                  style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold),
                ),
                TextButton(
                  onPressed: _showActivityLog,
                  child: const Text('Activity Log'),
                ),
              ],
            ),
            const SizedBox(height: 8),
            Expanded(
              child: _blockedApps.isEmpty
                  ? const Center(child: Text('No apps currently blocked.'))
                  : ListView.builder(
                      itemCount: _blockedApps.length,
                      itemBuilder: (context, index) {
                        final app = _blockedApps[index];
                        return ListTile(
                          leading: FutureBuilder<Uint8List?>(
                            future: _zoAppBlockerPlugin.getAppIcon(app['packageName'] ?? ''),
                            builder: (context, snapshot) {
                              if (snapshot.connectionState == ConnectionState.waiting) {
                                return const SizedBox(width: 40, height: 40, child: Padding(padding: EdgeInsets.all(8.0), child: CircularProgressIndicator(strokeWidth: 2)));
                              }
                              if (snapshot.hasData && snapshot.data != null) {
                                return Image.memory(snapshot.data!, width: 40, height: 40);
                              }
                              return const Icon(Icons.block, color: Colors.red, size: 40);
                            },
                          ),
                          title: Text(app['appName'] ?? 'Unknown App'),
                          subtitle: Text(app['packageName'] ?? ''),
                          trailing: IconButton(
                            icon: const Icon(Icons.delete, color: Colors.grey),
                            onPressed: () async {
                              final packageName = app['packageName'] as String;
                              await _zoAppBlockerPlugin.unblockApps([
                                packageName,
                              ]);
                              _loadBlockedApps();
                            },
                          ),
                        );
                      },
                    ),
            ),
          ],
        ),
      ),
    );
  }
}
3
likes
0
points
52
downloads

Publisher

verified publisherthezerone.com

Weekly Downloads

A Flutter plugin to block specific applications on Android.

Repository (GitHub)
View/report issues

License

unknown (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on zo_app_blocker

Packages that implement zo_app_blocker