plus_plugins icon indicating copy to clipboard operation
plus_plugins copied to clipboard

[Bug]: Android share and edit image from temp dir causes permission exception

Open EnduringBeta opened this issue 2 years ago • 18 comments

Platform

Android 12

Plugin

share_plus

Version

6.3.0

Flutter SDK

3.3.0

Steps to reproduce

Steps

  1. Run this repo and branch (screenshot) on an Android device.
  2. Touch the floating action button, which should use the screenshot package to create an image of a red/blue widget and bring up the Share bottom sheet.
  3. Ensure you are viewing the logs.
  4. Tap "Edit". Confirm you see the following exception...
E/DatabaseUtils( 2431): Writing exception to parcel
E/DatabaseUtils( 2431): java.lang.SecurityException: Permission Denial: writing dev.fluttercommunity.plus.share.ShareFileProvider uri content://com.example.flutterbug.flutter.share_provider/cache/testFile-0.png from pid=415, uid=10184 requires the provider be exported, or grantUriPermission()
E/DatabaseUtils( 2431): 	at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:907)
E/DatabaseUtils( 2431): 	at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:712)
E/DatabaseUtils( 2431): 	at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:679)
E/DatabaseUtils( 2431): 	at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:488)
E/DatabaseUtils( 2431): 	at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:272)
E/DatabaseUtils( 2431): 	at android.os.Binder.execTransactInternal(Binder.java:1179)
E/DatabaseUtils( 2431): 	at android.os.Binder.execTransact(Binder.java:1143)

Thoughts

This app stores the screenshot PNG file in the temporary directory. There are SO posts and resources for this exception, but few focused on Flutter. The ones that are encourage adding a <provider> tag in the AndroidManifest.xml, which I was unsuccessful at doing properly.

When I looked at share_plus's AndroidManifest.xml, it has a <provider>, though for a sub directory. I'm skeptical I should be duplicating or near-duplicating this.

I'm new to this aspect, so I'm open to this not being a bug at all. If it's not, though, I believe my confusion might deserve a documentation update to guide future folks.

Code Sample

https://github.com/EnduringBeta/flutter-bug/tree/screenshot

Here's the core function


  // This bug happens without the Screenshot plugin, as well.
  // It applies on Android when sharing an image and tapping "Edit".
  // I haven't tested iOS.
  void _screenshotShareAndCount() async {
    Uint8List bytes = await screenshotController.captureFromWidget(
      Container(
          padding: const EdgeInsets.all(30.0),
          decoration: BoxDecoration(
            border: Border.all(color: Colors.blueAccent, width: 5.0),
            color: Colors.redAccent,
          ),
          child: const Text("This is an invisible widget")),
    );

    final String tempDir = (await getTemporaryDirectory()).path;
    final String filePath =
        "$tempDir${Platform.pathSeparator}testFile-$_counter.png";
    debugPrint(filePath);
    final File file = File(filePath);
    try {
      file.writeAsBytesSync(bytes);
    } catch (e) {
      debugPrint(e.toString());
      return null;
    }

    Share.shareXFiles([XFile(filePath)]);

    setState(() {
      _counter++;
    });
  }

Logs

