Android 13 中的存储权限 - Flutter Android 13

man*_*nga 3 android file-permissions dart flutter android-13

我正在开发一个需要 Android 设备上的存储访问权限的 Flutter 应用程序。该应用程序在 Android 12 版本之前可以正常运行,但我在 Android 13 设备上遇到了存储权限问题。我遵循请求存储权限的标准实现,并在应用程序的 AndroidManifest.xml 文件中包含必要的权限声明。但是,在 Android 13 设备上,应用程序无法访问外部存储并遇到权限错误。

  • 错误
    I/ViewRootImpl@f9221bd[MainActivity](25559): handleAppVisibility mAppVisible = true visible = false
    I/SurfaceView@31e8ae4(25559): onWindowVisibilityChanged(8) false io.flutter.embedding.android.FlutterSurfaceView{31e8ae4 V.E...... ........ 0,0-720,1570} of ViewRootImpl@f9221bd[MainActivity]
    I/SurfaceView@31e8ae4(25559): Changes: creating=false format=false size=false visible=true alpha=false hint=false mUseAlpha=false visible=true left=false top=false
    I/SurfaceView@31e8ae4(25559): 52333284 Cur surface: Surface(name=null)/@0xfd2426a
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: vri = ViewRootImpl@f9221bd[MainActivity] fRS = false t = 0xb40000709aa32400 android.view.SurfaceView.performSurfaceTransaction:959 android.view.SurfaceView.updateSurface:1105 android.view.SurfaceView.onWindowVisibilityChanged:371 
    I/ViewRootImpl@f9221bd[MainActivity](25559): applyTransactionOnDraw: mRemoved = false isHardwareEnabled = true t = 0xb40000709aa32400android.view.SurfaceView.applyTransactionOnVriDraw:2048 android.view.SurfaceView.performSurfaceTransaction:959 android.view.SurfaceView.updateSurface:1105 android.view.SurfaceView.onWindowVisibilityChanged:371 android.view.View.dispatchWindowVisibilityChanged:15943 
    I/SurfaceView@31e8ae4(25559): surfaceDestroyed
    I/SurfaceView@31e8ae4(25559): surfaceDestroyed callback.size 1 #2 io.flutter.embedding.android.FlutterSurfaceView{31e8ae4 V.E...... ........ 0,0-720,1570}
    I/SurfaceView@31e8ae4(25559): updateSurface: mVisible = false mSurface.isValid() = true
    I/SurfaceView@31e8ae4(25559): releaseSurfaces: viewRoot = ViewRootImpl@f9221bd[MainActivity]
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: vri = ViewRootImpl@f9221bd[MainActivity] fRS = true t = 0xb40000711bc8e800 android.view.SurfaceView.releaseSurfaces:858 android.view.SurfaceView.updateSurface:1172 android.view.SurfaceView.onWindowVisibilityChanged:371 
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
    I/ViewRootImpl@f9221bd[MainActivity](25559): from releaseSurfaces t.apply t = 0xb40000711bc8e800
    V/SurfaceView@31e8ae4(25559): Layout: x=0 y=0 w=720 h=1570, frame=Rect(0, 0 - 720, 1570)
    D/SurfaceView@31e8ae4(25559): windowPositionLost, frameNr = 0
    D/OpenGLRenderer(25559): setSurface called with nullptr
    D/OpenGLRenderer(25559): setSurface() destroyed EGLSurface
    D/OpenGLRenderer(25559): destroyEglSurface
    I/ViewRootImpl@f9221bd[MainActivity](25559): performTraversals mFirst=false windowShouldResize=false viewVisibilityChanged=true mForceNextWindowRelayout=false params=null
    I/ViewRootImpl@f9221bd[MainActivity](25559): Relayout returned: old=(0,0,720,1600) new=(0,0,720,1600) req=(720,1600)8 dur=14 res=0x2 s={false 0x0} ch=true seqId=0
    I/SurfaceView@31e8ae4(25559): windowStopped(true) false io.flutter.embedding.android.FlutterSurfaceView{31e8ae4 V.E...... ........ 0,0-720,1570} of ViewRootImpl@f9221bd[MainActivity]
    D/SurfaceView@31e8ae4(25559): updateSurface: surface is not valid
    I/SurfaceView@31e8ae4(25559): releaseSurfaces: viewRoot = ViewRootImpl@f9221bd[MainActivity]
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: vri = ViewRootImpl@f9221bd[MainActivity] fRS = true t = 0xb400007106c68600 android.view.SurfaceView.releaseSurfaces:858 android.view.SurfaceView.updateSurface:998 android.view.SurfaceView.setWindowStopped:335 
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
    I/ViewRootImpl@f9221bd[MainActivity](25559): from releaseSurfaces t.apply t = 0xb400007106c68600
    D/SurfaceView@31e8ae4(25559): updateSurface: surface is not valid
    I/SurfaceView@31e8ae4(25559): releaseSurfaces: viewRoot = ViewRootImpl@f9221bd[MainActivity]
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: vri = ViewRootImpl@f9221bd[MainActivity] fRS = true t = 0xb40000707c17bd00 android.view.SurfaceView.releaseSurfaces:858 android.view.SurfaceView.updateSurface:998 android.view.SurfaceView.lambda$new$0$android-view-SurfaceView:200 
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
    I/ViewRootImpl@f9221bd[MainActivity](25559): from releaseSurfaces t.apply t = 0xb40000707c17bd00
    I/ViewRootImpl@f9221bd[MainActivity](25559): stopped(true) old = false
    I/ViewRootImpl@f9221bd[MainActivity](25559): WindowStopped on com.elektropod.eso/com.example.cso_application.MainActivity set to true
    D/SurfaceView@31e8ae4(25559): updateSurface: surface is not valid
    I/SurfaceView@31e8ae4(25559): releaseSurfaces: viewRoot = ViewRootImpl@f9221bd[MainActivity]
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: vri = ViewRootImpl@f9221bd[MainActivity] fRS = true t = 0xb40000707c252200 android.view.SurfaceView.releaseSurfaces:858 android.view.SurfaceView.updateSurface:998 android.view.SurfaceView.setVisibility:392 
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
    I/ViewRootImpl@f9221bd[MainActivity](25559): from releaseSurfaces t.apply t = 0xb40000707c252200
    I/MSHandlerLifeCycle(25559): removeMultiSplitHandler: no exist. decor=DecorView@b31705[MainActivity]
    D/SurfaceView@31e8ae4(25559): updateSurface: surface is not valid
    I/SurfaceView@31e8ae4(25559): releaseSurfaces: viewRoot = ViewRootImpl@f9221bd[MainActivity]
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: vri = ViewRootImpl@f9221bd[MainActivity] fRS = true t = 0xb40000707c252300 android.view.SurfaceView.releaseSurfaces:858 android.view.SurfaceView.updateSurface:998 android.view.SurfaceView.lambda$new$0$android-view-SurfaceView:200 
    I/SurfaceView@31e8ae4(25559): applyTransactionOnVriDraw: viewRoot.applyTransactionOnDrawFromReleaseSurfaces
    I/ViewRootImpl@f9221bd[MainActivity](25559): from releaseSurfaces t.apply t = 0xb40000707c252300
    D/InputTransport(25559): Input channel destroyed: 'ClientS', fd=138

