Skip to content Skip to sidebar Skip to footer

Flutter - How To Download Asset When Apps Launched And Used It

currently, my apps have many assets (images, sound, font, json, SQL-lite database file, etc). All have defined in pubspec.yaml However, due to a request to reduce APK size, I need

Solution 1:

The easiest way to do it is to download your files as zip (archived file) and unpack them in the path of the application storage directory getApplicationDocumentsDirectory

You will use this list of packages: archive , http and path_provider

The pubspec.yaml will look like

version:1.0.0+1environment:sdk:">=2.1.0 <3.0.0"dependencies:flutter:sdk:flutterpath_provider:^1.1.0http:^0.12.0+2archive:^2.0.8dev_dependencies:flutter_test:sdk:flutteruses-material-design:trueassets:-assets/images/

The main.dart file which coronations your app will look like Note that api is the URL of your file without the file name.

main.dart

import'dart:io';

import'package:archive/archive.dart';
import'package:flutter/material.dart';
import'package:http/http.dart'as http;
import'package:path_provider/path_provider.dart';

import'data.dart';

const api =
    'https://firebasestorage.googleapis.com/v0/b/playground-a753d.appspot.com/o';

enumAppTheme { candy, cocktail }

voidmain() => runApp(MyApp());

classMyAppextendsStatelessWidget {
  @overrideWidgetbuild(BuildContext context) {
    returnMaterialApp(
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(AppTheme.candy),
    );
  }
}

classMyHomePageextendsStatefulWidget {
  final AppTheme theme;

  MyHomePage(this.theme);

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class_MyHomePageStateextendsState<MyHomePage> {
  AppTheme _theme;
  String _dir;
  List<String> _images;

  @overridevoidinitState() {
    super.initState();
    _theme = widget.theme;
    _images = data[_theme];
  }

  @overrideWidgetbuild(BuildContext context) {
    returnScaffold(
      floatingActionButton: FloatingActionButton(
        child: Icon(Icons.style),
        onPressed: () async {
          if (_theme == AppTheme.candy) {
            await_downloadAssets('cocktail');
          }
          setState(() {
            _theme =
                _theme == AppTheme.candy ? AppTheme.cocktail : AppTheme.candy;
            _images = data[_theme];
          });
        },
      ),
      body: ListView.builder(
          itemCount: _images.length,
          itemBuilder: (BuildContext context, int index) {
            return_getImage(_images[index], _dir);
          }),
    );
  }

  Widget_getImage(String name, String dir) {
    if (_theme != AppTheme.candy) {
      var file = _getLocalImageFile(name, dir);
      returnImage.file(file);
    }
    returnImage.asset('assets/images/$name');
  }

  File_getLocalImageFile(String name, String dir) => File('$dir/$name');

  Future<void> _downloadAssets(String name) async {
    if (_dir == null) {
      _dir = (awaitgetApplicationDocumentsDirectory()).path;
    }

    if (!await_hasToDownloadAssets(name, _dir)) {
      return;
    }
    var zippedFile = await_downloadFile(
        '$api/$name.zip?alt=media&token=7442d067-a656-492f-9791-63e8fc082379',
        '$name.zip',
        _dir);

    var bytes = zippedFile.readAsBytesSync();
    var archive = ZipDecoder().decodeBytes(bytes);

    for (var file in archive) {
      var filename = '$_dir/${file.name}';
      if (file.isFile) {
        var outFile = File(filename);
        outFile = await outFile.create(recursive: true);
        await outFile.writeAsBytes(file.content);
      }
    }
  }

  Future<bool> _hasToDownloadAssets(String name, String dir) async {
    var file = File('$dir/$name.zip');
    return !(await file.exists());
  }

  Future<File> _downloadFile(String url, String filename, String dir) async {
    var req = await http.Client().get(Uri.parse(url));
    var file = File('$dir/$filename');
    return file.writeAsBytes(req.bodyBytes);
  }
}

Then you have to list all files and added them (logically to the corresponding theme)

data.dart:

import'main.dart' show AppTheme;

constMap<AppTheme, List<String>> data = const {
  AppTheme.candy: [
    'art-background-blue-1289363.jpg',
    'assortment-bright-candy-1043519.jpg',
    'bright-candies-cherry-1405760.jpg',
    'bright-candies-colorful-539447.jpg',
    'bright-candy-chewy-1328885.jpg',
  ],
  AppTheme.cocktail: [
    'alcohol-alcoholic-beverage-beverage-1304540.jpg',
    'alcohol-alcoholic-beverage-beverage-1723638.jpg',
    'alcohol-black-background-close-up-800390.jpg',
    'alcoholic-beverage-beverage-cocktail-970197.jpg',
    'bar-beverage-blur-338713.jpg',
  ]
};

For more information check this Github project and Medium article

Post a Comment for "Flutter - How To Download Asset When Apps Launched And Used It"