[ +544 ms] √  Built build\app\outputs\flutter-apk\app-debug.apk.
[   +2 ms] executing: C:\Users\ross\AppData\Local\Android\sdk\build-tools\33.0.1\aapt dump xmltree C:\Users\ross\projects\flutter-bug\build\app\outputs\flutter-apk\app.apk AndroidManifest.xml
[  +22 ms] Exit code 0 from: C:\Users\ross\AppData\Local\Android\sdk\build-tools\33.0.1\aapt dump xmltree C:\Users\ross\projects\flutter-bug\build\app\outputs\flutter-apk\app.apk AndroidManifest.xml
[        ] N: android=http://schemas.android.com/apk/res/android
             E: manifest (line=2)
               A: android:versionCode(0x0101021b)=(type 0x10)0x1
               A: android:versionName(0x0101021c)="1.0.0" (Raw: "1.0.0")
               A: android:compileSdkVersion(0x01010572)=(type 0x10)0x21
               A: android:compileSdkVersionCodename(0x01010573)="13" (Raw: "13")
               A: package="com.example.flutterbug" (Raw: "com.example.flutterbug")
               A: platformBuildVersionCode=(type 0x10)0x21
               A: platformBuildVersionName=(type 0x10)0xd
               E: uses-sdk (line=7)
                 A: android:minSdkVersion(0x0101020c)=(type 0x10)0x10
                 A: android:targetSdkVersion(0x01010270)=(type 0x10)0x1f
               E: uses-permission (line=15)
                 A: android:name(0x01010003)="android.permission.INTERNET" (Raw: "android.permission.INTERNET")
               E: permission (line=17)
                 A: android:name(0x01010003)="com.example.flutterbug.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" (Raw: "com.example.flutterbug.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION")
                 A: android:protectionLevel(0x01010009)=(type 0x11)0x2
               E: uses-permission (line=21)
                 A: android:name(0x01010003)="com.example.flutterbug.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION" (Raw: "com.example.flutterbug.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION")
               E: application (line=23)
                 A: android:label(0x01010001)="flutter-bug" (Raw: "flutter-bug")
                 A: android:icon(0x01010002)=@0x7f080000
                 A: android:name(0x01010003)="android.app.Application" (Raw: "android.app.Application")
                 A: android:debuggable(0x0101000f)=(type 0x12)0xffffffff
                 A: android:appComponentFactory(0x0101057a)="androidx.core.app.CoreComponentFactory" (Raw: "androidx.core.app.CoreComponentFactory")
                 E: activity (line=29)
                   A: android:theme(0x01010000)=@0x7f0a0000
                   A: android:name(0x01010003)="com.example.flutterbug.MainActivity" (Raw: "com.example.flutterbug.MainActivity")
                   A: android:exported(0x01010010)=(type 0x12)0xffffffff
                   A: android:launchMode(0x0101001d)=(type 0x10)0x1
                   A: android:configChanges(0x0101001f)=(type 0x11)0x40003fb4
                   A: android:windowSoftInputMode(0x0101022b)=(type 0x11)0x10
                   A: android:hardwareAccelerated(0x010102d3)=(type 0x12)0xffffffff
                   E: meta-data (line=44)
                     A: android:name(0x01010003)="io.flutter.embedding.android.NormalTheme" (Raw: "io.flutter.embedding.android.NormalTheme")
                     A: android:resource(0x01010025)=@0x7f0a0001
                   E: intent-filter (line=48)
                     E: action (line=49)
                       A: android:name(0x01010003)="android.intent.action.MAIN" (Raw: "android.intent.action.MAIN")
                     E: category (line=51)
                       A: android:name(0x01010003)="android.intent.category.LAUNCHER" (Raw: "android.intent.category.LAUNCHER")
                 E: meta-data (line=66)
                   A: android:name(0x01010003)="flutterEmbedding" (Raw: "flutterEmbedding")
                   A: android:value(0x01010024)=(type 0x10)0x2
                 E: provider (line=73)
                   A: android:name(0x01010003)="dev.fluttercommunity.plus.share.ShareFileProvider" (Raw: "dev.fluttercommunity.plus.share.ShareFileProvider")
                   A: android:exported(0x01010010)=(type 0x12)0x0
                   A: android:authorities(0x01010018)="com.example.flutterbug.flutter.share_provider" (Raw: "com.example.flutterbug.flutter.share_provider")
                   A: android:grantUriPermissions(0x0101001b)=(type 0x12)0xffffffff
                   E: meta-data (line=78)
                     A: android:name(0x01010003)="android.support.FILE_PROVIDER_PATHS" (Raw: "android.support.FILE_PROVIDER_PATHS")
                     A: android:resource(0x01010025)=@0x7f0c0000
                 E: receiver (line=86)
                   A: android:name(0x01010003)="dev.fluttercommunity.plus.share.SharePlusPendingIntent" (Raw: "dev.fluttercommunity.plus.share.SharePlusPendingIntent")
                   A: android:exported(0x01010010)=(type 0x12)0xffffffff
                   E: intent-filter (line=89)
                     E: action (line=90)
                       A: android:name(0x01010003)="EXTRA_CHOSEN_COMPONENT" (Raw: "EXTRA_CHOSEN_COMPONENT")
                 E: uses-library (line=94)
                   A: android:name(0x01010003)="androidx.window.extensions" (Raw: "androidx.window.extensions")
                   A: android:required(0x0101028e)=(type 0x12)0x0
                 E: uses-library (line=97)
                   A: android:name(0x01010003)="androidx.window.sidecar" (Raw: "androidx.window.sidecar")
                   A: android:required(0x0101028e)=(type 0x12)0x0
