app_installer_plus 1.2.0 copy "app_installer_plus: ^1.2.0" to clipboard
app_installer_plus: ^1.2.0 copied to clipboard

PlatformAndroid

Easily download and install Android APKs from direct URLs. Includes granular progress metrics, cancellation support, and secure FileProvider integration.

example/lib/main.dart

import 'package:app_installer_plus/app_installer_plus.dart';
import 'package:app_installer_plus/core/enums/download_error_type.dart';
import 'package:app_installer_plus/core/exceptions/file_download_exception.dart';
import 'package:app_installer_plus/core/helper/app_helper.dart';
import 'package:flutter/material.dart';

void main() {
  runApp(const MaterialApp(home: MyApp()));
}

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

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  final TextEditingController _urlController = TextEditingController();
  double downloadPercent = 0;
  String totalSize = "0";
  String downloadSpeed = "0";
  String timeLeft = "0";
  String downloadedSize = "0";

  final OutlineInputBorder _border = const OutlineInputBorder(
    borderRadius: BorderRadius.all(Radius.circular(12)),
    borderSide: BorderSide(color: Colors.black),
  );

  @override
  void dispose() {
    _urlController.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      /// Bg Color
      backgroundColor: Colors.white,

      /// App Bar
      appBar: AppBar(
        title: const Text("App Update Example"),
        centerTitle: true,
      ),

      /// Body
      body: Center(
        child: SingleChildScrollView(
          child: Column(
            mainAxisAlignment: MainAxisAlignment.center,
            children: [
              /// Url Text Form Filed
              Padding(
                padding: const EdgeInsets.all(12.0),
                child: TextFormField(
                  controller: _urlController,
                  decoration: InputDecoration(
                    hintText: "Paste your download file URL here",
                    border: _border,
                    enabledBorder: _border,
                    focusedBorder: _border,
                    hintFadeDuration: const Duration(milliseconds: 350),
                  ),
                ),
              ),

              /// Progress Bar
              Padding(
                padding: const EdgeInsets.all(12),
                child: Stack(
                  alignment: Alignment.center,
                  children: [
                    CircularProgressIndicator(
                      value: downloadPercent,
                      strokeCap: StrokeCap.round,
                      strokeWidth: 5,
                      strokeAlign: 4,
                      backgroundColor: Colors.grey.shade100,
                    ),
                    Text("${(downloadPercent * 100).toStringAsFixed(0)}%"),
                  ],
                ),
              ),

              /// Download Info
              Padding(
                padding: const EdgeInsets.all(12.0),
                child: Column(
                  spacing: 10,
                  children: [
                    Row(
                      children: [
                        Expanded(child: Text("Total Size")),
                        Text(totalSize),
                      ],
                    ),
                    Row(
                      children: [
                        Expanded(child: Text("Download Speed")),
                        Text(downloadSpeed),
                      ],
                    ),
                    Row(
                      children: [
                        Expanded(child: Text("Downloaded Size")),
                        Text(downloadedSize),
                      ],
                    ),
                    Row(
                      children: [
                        Expanded(child: Text("Estimated Time Left")),
                        Text(timeLeft),
                      ],
                    ),
                    Row(
                      children: [
                        Expanded(child: Text("Process")),
                        Text("$downloadedSize / $totalSize"),
                      ],
                    ),
                  ],
                ),
              ),

              /// Download and Install Button and Remove APK Button
              Row(
                children: [
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(12.0).copyWith(top: 15),
                      child: FilledButton(
                        onPressed: () async {
                          if (_urlController.text.trim().isEmpty) {
                            showSnackBar(message: "Url is mandatory");
                            return;
                          }
                          await onDownloadClicked();
                        },
                        child: const Text("Download & Install"),
                      ),
                    ),
                  ),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(12),
                      child: FilledButton(
                        onPressed: () async {
                          bool isDeleted = await AppInstallerPlus()
                              .removedDownloadedApk(downloadFileName: "test");
                          if (isDeleted) {
                            showSnackBar(message: "Apk Deleted Successfully");
                          } else {
                            showSnackBar(
                              message:
                                  "Deletion UnSuccessful. Either the file does not exist or an error occurred.",
                            );
                          }
                        },
                        child: const Text("Delete Apk"),
                      ),
                    ),
                  ),
                ],
              ),

              Row(
                children: [
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(12),
                      child: FilledButton(
                        onPressed: () async {
                          await AppInstallerPlus().cancelDownload(
                            deletePartialDownload: true,
                          );
                        },
                        child: const Text("Cancel Request"),
                      ),
                    ),
                  ),
                  Expanded(
                    child: Padding(
                      padding: const EdgeInsets.all(12),
                      child: FilledButton(
                        onPressed: () async {
                          setState(() {
                            downloadPercent = 0;
                            totalSize = "0";
                            downloadSpeed = "0";
                            timeLeft = "0";
                            downloadedSize = "0";
                          });
                        },
                        child: const Text("Clear"),
                      ),
                    ),
                  ),
                ],
              ),
            ],
          ),
        ),
      ),
    );
  }

  Future<void> onDownloadClicked() async {
    try {
      await AppInstallerPlus().downloadAndInstallApk(
        downloadFileUrl: _urlController.text,
        downloadFileName: "test",
        onDownloadedSize: (downloadedSize2) {
          printLog("Downloaded Size: $downloadedSize bytes");
          setState(() {
            downloadedSize = downloadedSize2;
          });
        },
        onTotalSize: (size) {
          printLog("Total Size : $size bytes/s");
          setState(() {
            totalSize = size;
          });
        },
        onSpeed: (speed) {
          printLog("Download Speed: $speed bytes/s");
          setState(() {
            downloadSpeed = speed;
          });
        },
        onTimeLeft: (timeLeft2) {
          printLog("Estimated Time Left: $timeLeft seconds");
          setState(() {
            timeLeft = timeLeft2;
          });
        },
        onProgress: (progress) {
          setState(() {
            downloadPercent = progress;
          });
        },
      );
    } on FileDownloadException catch (e) {
      String? errorMessage;
      switch (e.type) {
        case DownloadErrorType.cancelled:
          errorMessage = "Request Cancelled";
          break;
        case DownloadErrorType.storageAccessDenied:
          errorMessage =
              "Storage access denied. Please grant permissions and try again.";
          break;
        case DownloadErrorType.badResponse:
          errorMessage =
              "bad response from server. Please check the URL and try again.";
          break;
        case DownloadErrorType.networkTimeout:
          errorMessage =
              "Timeout. Please check your internet connection and try again.";
          break;
        case DownloadErrorType.noInternetConnection:
          errorMessage =
              "No internet connection. Please check your connection and try again.";
          break;
        case DownloadErrorType.unknown:
          errorMessage = "An unknown error occurred. Please try again.";
          break;
        case DownloadErrorType.alreadyRunning:
          errorMessage =
              "A download task is currently active. Please wait for it to finish or cancel it.";
          break;
      }

      showSnackBar(message: errorMessage);
    } catch (e) {
      showSnackBar(message: "An error occurred: $e");
    }
  }

  void showSnackBar({required String message}) {
    ScaffoldMessenger.of(context).showSnackBar(
      SnackBar(
        content: Text(message),
        behavior: SnackBarBehavior.floating,
        shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
      ),
    );
  }
}
1
likes
160
points
217
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

Easily download and install Android APKs from direct URLs. Includes granular progress metrics, cancellation support, and secure FileProvider integration.

Repository (GitHub)
View/report issues

License

MIT (license)

Dependencies

dio, flutter, path_provider, plugin_platform_interface

More

Packages that depend on app_installer_plus

Packages that implement app_installer_plus