fluttercommunity / flutter_downloader

Flutter Downloader - A plugin for creating and managing download tasks.
https://pub.dev/packages/flutter_downloader
BSD 3-Clause "New" or "Revised" License
915 stars 515 forks source link

BUG change status when loading is complete, API 28 (android 9) #907

Open DmitriySimonov opened 1 year ago

DmitriySimonov commented 1 year ago

flutter_downloader 1.11.4

BUG change status when loading is complete, API 28 (android 9)

I am attaching the logs изображение

With 100% progress, the status should be DownloadTaskStatus.complete On API 29-33 works correctly

flutter doctor -v [✓] Flutter (Channel stable, 3.13.7, on Ubuntu 22.04.3 LTS 5.15.0-87-generic, locale ru_RU.UTF-8) • Flutter version 3.13.7 on channel stable at /home/dmitriysi/snap/flutter/common/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision 2f708eb839 (2 недели назад), 2023-10-09 09:58:08 -0500 • Engine revision a794cf2681 • Dart version 3.1.3 • DevTools version 2.25.0

[✓] Android toolchain - develop for Android devices (Android SDK version 34.0.0-rc1) • Android SDK at /home/dmitriysi/androidStudio/sdk • Platform android-34, build-tools 34.0.0-rc1 • Java binary at: /home/dmitriysi/androidStudio/android-studio/jbr/bin/java • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231) • All Android licenses accepted.

[✓] Chrome - develop for the web • Chrome at google-chrome

[✓] Linux toolchain - develop for Linux desktop • clang version 10.0.0-4ubuntu1 • cmake version 3.16.3 • ninja version 1.10.0 • pkg-config version 0.29.1

[✓] Android Studio (version 2022.3) • Android Studio at /home/dmitriysi/androidStudio/android-studio • Flutter plugin version 75.1.2 • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 17.0.6+0-17.0.6b829.9-10027231)

[✓] Connected device (3 available) • AOSP on IA Emulator (mobile) • emulator-5554 • android-x86 • Android 9 (API 28) (emulator) • Linux (desktop) • linux • linux-x64 • Ubuntu 22.04.3 LTS 5.15.0-87-generic • Chrome (web) • chrome • web-javascript • Google Chrome 108.0.5359.98

[✓] Network resources • All expected network resources are available.

Code example:

  @override
  void initState() {
    super.initState();
    IsolateNameServer.registerPortWithName(_port.sendPort, ISOLATE_KEY);
    _port.listen((dynamic data) {
      //String id = data[0];
      final DownloadTaskStatus status = DownloadTaskStatus.fromInt(data[1]);
      final int progress = data[2];
      blocContext.read<UpdateScreenBloc>().add(UpdateScreenProgressLoading(progress, status));
    });`

  FutureOr<void> _onUpdateScreenProgressLoading(
    UpdateScreenProgressLoading event,
    Emitter<UpdateScreenState> emit,
  ) {
    FLog.info(text: 'Загрузка обновления progress ${event.progress}, status: ${event.status}');
    switch (event.status) {
      case DownloadTaskStatus.undefined:
        emit(UpdateScreenLoadingError(LocaleKeys.updateScreen_errorDownloadUpdate.tr()));
        break;
      case DownloadTaskStatus.enqueued:
        emit(UpdateScreenLoading(event.progress));
        break;
      case DownloadTaskStatus.running:
        emit(UpdateScreenLoading(event.progress));
        break;
      case DownloadTaskStatus.complete:
        emit(UpdateScreenInstall(newVrsn));
        break;
      case DownloadTaskStatus.failed:
        emit(UpdateScreenLoadingError(LocaleKeys.updateScreen_errorDownloadUpdate.tr()));
        break;
      case DownloadTaskStatus.canceled:
        emit(UpdateScreenLoadingError(LocaleKeys.updateScreen_downloadCanceled.tr()));
        break;
      case DownloadTaskStatus.paused:
        emit(UpdateScreenLoadingError(LocaleKeys.updateScreen_downloadPaused.tr()));
        break;
    }
  }
qwertylolman commented 1 year ago

you need to ask for WRITE_EXTERNAL_STORAGE permission

DmitriySimonov commented 1 year ago

you need to ask for WRITE_EXTERNAL_STORAGE permission

It did not help

I am use

        compileSdkVersion = 34
        targetSdkVersion = 34

even if I add these lines to the manifest, nothing will change

    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    ....
    android:requestLegacyExternalStorage="true"

https://developer.android.com/about/versions/11/privacy/storage Target Android 11

If your app targets Android 11, both the WRITE_EXTERNAL_STORAGE permission and the WRITE_MEDIA_STORAGE privileged permission no longer provide any additional access.

Keep in mind that, on devices that run Android 10 (API level 29) or higher, your app can contribute to well-defined media collections such as MediaStore.Downloads without requesting any storage-related permissions. Learn more about how to request only the necessary permissions when working with media files in your app.

qwertylolman commented 1 year ago

did you request the permission? writing permission in manifest is not enough. also, check that permission is granted in app settings.

DmitriySimonov commented 1 year ago

I don't need permission because I'm saving the file to my phone's internal memory NOT ExternalStorage

qwertylolman commented 1 year ago

could you show the FlutterDownloader.enqueue method call and passed arguments?

DmitriySimonov commented 1 year ago

On api 29 I tried different installation paths, but the error persists

 String path = await NetworkUtils.generateFullPath(
      path: '/update/apk',
      api: NetworkEngine.MOBILE_API,
      serverService: _serverService,
    );

    String? accessToken = await _authenticationService.getAccessToken();
    if (accessToken == null || accessToken.isEmpty) {
      throw ('accessToken is null');
    }

    try {
      final IFileUpdateManager fileUpdateManager = FileUpdateManager();
      final String saveDir = await fileUpdateManager.directoryPath();
      final String fileName = fileUpdateManager.getFileName(version);

      final String? result = await FlutterDownloader.enqueue(
        url: path,
        //url: 'https://speed.hetzner.de/100MB.bin', // для отладки
        headers: {
          HttpHeaders.authorizationHeader: NetworkEngine.BEARER + accessToken,
        },
        savedDir: saveDir,
        showNotification: true,
        fileName: fileName,
        openFileFromNotification: true,
      );
      return result;
    } catch (e) {
      rethrow;
    }

  Future<String> directoryPath() async {
    final Directory? dir = await getExternalStorageDirectory();
    if (dir == null) {
      FLog.error(text: 'Нет директории getExternalStorageDirectory!, вернем пустую строку');
      return '';
    }

    final Directory dirUpdate = Directory('${dir.path}/update');
    dirUpdate.createSync();
    return dirUpdate.path;
  }

image

balajiks-dev commented 9 months ago

@DmitriySimonov yes the package having this issue sometimes. As of now, call your function if(progress == 100). You have to call your function in status completed also since progress == 100 won't work sometimes. Call the function in both conditions. Note that It's a temporary solution.

wengxianxun commented 8 months ago

When will this bug be fixed?

wengxianxun commented 8 months ago

@DmitriySimonov是的,有时软件包会出现此问题。现在,调用您的函数 if(progress == 100)。 您还必须在已完成状态下调用函数,因为进度== 100有时不起作用。在两种情况下调用该函数。 请注意,这是一个临时解决方案。

When will this bug be fixed?