[   +2 ms] Stopping app 'app.apk' on Pixel 3.
[        ] executing: C:\Users\ross\AppData\Local\Android\sdk\platform-tools\adb.exe -s 8C5X1JCQQ shell am force-stop com.example.flutterbug
[ +110 ms] executing: C:\Users\ross\AppData\Local\Android\sdk\platform-tools\adb.exe -s 8C5X1JCQQ shell pm list packages com.example.flutterbug
[  +87 ms] package:com.example.flutterbug
[        ] executing: C:\Users\ross\AppData\Local\Android\sdk\platform-tools\adb.exe -s 8C5X1JCQQ shell cat /data/local/tmp/sky.com.example.flutterbug.sha1
[  +93 ms] c86c251e0cc1a14309fdc94526415b3b34b660dc
[        ] Latest build already installed.
[        ] executing: C:\Users\ross\AppData\Local\Android\sdk\platform-tools\adb.exe -s 8C5X1JCQQ shell -x logcat -v time -t 1
[ +103 ms] --------- beginning of main
                    11-29 12:40:15.555 D/ProcessState( 3491): Binder ioctl to enable oneway spam detection failed: Invalid argument
[   +4 ms] executing: C:\Users\ross\AppData\Local\Android\sdk\platform-tools\adb.exe -s 8C5X1JCQQ shell am start -a android.intent.action.MAIN -c android.intent.category.LAUNCHER -f 0x20000000 --ez enable-dart-profiling true --ez
enable-checked-mode true --ez verify-entry-points true com.example.flutterbug/com.example.flutterbug.MainActivity
[  +98 ms] Starting: Intent { act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x20000000 cmp=com.example.flutterbug/.MainActivity (has extras) }
[        ] Waiting for observatory port to be available...
[ +707 ms] Observatory URL on device: http://127.0.0.1:39923/G3MHPHgrWYI=/
[        ] executing: C:\Users\ross\AppData\Local\Android\sdk\platform-tools\adb.exe -s 8C5X1JCQQ forward tcp:0 tcp:39923
[  +25 ms] 51045
[        ] Forwarded host port 51045 to device port 39923 for Observatory
[   +4 ms] Caching compiled dill
[  +28 ms] Connecting to service protocol: http://127.0.0.1:51045/G3MHPHgrWYI=/
[ +184 ms] Launching a Dart Developer Service (DDS) instance at http://127.0.0.1:0, connecting to VM service at http://127.0.0.1:51045/G3MHPHgrWYI=/.
[ +118 ms] DDS is listening at http://127.0.0.1:51048/Qppso3QMTUI=/.
[  +38 ms] Successfully connected to service protocol: http://127.0.0.1:51045/G3MHPHgrWYI=/
[  +56 ms] DevFS: Creating new filesystem on the device (null)
[  +30 ms] DevFS: Created new filesystem on the device (file:///data/user/0/com.example.flutterbug/code_cache/flutter-bugEJHAAX/flutter-bug/)
[   +1 ms] Updating assets
[  +69 ms] Syncing files to device Pixel 3...
[   +1 ms] Compiling dart to kernel with 0 updated files
[        ] Processing bundle.
[        ] <- recompile package:flutter_bug/main.dart 372ce75a-6508-4c42-aff4-7ac45e89e8ba
[        ] <- 372ce75a-6508-4c42-aff4-7ac45e89e8ba
[   +1 ms] Bundle processing done.
[ +107 ms] Updating files.
[        ] DevFS: Sync finished
[   +1 ms] Syncing files to device Pixel 3... (completed in 111ms)
[        ] Synced 0.0MB.
[   +1 ms] <- accept
[   +3 ms] Connected to _flutterView/0x77acbfc3e0.
[   +2 ms] Flutter run key commands.
[   +1 ms] r Hot reload. 
[        ] R Hot restart.
[        ] h List all available interactive commands.
[        ] d Detach (terminate "flutter run" but leave application running).
[        ] c Clear the screen
[        ] q Quit (terminate the application on the device).
[        ]  Running with sound null safety 
[        ] An Observatory debugger and profiler on Pixel 3 is available at: http://127.0.0.1:51048/Qppso3QMTUI=/
[ +526 ms] I/Gralloc4( 3508): mapper 4.x is not supported
[        ] W/Gralloc3( 3508): mapper 3.x is not supported
[        ] W/Gralloc4( 3508): allocator 4.x is not supported
[        ] W/Gralloc3( 3508): allocator 3.x is not supported
[   +6 ms] The Flutter DevTools debugger and profiler on Pixel 3 is available at: http://127.0.0.1:9101?uri=http://127.0.0.1:51048/Qppso3QMTUI=/
[+3979 ms] I/flutter ( 3508): /data/user/0/com.example.flutterbug/cache/testFile-0.png
[  +30 ms] D/CompatibilityChangeReporter( 3508): Compat change id reported: 160794467; UID 10342; state: ENABLED
[+1839 ms] E/DatabaseUtils( 3508): Writing exception to parcel
[        ] E/DatabaseUtils( 3508): java.lang.SecurityException: Permission Denial: writing dev.fluttercommunity.plus.share.ShareFileProvider uri content://com.example.flutterbug.flutter.share_provider/cache/testFile-0.png from pid=415, uid=10184   
requires the provider be exported, or grantUriPermission()
[        ] E/DatabaseUtils( 3508):      at android.content.ContentProvider.enforceWritePermissionInner(ContentProvider.java:907)
[        ] E/DatabaseUtils( 3508):      at android.content.ContentProvider$Transport.enforceWritePermission(ContentProvider.java:712)
[        ] E/DatabaseUtils( 3508):      at android.content.ContentProvider$Transport.enforceFilePermission(ContentProvider.java:679)
[        ] E/DatabaseUtils( 3508):      at android.content.ContentProvider$Transport.openAssetFile(ContentProvider.java:488)
[        ] E/DatabaseUtils( 3508):      at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:272)
[        ] E/DatabaseUtils( 3508):      at android.os.Binder.execTransactInternal(Binder.java:1179)
[        ] E/DatabaseUtils( 3508):      at android.os.Binder.execTransact(Binder.java:1143)
[+3166 ms] I/OpenGLRenderer( 3508): Davey! duration=8867ms; Flags=1, FrameTimelineVsyncId=136919, IntendedVsync=75659661938017, Vsync=75659661938017, InputEventId=0, HandleInputStart=75659662307935, AnimationStart=75659662312570,
PerformTraversalsStart=75659662314393, DrawStart=75659662905643, FrameDeadline=75659682604683, FrameInterval=75659662296476, FrameStartTime=16666666, SyncQueued=75659663757466, SyncStart=75659663831893, IssueDrawCommandsStart=75659664178872,       
SwapBuffers=75659673759759, FrameCompleted=75668529412932, DequeueBufferDuration=1077083, QueueBufferDuration=500417, GpuCompleted=75668529412932, SwapBuffersCompleted=75659674799550, DisplayPresentTime=0,

