V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zhttp
V2EX  ›  Android

关于 Android 保存文件的权限问题,想请教一下

  •  
  •   zhttp · 2022-09-21 11:02:58 +08:00 · 8407 次点击
    这是一个创建于 788 天前的主题,其中的信息可能已经有所发展或是发生改变。

    在 Android 平台写一个图像处理的 demo 来验证一下算法,主要是用 mediacodec 读 mp4 文件解码,逐帧处理图像,然后再编码封装成 mp4 ,现在只完成了前半部分,编码的部分还没有写,想把处理完成的图像保存一帧下来看看效果,结果卡在了保存这一步。
    目前已经完成的事情:
    1 、在 AndroidManifest.xml 里面添加
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    2 、在 mainactivity 里面加了请求权限的代码,第一次打开应用也选择了始终同意,可以读 mp4 文件,但是无法新建文件,file.canWrite 返回 false ,Environment.getExternalStorageDirectory().canWrite()返回 false ,canRead 返回 true ,也就是只有读权限没有写权限;
    3 、文件目录是 /storage/emulated/0/DCIM/myapp/test.yuv 这样子的
    Android 新手,还请指教。

    第 1 条附言  ·  2022-09-21 18:05:57 +08:00

    感谢各位的回复和帮助,目前代码勉强能用了,我把现在的代码贴出来,希望能帮助到其他人,如果代码有什么问题的话还请指出,谢谢。

    ContentResolver resolver = mContext.getContentResolver();
    Uri imageCollection;
    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
        imageCollection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY);
    } else {
        imageCollection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
    }
    ContentValues yuvimage = new ContentValues();
    yuvimage.put(MediaStore.Images.Media.DISPLAY_NAME, "test");
    yuvimage.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
    Uri newImage = resolver.insert(imageCollection, yuvimage);
    OutputStream os = resolver.openOutputStream(newImage);
    byte[] data = new byte[info.size];
    outputBuffer.get(data);  //outputBuffer是mediacodec获取的解码数据
    os.write(data);
    
    12 条回复    2022-09-21 18:07:53 +08:00
    okakuyang
        1
    okakuyang  
       2022-09-21 11:33:42 +08:00
    在安卓 9/10 以上系统强制启用文件分区,App 只能读写自己的文件目录,你上面的方法已经过时了。
    如果是在照片下载等公共目录读写也需要申请相关的权限。
    dingwen07
        2
    dingwen07  
       2022-09-21 14:54:07 +08:00   ❤️ 1
    个人观察 2022 年还在非必要使用 WRITE_EXTERNAL_STORAGE 的软件 90%都很烂
    dingwen07
        3
    dingwen07  
       2022-09-21 14:55:22 +08:00
    7c00
        4
    7c00  
       2022-09-21 15:21:39 +08:00
    google 为了限制 WRITE_EXTERNAL_STORAGE 的滥用,从 android 11 开始 WRITE_EXTERNAL_STORAGE 就只能写入媒体目录。要能像之前一样读写所有目录需要新权限 MANAGE_EXTERNAL_STORAGE ,这个权限貌似会影响是否能上架 google play ,但在国内,这个权限还是继续被滥用就是了。
    bingoway
        5
    bingoway  
       2022-09-21 15:52:04 +08:00
    q503315508
        6
    q503315508  
       2022-09-21 15:54:28 +08:00
    android/data/${packageName}/
    7c00
        9
    7c00  
       2022-09-21 17:09:06 +08:00
    @bingoway requestLegacyExternalStorage 只对 android 10 有用,从 11 起,requestLegacyExternalStorage 被废弃
    gaifanking
        10
    gaifanking  
       2022-09-21 17:43:41 +08:00
    @7c00 这里的 11 是编译时 targetSdkVersion ,不是运行的手机的版本号。
    @zhttp 你的动态权限申请 申请了 WRITE 权限吗?
    zhttp
        11
    zhttp  
    OP
       2022-09-21 17:56:17 +08:00
    感谢楼上各位的回复和帮助,我查了一下午文档以及 StackOverflow 之后,现在基本上勉强能用了,我原本是使用 FileOutputStream 直接在 Environment.getExternalStorageDirectory()下面写,现在改成了使用 MediaStore ,可以正常保存文件,参考了开发者文档和这个链接 https://stackoverflow.com/questions/56904485/how-to-save-an-image-in-android-q-using-mediastore
    zhttp
        12
    zhttp  
    OP
       2022-09-21 18:07:53 +08:00
    @anjxue 权限问题我完全没搞懂。。。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   2749 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 20ms · UTC 09:42 · PVG 17:42 · LAX 01:42 · JFK 04:42
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.