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

3
我正在开发一个Flutter应用程序,需要在Android设备上访问存储。该应用程序在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

  • 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" />
  • main.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,
    );
  }
}

我按照标准的实现方式来请求存储权限。但是有一个错误,因为在Android 13中所需的权限已经发生了变化。清单文件中缺少读取媒体文件的权限。 - undefined
我在你的错误日志中没有看到任何与存储或权限有关的内容。 - undefined
2个回答

5
根据Android文档,从API级别33开始,READ_EXTERNAL_STORAGE权限不再起作用。对于API级别33及以上,您可以根据您的使用情况使用READ_MEDIA_IMAGESREAD_MEDIA_VIDEOREAD_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"/>

2
我遇到了完全相同的问题。我的经验是,同样的清单曾用于请求访问文件的权限,现在却要求访问媒体,如图片所示: (Files -> Music and audio, Notifications, Photos and videos)

这个问题始于2023年7月的最新安全补丁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接