Как загружать фотографии не в основной каталог flutter?

Честно скажу, скрипт не мой. Купленный и знания тут у меня меньше чем хотелось бы. Суть такова: есть мобильное приложение flutter с бэкендом. Приложение грузит данные (фотографии и текст) с сайта, при обновлении перезаписывает текст, но дублирует картинки, бесконечно множив их в корневой папке Андроида В итоге после 10 обновлении по кнопке у человека на телефоне будет захламлена память наглухо.

Как указать приложению flutter, чтобы загрузка данных происходила не в папке /внутренная память/Pictures/ А как в телеграмме, где ты загружаешь фотографию, она видна в диалоге, но не отображается в папке и в галерее, если её предварительно не скачать. Как реализовать данный функционал? Мне индус, который делал данный скрипт, сказал, что это не реализуемо. Но в телеге же как то есть. Как вариант, скачивается файл в определенном расширении, например в .tg, а само приложение интерпретирует как jpeg/png Ну или я не знаю. Если кратко то два вопроса:

  1. Как решить проблему с дублированием фотографий при обновлении с сайта, удалении приложения и установки его снова
  2. Как скрыть фотографии с галереи, чтобы они не захламляли галерею пользователя, а лежали ничком где-нибудь в папке и не светились

import 'dart:io';
import 'dart:typed_data';

import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter_story_app_online_2_8_22/PrefData.dart';
import 'package:flutter_story_app_online_2_8_22/model/ModelSubCategory.dart';
import 'package:flutter_story_app_online_2_8_22/model/ModelSubCategory.dart'
    as subCategory;

import 'package:image_gallery_saver/image_gallery_saver.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:uri_to_file/uri_to_file.dart';

import '../ConstantDatas.dart';
import '../SizeConfig.dart';
import '../model/ModelHomeBanner.dart';
import '../model/ModelMainCategory.dart';
import '../model/ModelMyStory.dart';
import '../services/MainCategoryServices.dart';
import 'package:http/http.dart' as http;

class OfflineData {
  static String categoryBox = "category_data";
  static String myStoryBox = "my_story_data";
  static String sliderBox = "slider_data";
  static String isFirstTime = "first_time";
  static String keyReadQuickStory = "read_quick_story";
  static String keyReadQuickCategory = "read_quick_category";

  static downloadAllData(Function function) async {
    //    DataHelper dataHelper= DataHelper();
    //
    //
    // // await   dataHelper.init();
    // await   dataHelper.getAllData();

    // try {
    //   await DataHelper.init();
    //   await DataHelper.getAllData();
    //
    // } catch (e) {
    //   print(e);
    // }

    print("permission====true");

    // bool isPermission = await requestFilePermission();

    // print("permission====$isPermission");

    // if(isPermission) {
    await downloadSliderData();
    await downloadCategoryData();

    await downloadMyStoryData().then((value) async {
      SharedPreferences prefs = await SharedPreferences.getInstance();
      prefs.setBool(isFirstTime, false);
      function(true);
    });
    // }else{
    //   function(false);
    // }
  }

