Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BUG] requestPermissionExtend results in null value first time #900

Closed
Sahkay opened this issue Feb 7, 2023 · 6 comments
Closed

[BUG] requestPermissionExtend results in null value first time #900

Sahkay opened this issue Feb 7, 2023 · 6 comments

Comments

@Sahkay
Copy link

Sahkay commented Feb 7, 2023

Describe the bug
When using PhotoManager.requestPermissionExtend() (I am testing on Android API 31), it results in a null value when run for the first time for that app even if permissions are granted. Repeating the future after permissions are applied works fine, just the first time has the issue. There are no observable errors.

To Reproduce
Steps to reproduce the behavior:

  1. Wait for PhotoManager.requestPermissionExtend()
  2. The future completes as null

Expected behavior
The future should wait until the user selects the permission option and then complete with the permission value.

Screenshots
If applicable, add screenshots to help explain your problem.

Flutter version
[✓] Flutter (Channel stable, 3.7.1, on macOS 12.4 21F79 darwin-x64, locale en-AU)
• Flutter version 3.7.1 on channel stable at ~/flutter
• Upstream repository https://github.com/flutter/flutter.git
• Framework revision 7048ed95a5 (6 days ago), 2023-02-01 09:07:31 -0800
• Engine revision 800594f1f4
• Dart version 2.19.1
• DevTools version 2.20.1

[!] Android toolchain - develop for Android devices (Android SDK version 33.0.0)
• Android SDK at ~/Library/Android/sdk
• Platform android-33, build-tools 33.0.0
• Java binary at: /Library/Java/JavaVirtualMachines/temurin-8.jdk/Contents/Home/bin/java
• Java version OpenJDK Runtime Environment (Temurin)(build 1.8.0_302-b08)
✗ Android license status unknown.
Run flutter doctor --android-licenses to accept the SDK licenses.
See https://flutter.dev/docs/get-started/install/macos#android-setup for more details.

[✓] Xcode - develop for iOS and macOS (Xcode 13.4.1)
• Xcode at /Applications/Xcode.app/Contents/Developer
• Build 13F100
• CocoaPods version 1.11.3

[✓] Chrome - develop for the web
• Chrome at /Applications/Google Chrome.app/Contents/MacOS/Google Chrome

[!] Android Studio (version 2022.1)
• Android Studio at /Applications/Android Studio.app/Contents
• Flutter plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/9212-flutter
• Dart plugin can be installed from:
🔨 https://plugins.jetbrains.com/plugin/6351-dart
✗ Unable to find bundled Java version.
• Try updating or re-installing Android Studio.

[✓] VS Code (version 1.73.1)
• VS Code at /Applications/Visual Studio Code.app/Contents
• Flutter extension version 3.42.0
Scanning for devices is taking a long time...[✓] Connected device (3 available)
• sdk gphone64 x86 64 (mobile) • emulator-5554 • android-x64 • Android 12 (API 31) (emulator)
• macOS (desktop) • macos • darwin-x64 • macOS 12.4 21F79 darwin-x64
• Chrome (web) • chrome • web-javascript • Google Chrome 110.0.5481.77

[✓] HTTP Host Availability
• All required HTTP hosts are available

Smartphone (please complete the following information):

  • Device: Pixel 5 Emulator
  • OS: Android
  • Version Api 31
@AlexV525
Copy link
Member

AlexV525 commented Feb 8, 2023

There are no observable errors.

If the permission request returns null, there must be a NPE exception. Please re-identify which method is wrong and provide usage code, logs and screen recordings.

@wanbinkimoon

This comment was marked as off-topic.

@Sahkay
Copy link
Author

Sahkay commented Feb 9, 2023

logcat via android studio shows no messages at level error or higher.
Screen recording will provide no extra information for this issue.
Here is some example code

import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';

class MediaLibraryScreen extends StatefulWidget {
  final String? mediaType;
  final AssetPathEntity? folder;
  final bool multiple;

  const MediaLibraryScreen({this.mediaType, this.folder, this.multiple = false, Key? key}) : super(key: key);

  @override
  State<MediaLibraryScreen> createState() => _MediaLibraryScreenState();
}

class _MediaLibraryScreenState extends State<MediaLibraryScreen> {
  Future<dynamic>? mediaLibraryRequest;

  @override
  Widget build(BuildContext context) {
    mediaLibraryRequest ??= Future.wait([
      PhotoManager.requestPermissionExtend(),
      widget.folder == null ? PhotoManager.getAssetPathList() : widget.folder!.getAssetListPaged(page: 0, size: 50),
    ]);
    return Scaffold(
      body: SafeArea(
        child: FutureBuilder(
          future: mediaLibraryRequest,
          builder: (context, snapshot) {
            if (snapshot.hasData) {
              PermissionState mediaPerms = snapshot.data[0] as PermissionState;
              List<dynamic> assetList = snapshot.data[1];
              if (mediaPerms.hasAccess) {
                return GridView.count(
                  primary: true,
                  crossAxisCount: 3,
                  children: [
                    ...assetList
                        .map((item) =>
                        Container(
                          child: Text(item.name),
                        ))
                        .toList(),
                  ],
                );
              } else if (snapshot.data[0] != null) {
                return Center(child: Text("Test"));
              } else {
                return Column(
                  mainAxisAlignment: MainAxisAlignment.center,
                  children: [
                    Text("Media Permissions were denied"),
                    OutlinedButton(
                      child: Text("Open Settings"),
                      onPressed: () => PhotoManager.openSetting(),
                    ),
                  ],
                );
              }
            } else if (snapshot.connectionState == ConnectionState.done) {
              return Center(child: Text(snapshot.data?[0] ?? "null"));
            } else {
              return const Center(
                child: CircularProgressIndicator(),
              );
            }
          },
        ),
      ),
    );
  }
}

In the example code, if the page is opened for the first time, after the prompt is accepted for file access, the text "null" is shown on screen due to the else if.

@Sahkay Sahkay closed this as completed Feb 9, 2023
@Sahkay Sahkay reopened this Feb 9, 2023
@Sahkay
Copy link
Author

Sahkay commented Feb 9, 2023

Sorry clicked close with comment by accident.

@Sahkay
Copy link
Author

Sahkay commented Feb 9, 2023

I found the cause of the issue, when running the double future in the example it causes the error but running the requestPermissionExtend on its own, the issue does not occur. So the issue either lies with the future waiting or with the PhotoManager.getAssetPathList() running with requestPermissionExtend. There is also the fact that getAssetPathList is returning an empty list even when there is a photo in the downloads folder.

@AlexV525
Copy link
Member

AlexV525 commented Feb 9, 2023

mediaLibraryRequest ??= Future.wait([
PhotoManager.requestPermissionExtend(),
widget.folder == null ? PhotoManager.getAssetPathList() : widget.folder!.getAssetListPaged(page: 0, size: 50),
]);

This is an invalid usage. Please follow the simple example which already described how to integrate with the plugin.

Regarding the empty list, see #852.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants