1

I am trying to create a downloads_page to show download Item list from localStorage. I am using flutter_downloader with flutter_inappwebview widget.

I'm getting this error while downloading file from webview in the app.

Please help me fix this soon.

ERROR ON RUNNING APP:

E/flutter: [ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: LateInitializationError: Field '_localPath@71099368' has not been initialized.
#0      _localPath (package:myapp/pages/downloads_page.dart)
#1      requestDownload (package:myapp/pages/downloads_page.dart:578:17)
<asynchronous suspension>
#2      _WebViewTabState._buildWebView.<anonymous closure> (package:myapp/webview_tab.dart:359:9)
<asynchronous suspension>

Can someone please tell how to initialize _localPath string here ?

CODE:

import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
import 'package:myapp/webview_tab.dart';
import '../models/download_list_model.dart';
import 'package:device_info_plus/device_info_plus.dart';

final downloadsPageKey = GlobalKey<_DownloadsPageState>();
late bool _saveInPublicStorage;
late String _localPath;

class DownloadsPage extends StatefulWidget with WidgetsBindingObserver {
  const DownloadsPage({super.key, required this.title, required this.platform});
  final TargetPlatform? platform;

  final String title;

  @override
  State<DownloadsPage> createState() => _DownloadsPageState();
}

// 1. a model class to store information about downloaded files:
class DownloadedFile {
  final String url;
  final String fileName;
  final String localPath;
  final int totalBytes;
  int receivedBytes;
  bool isPaused;
  bool isCancelled;

  DownloadedFile(this.url, this.fileName, this.localPath, this.totalBytes, this.receivedBytes,
      {this.isPaused = false, this.isCancelled = false});
}

// 2. stateful widget for the download page:
class _DownloadsPageState extends State<DownloadsPage> {
 
  late bool _showContent;
  late bool _permissionReady;

  final List<DownloadedFile> _downloadedFiles = [];

  final ReceivePort _port = ReceivePort();

  @override
  void initState() {
    super.initState();
    //DONE
    _bindBackgroundIsolate();

    FlutterDownloader.registerCallback(downloadCallback, step: 1);

    _showContent = false;
    _permissionReady = false;
    _saveInPublicStorage = true;
    _localPath;
    _prepare();

    _loadDownloadedFiles();
  }

  @override
  void dispose() { //done
    _unbindBackgroundIsolate();
    super.dispose();
  }
}

Future<String?> getLocalPath() async {
  final directory = await getExternalStorageDirectory();
  return directory?.path;
}

Future<void> requestDownload(String url, [String? filename]) async { //DONE
  var hasStoragePermission = await Permission.storage.isGranted;
  if (!hasStoragePermission) {
    final status = await Permission.storage.request();
    hasStoragePermission = status.isGranted;
  }
  if (hasStoragePermission) {
    final taskId = await FlutterDownloader.enqueue(
      url: url,
      headers: {},
      savedDir: _localPath,
      // fileName: fileName,
      showNotification: true,
      openFileFromNotification: true,
      saveInPublicStorage: _saveInPublicStorage,

    );
  }
}
ayushkadbe
  • 91
  • 2
  • 13

3 Answers3

0

The variable _localPath was not initialized in initState method.

José Lucas
  • 46
  • 1
  • 3
0

Your local path is where the downloaded files saved ,you need to initeate the path in your init state

in your case its something like this

_localpath = getLocalPath()

add this to your initstate

MrShakila
  • 874
  • 1
  • 4
  • 19
0

Error could be caused by the fact that the _localPath String variable is declared with the late keyword, not sure why!

late in dart is used to declare variables without assigning any values. But some value has to be assigned to late variable right before its being used.

Which is nothing but a non-nullable variable that will be initialized later. Also, variable should be initialized which is not happening anywhere in the code, in return LateInitializationError caused.

If I want to fix it, I would be calling the getLocalPath function and assign its return value to _localPath in the prepare function. Something like this:

Future<void> _prepare() async {
  // get local path
  _localPath = await getLocalPath() ?? '';

  // other initialization code
  // ...
}

Makes sense?

In this way, you should be able to avoid the LateInitializationError

Shanu
  • 311
  • 2
  • 16
Joypal
  • 178
  • 9