Run Code Online (Sandbox Code Playgroud)
  • AndroidManifest.xml
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
Run Code Online (Sandbox Code Playgroud)
  • 主程序.dart
Future<void> main() async {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return GetMaterialApp(
      onInit: () async {
        try {
          var status = await Permission.storage.request();
          if (status.isGranted) {
            print('isGranted');
          } else if (status.isPermanentlyDenied) {
            openAppSettings();
          }
        } catch (e) {
          print('~~error~~~>>>>>> $e');
        }
      },
      theme: ThemeData(
        primaryColor: orangeColor,
      ),
      home: FutureBuilder(
        future: getId(),
        builder: (context, snapshot) {
          if (snapshot.hasData && snapshot.data != null) {
            return const MyHomePage();
          } else {
            return Login();
          }
        },
      ),
      debugShowCheckedModeBanner: false,
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

cem*_*256 5

根据 Android文档, READ_EXTERNAL_STORAGE从 API 级别 33 开始,权限无效。对于 API 级别 33 及以上,您可以根据您的用例使用READ_MEDIA_IMAGES, READ_MEDIA_VIDEO,权限READ_MEDIA_AUDIO

您可以修改 AndroidManifest.xml 以根据 API 级别请求相关权限:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" 
android:maxSdkVersion="32" />

<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO"/>
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO"/>
Run Code Online (Sandbox Code Playgroud)