flutter-permission-handler icon indicating copy to clipboard operation
flutter-permission-handler copied to clipboard

final permission = Permission.manageExternalStorage.request();

Open tluanga opened this issue 2 years ago • 9 comments

While using Pemission handler inside main function it throws an exception. void main() async { final permission = Permission.manageExternalStorage.request(); if (await permission.isGranted){ } Error: Exception has occurred. _CastError (Null check operator used on a null value)

tluanga avatar Jul 25 '21 07:07 tluanga

Hi @tluanga,

This is probably caused by the the Flutter activity not being registered with Android yet.

Please make sure to call WidgetsFlutterBinding.ensureInitialized() method before you make any calls to the permission_handler (this would be true for any plugin b.t.w.)

mvanbeusekom avatar Jul 25 '21 20:07 mvanbeusekom

Permission.manageExternalStorage.request() Issue.

env: version 8.1.6, version 6.1.1, Android 10

Permission.manageExternalStorage.request() return "restricted" in version 8.1.6, but return "denied" (this is supposed) in version 6.1.1.

Issue 1: : permission status: test code 1: var status = await Permission.manageExternalStorage.status;

returns: PermissionStatus.restricted in version 8.1.6, but PermissionStatus.denied in version 6.1.1, both has following exception log: _D/permissions_handler( 8074): No permissions found in manifest for: []22

Issue 2: : no permission request happens. test code 2: status = await Permission.manageExternalStorage.request() do nothing and does not pops up permission request dialog, and has log: _D/permissions_handler( 8074): No permissions found in manifest for: []22

For test code 2: double-check the AndroidManifest.xml file for main, debug, profile. all have:

    <!-- %%INSERT_PERMISSIONS -->
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Potential solution tries:

1 Flutter clean and WidgetsFlutterBinding.ensureInitialized() does not help.

CellCS avatar Sep 17 '21 19:09 CellCS

One finding:

  1. Following function: plugin 6.1.1 return denied, 8.1.6 returns restricted, but it is permanentDenied. 6.1.1 and 8.1.6 return false about "await Permission.manageExternalStorage.isPermanentlyDenied"

(the reason for me to use 6.1.1, camera permission is partiallyly correct in 6.1.1)

__Permission p = Permission.manageExternalStorage;
var status = await p.status;__

CellCS avatar Sep 21 '21 16:09 CellCS

Hi @CellCS, for the manageExternalStorage permission you need another line in your AndroidManifest than you mentioned. The line you need to add is as follows:

<!-- Permissions options for the `manage external storage` group -->
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

Then you can try the flutter clean followed by the flutter pub get, let me know if it worked, thanks in advance!

JDDV avatar Sep 30 '21 10:09 JDDV

@JDDV I am having the same issue, I tried flutter clean but I am still facing an issue, there is no popup for confirming and the status comes as restricted for Permission.manageExternalStorage.

Manifest debug:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <!-- Flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    
</manifest>

Manifest profile:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <!-- Flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
</manifest>

Manifest main:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
   <application
        android:label="yt_player"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:requestLegacyExternalStorage="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <!-- Displays an Android View that continues showing the launch screen
                 Drawable until Flutter paints its first frame, then this splash
                 screen fades out. A splash screen is useful to avoid any visual
                 gap between the end of Android's launch screen and the painting of
                 Flutter's first frame. -->
            <meta-data
              android:name="io.flutter.embedding.android.SplashScreenDrawable"
              android:resource="@drawable/launch_background"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

shessafridi avatar Oct 11 '21 16:10 shessafridi

@JDDV thanks, no lucky. tried with add in AndroidManifest, tried flutter clean followed by flutter pub get

CellCS avatar Oct 11 '21 16:10 CellCS

@JDDV I am having the same issue, I tried flutter clean but I am still facing an issue, there is no popup for confirming and the status comes as restricted for Permission.manageExternalStorage.

Manifest debug:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <!-- Flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    
</manifest>

Manifest profile:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <!-- Flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
</manifest>

Manifest main:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
   <application
        android:label="yt_player"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:requestLegacyExternalStorage="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <!-- Displays an Android View that continues showing the launch screen
                 Drawable until Flutter paints its first frame, then this splash
                 screen fades out. A splash screen is useful to avoid any visual
                 gap between the end of Android's launch screen and the painting of
                 Flutter's first frame. -->
            <meta-data
              android:name="io.flutter.embedding.android.SplashScreenDrawable"
              android:resource="@drawable/launch_background"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

Issue fixed I moved the android:requestLegacyExternalStorage="true" to the application tag

shessafridi avatar Oct 25 '21 13:10 shessafridi

@JDDV I am having the same issue, I tried flutter clean but I am still facing an issue, there is no popup for confirming and the status comes as restricted for Permission.manageExternalStorage. Manifest debug:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <!-- Flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
    
</manifest>

Manifest profile:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <!-- Flutter needs it to communicate with the running application
         to allow setting breakpoints, to provide hot reload, etc.
    -->
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
</manifest>

Manifest main:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.yt_player">
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
   <application
        android:label="yt_player"
        android:icon="@mipmap/ic_launcher">
        <activity
            android:name=".MainActivity"
            android:launchMode="singleTop"
            android:theme="@style/LaunchTheme"
            android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
            android:hardwareAccelerated="true"
            android:requestLegacyExternalStorage="true"
            android:windowSoftInputMode="adjustResize">
            <!-- Specifies an Android theme to apply to this Activity as soon as
                 the Android process has started. This theme is visible to the user
                 while the Flutter UI initializes. After that, this theme continues
                 to determine the Window background behind the Flutter UI. -->
            <meta-data
              android:name="io.flutter.embedding.android.NormalTheme"
              android:resource="@style/NormalTheme"
              />
            <!-- Displays an Android View that continues showing the launch screen
                 Drawable until Flutter paints its first frame, then this splash
                 screen fades out. A splash screen is useful to avoid any visual
                 gap between the end of Android's launch screen and the painting of
                 Flutter's first frame. -->
            <meta-data
              android:name="io.flutter.embedding.android.SplashScreenDrawable"
              android:resource="@drawable/launch_background"
              />
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER"/>
            </intent-filter>
        </activity>
        <!-- Don't delete the meta-data below.
             This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
        <meta-data
            android:name="flutterEmbedding"
            android:value="2" />
    </application>
</manifest>

Issue fixed I moved the android:requestLegacyExternalStorage="true" to the application tag

still giving error any solution???

laxkarparas1 avatar Nov 12 '21 12:11 laxkarparas1

This happens to me in a weird mode. An app raises the following error:

Unhandled Exception: Null check operator used on a null value

But another app, same code to request for permissions works perfectly.

neoacevedo avatar Mar 20 '22 00:03 neoacevedo

It seems to work fine on Android 13 Example app. Do you have some additional information regarding Android version that you are testing on?

Kind regards,

TimHoogstrate avatar Aug 24 '23 09:08 TimHoogstrate

@TimHoogstrate facing the same issue the device is Android 10

Rizwan201 avatar Sep 04 '23 11:09 Rizwan201

Hi @Rizwan201,

The MANAGE_EXTERNAL_STORAGE permission is introduced in Android API 30 (which relates to Android 11) as a replacement for the READ_EXTERNAL_STORAGE and WRITE_EXTERNAL_STORAGE permissions.

As a developer it is currently your responsibility to validate which Android version your app is running on and request the appropriate permission.

I am going to go ahead and close this issue as the original problem was solved by making sure the ensureInitialized method was called before accessing the permission_handler.

mvanbeusekom avatar Sep 12 '23 13:09 mvanbeusekom