Flutter Doctor

[√] Flutter (Channel stable, 3.3.0, on Microsoft Windows [Version 10.0.22621.819], locale en-US)
    • Flutter version 3.3.0 on channel stable at C:\Users\ross\projects\flutter
    • Upstream repository https://github.com/flutter/flutter.git
    • Framework revision ffccd96b62 (3 months ago), 2022-08-29 17:28:57 -0700
    • Engine revision 5e9e0e0aa8
    • Dart version 2.18.0
    • DevTools version 2.15.0

[√] Android toolchain - develop for Android devices (Android SDK version 33.0.1)
    • Android SDK at C:\Users\ross\AppData\Local\Android\sdk
    • Platform android-33, build-tools 33.0.1
    • Java binary at: C:\Program Files\Android\Android Studio\jre\bin\java
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)
    • All Android licenses accepted.

[√] Chrome - develop for the web
    • Chrome at C:\Program Files (x86)\Google\Chrome\Application\chrome.exe

[√] Visual Studio - develop for Windows (Visual Studio Community 2022 17.2.6)
    • Visual Studio at C:\Program Files\Microsoft Visual Studio\2022\Community
    • Visual Studio Community 2022 version 17.2.32630.192
    • Windows 10 SDK version 10.0.19041.0

[√] Android Studio (version 2020.3)
    • Android Studio at C:\Program Files\Android\Android Studio
    • 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
    • Java version OpenJDK Runtime Environment (build 11.0.11+9-b60-7590822)

[√] Android Studio (version 2021.3)
    • Android Studio at C:\Program Files\Android\Android Studio1
    • 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
    • Java version OpenJDK Runtime Environment (build 11.0.13+0-b1751.21-8125866)

[√] VS Code (version 1.66.2)
    • VS Code at C:\Users\ross\AppData\Local\Programs\Microsoft VS Code
    • Flutter extension can be installed from:
       https://marketplace.visualstudio.com/items?itemName=Dart-Code.flutter

[√] Connected device (4 available)
    • Pixel 3 (mobile)  • 8C5X1JCQQ • android-arm64  • Android 12 (API 31)
    • Windows (desktop) • windows   • windows-x64    • Microsoft Windows [Version 10.0.22621.819]
    • Chrome (web)      • chrome    • web-javascript • Google Chrome 107.0.5304.108
    • Edge (web)        • edge      • web-javascript • Microsoft Edge 107.0.1418.42

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

• No issues found!

Checklist before submitting a bug

  • [X] I Google'd a solution and I couldn't find it
  • [X] I searched on StackOverflow for a solution and I couldn't find it
  • [X] I read the README.md file of the plugin
  • [X] I'm using the latest version of the plugin
  • [X] All dependencies are up to date with flutter pub upgrade
  • [X] I did a flutter clean
  • [X] I tried running the example project

EnduringBeta avatar Nov 29 '22 17:11 EnduringBeta