android-studio - Android 9.+ API 29:/storage/emulated/0/Pictures/myPic.png 打开失败:EACCES(权限被拒绝)
问题描述
我正在使用 Android Virtual Device (AVD) Nexus 7 (2012) API 29 在 Android Studio 3.4.1 上尝试一个非常基本的相机应用程序的源代码。我在模拟器中用相机拍照并尝试将其保存为 / storage/emulated/0/Pictures/myPic.png,但出现 /storage/emulated/0/Pictures/myPic.png 打开失败:EACCES(权限被拒绝)。我已经尝试了所有在线可用的建议,例如:
- 在 AndroidManifest.xml 中,我添加了:
<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" />
- 在 MainActivity.java 中,我添加了以下运行时权限检查和请求代码:
public class MainActivity extends Activity {
private static final int REQUEST_EXTERNAL_STORAGE = 1;
private static String[] PERMISSIONS_STORAGE = {
Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE
};
public static void verifyStoragePermissions(Activity activity) {
int permission = ActivityCompat.checkSelfPermission(activity, Manifest.permission.WRITE_EXTERNAL_STORAGE);
boolean checkPermission = (permission == PackageManager.PERMISSION_GRANTED);
Toast toastPermission = Toast.makeText(activity,
"Is permission granted? " + checkPermission,
Toast.LENGTH_SHORT);
LinearLayout toastLayoutPermission = (LinearLayout) toastPermission.getView();
TextView toastTVPermission = (TextView) toastLayoutPermission.getChildAt(0);
toastTVPermission.setTextSize(30);
toastPermission.show();
if (permission != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(
activity,
PERMISSIONS_STORAGE,
REQUEST_EXTERNAL_STORAGE
);
}
}
- 然后,我在 onCreate 和要保存图片之前检查并请求权限,如下所示:
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
verifyStoragePermissions(this);
......
private void saveImageToFile(File file)
{
if (mCameraBitmap != null)
{
FileOutputStream outStream = null;
verifyStoragePermissions(this);
try
{
outStream = new FileOutputStream(file);
...
}
catch (Exception e)
{
Toast toastException = Toast.makeText(MainActivity.this,
"Exception: " + e.getMessage(),
Toast.LENGTH_SHORT);
LinearLayout toastLayoutException = (LinearLayout) toastException.getView();
TextView toastTVException = (TextView) toastLayoutException.getChildAt(0);
toastTVException.setTextSize(30);
toastException.show();
}
...
- 我还在模拟器中手动检查了存储权限,以确保允许访问存储。
但是,没有任何建议有效!
该代码引发了异常
/storage/emulated/0/Pictures/myPic.png 打开失败:EACCES(权限被拒绝)
当它到达线
outStream = new FileOutputStream(file);
有什么想法可以进一步解决这个问题吗?非常感谢。
解决方案
将android:requestLegacyExternalStorage="true"添加到 Android Manifest 对我来说适用于 Android 29
<application
android:name=".MyApplication"
android:allowBackup="true"
android:requestLegacyExternalStorage="true" ...
推荐阅读
- python - Pandas:从具有多个字典列表的列中提取值并将值拆分为多个列
- php - 如何使用 Api-Platform 保存空数据?
- python - 使用 fsolve 和字符串方程
- python - Python shell 在打印 4788 行后重新启动
- ruby-on-rails - 如何动态地在 Rails 中创建连接
- fortran - 运行使用 f2py 编译的 fortran 程序时输出不一致
- command - (WinDbg) 在使用 WinDbg(内核模式)切换到进程上下文后,如何切换回内核上下文?
- swiftui - 我无法在 SwiftUI 中将 NavigationItemTitle 覆盖到 TabView
- javascript - 在循环内设置本地存储项
- python - 如何使表单重定向到 Django 中用户给出的 URL?