  static Future<bool> getIsFirstTime() async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    return await prefs.getBool(isFirstTime) ?? true;
  }

  static checkData(Function function) async {
    OfflineData.getIsFirstTime().then((value) async {
      if (value) {
        await downloadAllData(function);
      } else {
        function(true);
      }
    });
  }

  static Future<bool> requestFilePermission() async {
    PermissionStatus result;
    // In Android we need to request the storage permission,
    // while in iOS is the photos permission
    if (Platform.isAndroid) {
      result = await Permission.storage.request();
    } else {
      result = await Permission.accessMediaLocation.request();
    }

    // Directory directory = Platform.isAndroid
    //     ? await getExternalStorageDirectory() //FOR ANDROID
    //     : await getApplicationSupportDirectory(); //FOR iOS

    // Map<Permission, PermissionStatus> result = await [
    //   Permission.location,
    //   Permission.photos,
    // ].request();
    //
    //

    print("object====${result.isGranted}");
    if (result.isGranted) {
      // imageSection = ImageSection.browseFiles;
      return true;
    }
    // else if (Platform.isIOS || result.isPermanentlyDenied) {
    //
    // } else {
    //
    // }
    return false;
  }

  static setQuickReadStory(String storyId, String categoryId) async {
    SharedPreferences prefs = await SharedPreferences.getInstance();
    prefs.setString(keyReadQuickStory, storyId);
    prefs.setString(keyReadQuickCategory, categoryId);
  }

  // static setData(String key, String data) async {
  //   SharedPreferences prefs =await SharedPreferences.getInstance();
  //    prefs.setString(key, data);
  // }

  static getKeyFromID(String id) {
    return categoryBox + "_" + id;
  }

  // static getData(
  //   String key,
  // ) async {
  //   SharedPreferences prefs = await SharedPreferences.getInstance();
  //   await prefs.getString(key) ?? '';
  // }

  static downloadSliderData() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    ModelHomeBanner modelHomeBanner = await getAllHomeBanner();
    if (modelHomeBanner.data!.success == 1) {
      List<Homebanner> list1 = [];

      List<Homebanner> list = modelHomeBanner.data!.homebanner!;

      await Future.forEach(list, (item) async {
        Homebanner homebanner = item as Homebanner;

        print("path12121212========${item.image}");

        String? path = await save(item.image ?? "");
        // String? path = await save(item.image??"");

        print("path====${path}====${item.image}");

        homebanner.image = path ?? '';

        print("path====${path}====${homebanner.image}");

        list1.add(homebanner);
      });

      prefs.setString(sliderBox, Homebanner.encode(list1));

      // await setData(sliderBox, Homebanner.encode(list1));

      // final String? musicsString = await getData(sliderBox);
      final String? musicsString = await prefs.getString(sliderBox);

      final List<Homebanner> musics = Homebanner.decode(musicsString!);

      print("list====${musics.length}");
    }
  }
