Как загружать фотографии не в основной каталог flutter?
Честно скажу, скрипт не мой. Купленный и знания тут у меня меньше чем хотелось бы. Суть такова: есть мобильное приложение flutter с бэкендом. Приложение грузит данные (фотографии и текст) с сайта, при обновлении перезаписывает текст, но дублирует картинки, бесконечно множив их в корневой папке Андроида В итоге после 10 обновлении по кнопке у человека на телефоне будет захламлена память наглухо.
Как указать приложению flutter, чтобы загрузка данных происходила не в папке /внутренная память/Pictures/ А как в телеграмме, где ты загружаешь фотографию, она видна в диалоге, но не отображается в папке и в галерее, если её предварительно не скачать. Как реализовать данный функционал? Мне индус, который делал данный скрипт, сказал, что это не реализуемо. Но в телеге же как то есть. Как вариант, скачивается файл в определенном расширении, например в .tg, а само приложение интерпретирует как jpeg/png Ну или я не знаю. Если кратко то два вопроса:
- Как решить проблему с дублированием фотографий при обновлении с сайта, удалении приложения и установки его снова
- Как скрыть фотографии с галереи, чтобы они не захламляли галерею пользователя, а лежали ничком где-нибудь в папке и не светились
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 '';
}
}
}