installed_apps_manager 1.0.0 copy "installed_apps_manager: ^1.0.0" to clipboard
installed_apps_manager: ^1.0.0 copied to clipboard

A strictly focused, high-performance Flutter plugin for managing installed applications on Android devices with native pagination and intent handling.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:installed_apps_manager/installed_apps_manager.dart';

void main() {
  runApp(const MyApp());
}

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

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Installed Apps Manager',
      theme: ThemeData(useMaterial3: true, colorSchemeSeed: Colors.blue),
      home: const AppsListScreen(),
    );
  }
}

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

  @override
  State<AppsListScreen> createState() => _AppsListScreenState();
}

class _AppsListScreenState extends State<AppsListScreen> {
  final List<AppInfo> _apps = [];
  bool _isLoading = false;
  bool _hasMore = true;
  int _offset = 0;
  final int _limit = 50;
  bool _includeSystemApps = false;

  final TextEditingController _searchController = TextEditingController();
  AppSortBy _sortBy = AppSortBy.appName;
  SortOrder _sortOrder = SortOrder.ascending;

  @override
  void initState() {
    super.initState();
    _fetchNextPage();
  }

  Future<void> _fetchNextPage() async {
    if (_isLoading || !_hasMore) return;

    setState(() => _isLoading = true);

    try {
      final page = await InstalledAppsManager.getInstalledAppsPaginated(
        includeSystemApps: _includeSystemApps,
        limit: _limit,
        offset: _offset,
        searchQuery: _searchController.text,
        sortBy: _sortBy,
        sortOrder: _sortOrder,
      );

      setState(() {
        _apps.addAll(page.items);
        _hasMore = !page.isLastPage;
        _offset += _limit;
        _isLoading = false;
      });
    } catch (e) {
      setState(() => _isLoading = false);
      if (mounted) {
        ScaffoldMessenger.of(
          context,
        ).showSnackBar(SnackBar(content: Text('Error: $e')));
      }
    }
  }

  void _refreshList() {
    setState(() {
      _apps.clear();
      _offset = 0;
      _hasMore = true;
    });
    _fetchNextPage();
  }

  void _showError(String message) {
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(message), backgroundColor: Colors.red),
      );
    }
  }

  void _showSuccess(String message) {
    if (mounted) {
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(message), backgroundColor: Colors.green),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Installed Apps'),
        actions: [
          IconButton(
            icon: Icon(
              _includeSystemApps ? Icons.android : Icons.phone_android,
            ),
            tooltip: _includeSystemApps
                ? 'Hide System Apps'
                : 'Show System Apps',
            onPressed: () {
              _includeSystemApps = !_includeSystemApps;
              _refreshList();
            },
          ),
          PopupMenuButton<AppSortBy>(
            icon: const Icon(Icons.sort),
            onSelected: (AppSortBy result) {
              if (_sortBy == result) {
                _sortOrder = _sortOrder == SortOrder.ascending
                    ? SortOrder.descending
                    : SortOrder.ascending;
              } else {
                _sortBy = result;
                _sortOrder = SortOrder.ascending;
              }
              _refreshList();
            },
            itemBuilder: (BuildContext context) => <PopupMenuEntry<AppSortBy>>[
              const PopupMenuItem<AppSortBy>(
                value: AppSortBy.appName,
                child: Text('Sort by Name'),
              ),
              const PopupMenuItem<AppSortBy>(
                value: AppSortBy.size,
                child: Text('Sort by Size'),
              ),
              const PopupMenuItem<AppSortBy>(
                value: AppSortBy.installTime,
                child: Text('Sort by Install Time'),
              ),
            ],
          ),
        ],
        bottom: PreferredSize(
          preferredSize: const Size.fromHeight(60),
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: TextField(
              controller: _searchController,
              decoration: InputDecoration(
                hintText: 'Search apps...',
                prefixIcon: const Icon(Icons.search),
                border: OutlineInputBorder(
                  borderRadius: BorderRadius.circular(30),
                ),
                contentPadding: EdgeInsets.zero,
                filled: true,
                fillColor: Theme.of(context).colorScheme.surface,
              ),
              onSubmitted: (_) => _refreshList(),
            ),
          ),
        ),
      ),
      body: _apps.isEmpty && _isLoading
          ? const Center(child: CircularProgressIndicator())
          : NotificationListener<ScrollNotification>(
              onNotification: (ScrollNotification scrollInfo) {
                if (!_isLoading &&
                    scrollInfo.metrics.pixels >=
                        scrollInfo.metrics.maxScrollExtent - 500) {
                  _fetchNextPage();
                  return true;
                }
                return false;
              },
              child: ListView.builder(
                itemCount: _apps.length + (_hasMore ? 1 : 0),
                itemBuilder: (context, index) {
                  if (index == _apps.length) {
                    return const Center(
                      child: Padding(
                        padding: EdgeInsets.all(16.0),
                        child: CircularProgressIndicator(),
                      ),
                    );
                  }

                  final app = _apps[index];
                  return ListTile(
                    leading: CircleAvatar(
                      backgroundColor: Colors.transparent,
                      backgroundImage: AppIconImageProvider(app.packageName),
                    ),
                    title: Text(app.appName),
                    subtitle: Text(
                      '${app.packageName} • ${(app.baseApkSize / 1024 / 1024).toStringAsFixed(1)} MB',
                    ),
                    trailing: PopupMenuButton<String>(
                      onSelected: (action) async {
                        try {
                          switch (action) {
                            case 'open':
                              await InstalledAppsManager.openApp(
                                app.packageName,
                              );
                              break;
                            case 'settings':
                              await InstalledAppsManager.openSettingsScreen(
                                app.packageName,
                              );
                              break;
                            case 'extract':
                              final path =
                                  await InstalledAppsManager.extractApk(
                                    app.packageName,
                                    app.appName,
                                  );
                              _showSuccess('Saved to $path');
                              break;
                            case 'save_icon':
                              final path =
                                  await InstalledAppsManager.saveAppIcon(
                                    app.packageName,
                                    app.appName,
                                  );
                              _showSuccess('Saved to $path');
                              break;
                            case 'uninstall':
                              await InstalledAppsManager.uninstallApp(
                                app.packageName,
                              );
                              break;
                          }
                        } on InstalledAppsManagerException catch (e) {
                          _showError(e.message);
                        } catch (e) {
                          _showError(e.toString());
                        }
                      },
                      itemBuilder: (context) => [
                        const PopupMenuItem(
                          value: 'open',
                          child: Text('Open App'),
                        ),
                        const PopupMenuItem(
                          value: 'settings',
                          child: Text('App Settings'),
                        ),
                        const PopupMenuItem(
                          value: 'extract',
                          child: Text('Extract APK'),
                        ),
                        const PopupMenuItem(
                          value: 'save_icon',
                          child: Text('Save Icon'),
                        ),
                        const PopupMenuItem(
                          value: 'uninstall',
                          child: Text('Uninstall'),
                        ),
                      ],
                    ),
                  );
                },
              ),
            ),
    );
  }
}
0
likes
130
points
19
downloads

Documentation

API reference

Publisher

verified publishergunjan.tech

Weekly Downloads

A strictly focused, high-performance Flutter plugin for managing installed applications on Android devices with native pagination and intent handling.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

flutter, plugin_platform_interface

More

Packages that depend on installed_apps_manager

Packages that implement installed_apps_manager