static Future<bool> getIsAlreadyExists(String s) async {

  String filePath = await PrefData().getDummyPath();


  String imgPath = filePath+"/"+s;


  print("imgPath===$imgPath");

  return await File(imgPath).exists();




}

  static Future<String> getImagePath(String s) async {

    String filePath = await PrefData().getDummyPath();


    String imgPath = filePath+"/"+s;

    return imgPath;




  }

  static Future<String> save(String image) async {
    // return '';
    if (image.trim().isEmpty) {
      return '';
    }

    DateTime dateTime = DateTime.now();

    List<String>? s = image.trim().split(".");

    String imageName = "hello_${dateTime.microsecond}";
    //
    if( s.length > 0){
      imageName = s[0];
    }


    bool isExists = await getIsAlreadyExists(imageName);

    if(isExists){
      return await getImagePath(imageName);
    }


    final http.Response responseData =
        await http.get(Uri.parse(ConstantDatas.uploadUrl + image.trim()));


    if (responseData.bodyBytes.length <= 0) {
      return '';
    }

    // var response = await Dio().get(ConstantDatas.uploadUrl + image,
    //     options: Options(responseType: ResponseType.bytes));
    final result = await ImageGallerySaver.saveImage(responseData.bodyBytes,
        quality: 60,
        isReturnImagePathOfIOS: true,
        name: imageName);
    print("result===${result}");



    // if( s.length > 1){
    //   String uri = await convertUriToFile(result["filePath"]);
    //
    //
    //   String newPAth = new File(uri).parent.path.toString().replaceAll("'","")+"/"+imageName+" (1)."+s[1];
    //
    //
    //   print("new===$newPAth");
    //
    //   bool b = await new File(newPAth).exists();
    //
    //   if(b){
    //     await new File(newPAth).delete();
    //   }
    //
    // }



    // return '';
    return result["filePath"];
  }

  static Future<List<Homebanner>> getAllHomeBannerList() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    // final String? data = await getData(sliderBox);

    final String? data = await prefs.getString(sliderBox);

    print("data12==$data");

    return Homebanner.decode(data!) ?? [];
  }

  static Future<List<Category>> getAllCategoryList() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    final String? data = await prefs.getString(categoryBox);

    print("data12==$data");

    List<Category> list = Category.decode(data!) ?? [];

    list = await sortList(list);

    list = list.reversed.toList();

    return list;
  }

  static sortList(List<Category> list) async {
    list.sort((a, b) => b.categoryId!.compareTo(a.categoryId!));

    return list;
  }

  static Future<List<subCategory.Story>> getMyStoryList() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    final String? data = await prefs.getString(myStoryBox);

    print("data12==$data");

    return subCategory.Story.decode(data!) ?? [];
  }

  static Future<subCategory.Story?> getQuickReadStory() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    String id = await prefs.getString(keyReadQuickStory) ?? '';
    String catId = await prefs.getString(keyReadQuickCategory) ?? '';

    print("sfasfsdf===$id");

    if (id.isEmpty || catId.isEmpty) {
      return null;
    }

    subCategory.Story? category;

    final String? data = await prefs.getString(getKeyFromID(catId));

    print("data12==$data");

    await Future.forEach(subCategory.Story.decode(data!), (item) async {
      subCategory.Story story = item as subCategory.Story;

      print("storyId===${story.storyId}===$id");

      if (story.storyId == id) {
        category = story;
      }
    });

    return category == null ? null : category;
  }

  static getOfflineImageWidget(String image) {
    return FutureBuilder<String>(
        builder: (context, snapshot) {
          if (snapshot.data != null && snapshot.data!.isNotEmpty) {
            return Image.file(
              File(snapshot.data!),
              width: SizeConfig.safeBlockHorizontal! * 90,
              height: double.infinity,
              fit: BoxFit.cover,
            );
          }
          return Container();
        },
        future: OfflineData.convertUriToFile(image));
  }

  static Future<List<subCategory.Story>> getAllStoryFromCategoryId(
      String id) async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    final String? data = await prefs.getString(getKeyFromID(id));

    print("data12==$data");

    return subCategory.Story.decode(data!);
  }

  static Future downloadCategoryData() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();

    ModelMainCategory modelMainCategory = await getAllCats();
    if (modelMainCategory.data!.success == 1) {
      List<Category> list1 = [];

      List<Category> list = modelMainCategory.data!.category!;

      await Future.forEach(list, (item) async {
        Category category = item as Category;

        print("catId===${category.categoryId}");
        String? path = await save(category.image ?? "");
        category.image = path;
        list1.add(category);
      });

      prefs.setString(categoryBox, Category.encode(list1));

      await Future.forEach(list, (item) async {
        Category category = item as Category;
        ModelSubCategory modelSubCategory =
            await getAllSubCategoryList(category.categoryId!);
        if (modelSubCategory.data != null &&
            modelSubCategory.data!.success == 1 &&
            modelSubCategory.data!.story != null) {
          List<subCategory.Story> subCatList = [];
          // subCatList.addAll(modelSubCategory.data!.story!);

          await Future.forEach(modelSubCategory.data!.story!, (item) async {
            subCategory.Story category = item as subCategory.Story;

            String? path = await save(category.image ?? "");

            print("path====${path}====${item.image}");

            category.image = path ?? '';

            // print("path====${path}====${homebanner.image}");

            subCatList.add(category);
          });

          prefs.setString(getKeyFromID(category.categoryId!),
              subCategory.Story.encode(subCatList));

        }
      });


      // final List<Homebanner> musics = Homebanner.decode(musicsString!);
      // print("list====${musics.length}");

    }
  }

  static Future downloadMyStoryData() async {
    final SharedPreferences prefs = await SharedPreferences.getInstance();
    ModelMyStory modelMainCategory = await getMYStories();
    if (modelMainCategory.data!.success == 1) {
      List<subCategory.Story> list1 = [];
      List<subCategory.Story> list = modelMainCategory.data!.story!;
      await Future.forEach(list, (item) async {
        subCategory.Story category = item as subCategory.Story;
        String? path = await save(category.image ?? "");
        category.image = path;
        list1.add(category);
      });
      prefs.setString(myStoryBox, subCategory.Story.encode(list1));
    }
  }

  static Future<String> convertUriToFile(String uriString) async {
    try {
      File file = await toFile(uriString);
      return file.path;
    } on UnsupportedError catch (e) {
      print(e.message);
      return '';
    } on IOException catch (e) {
      print(e);
      return '';
    } catch (e) {
      print(e);
      return '';
    }
  }
}


Ответы (0 шт):