我正在 flutter 上制作 Instagram 克隆,并尝试访问设备的存储空间,以便用户可以选择要发布的图像,但应用程序设置中的权限显示为灰色。我正在遵循 youtube 上的教程,并且我遵循了该人的代码,但我的代码不起作用。我只在运行 android 11 的模拟器上收到权限请求,但在运行 android 14 的物理设备上,我没有收到任何权限请求,并且权限在应用程序设置中显示为灰色。我的代码如下。 (我已经将使用权限添加到 Android 清单中)
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:photo_manager/photo_manager.dart';
class NewPostScreen extends StatefulWidget {
const NewPostScreen({Key? key}) : super(key: key);
@override
State<NewPostScreen> createState() => _NewPostScreenState();
}
class _NewPostScreenState extends State<NewPostScreen> {
final List<Widget> _mediaList = [];
final List<File> path = [];
File? _file;
int currentPage = 0;
int? lastPage;
_fetchNewMedia() async {
lastPage = currentPage;
final PermissionState ps = await PhotoManager.requestPermissionExtend();
if (ps.isAuth) {
List<AssetPathEntity> album =
await PhotoManager.getAssetPathList(onlyAll: true);
List<AssetEntity> media =
await album[0].getAssetListPaged(page: currentPage, size: 60);
for (var asset in media) {
if (asset.type == AssetType.image) {
final file = await asset.file;
if (file != null) {
path.add(File(file.path));
_file = path[0];
}
}
}
List<Widget> temp = [];
for (var asset in media) {
temp.add(FutureBuilder(
future: asset.thumbnailDataWithSize(const ThumbnailSize(
200,
200,
)),
builder: (context, snapshot) {
print('Thumbnail data: ${snapshot.data}');
if (snapshot.connectionState == ConnectionState.done) {
return Container(
child: Stack(
children: [
Positioned.fill(
child: Image.memory(
snapshot.data!,
fit: BoxFit.cover,
))
],
),
);
}
return Container();
}));
}
setState(() {
_mediaList.addAll(temp);
currentPage++;
});
}
}
@override
void initState() {
super.initState();
_fetchNewMedia();
}
int indexx = 0;
//@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
backgroundColor: Theme.of(context).brightness == Brightness.light
? Colors.white
: Colors.black,
title: const Text(
'New Post',
style: TextStyle(
//color: Colors.lightBlueAccent,
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
toolbarHeight: 40,
// elevation: 10,
centerTitle: true,
automaticallyImplyLeading: false,
),
body: SafeArea(
child: SingleChildScrollView(
child: Column(
children: [
SizedBox(
height: 410,
child: GridView.builder(
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 1,
mainAxisSpacing: 1,
crossAxisSpacing: 1),
itemBuilder: (context, index) {
return _mediaList[indexx];
},
),
),
Container(
width: double.infinity,
height: 40,
//color: Colors.white,
child: Row(
children: [
SizedBox(
width: 10,
),
Text(
'Recent',
style: TextStyle(fontWeight: FontWeight.w500),
)
],
),
),
GridView.builder(
shrinkWrap: true,
itemCount: _mediaList.length,
gridDelegate: const SliverGridDelegateWithFixedCrossAxisCount(
crossAxisCount: 3, mainAxisSpacing: 1, crossAxisSpacing: 2),
itemBuilder: (context, index) {
return GestureDetector(onTap: () {
setState(() {
indexx = index;
});
}, child: _mediaList[index],
);
},
)
],
),
),
),
);
}
}
添加 API 33 和 API 34 的 Android 附加功能,如此处所述。添加它们后,它开始正常工作。
Android 14 (API 34) 额外配置
当面向 Android 14(API 级别 34)时,需要将以下额外配置添加到清单中:
<manifest>
<uses-permission android:name="android.permission.READ_MEDIA_VISUAL_USER_SELECTED" /> <!-- If you want to use the limited access feature. -->
</manifest>
Android 13 (API 33) 额外配置
当面向 Android 13(API 级别 33)时,需要将以下额外配置添加到清单中:
<manifest>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" /> <!-- If you want to read images-->
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" /> <!-- If you want to read videos-->
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" /> <!-- If you want to read audio-->
</manifest>