首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >SD卡上的安卓KitKat 4.4文件夹

SD卡上的安卓KitKat 4.4文件夹
EN

Stack Overflow用户
提问于 2014-05-07 17:55:36
回答 2查看 11K关注 0票数 16

我们刚刚与Android 4.4上适用于将文件写入SD卡(外部存储)的新权限冲突(EACCES权限被拒绝)

在KitKat之前,我们将可写文件夹设置如下:

代码语言:javascript
复制
mfolder = Environment.getExternalStorageDirectory().getPath() + "/appfiles";

然而,经过几个小时的搜索,我得出了一个结论,无论是对还是错,在4.4设备上,为了允许写入文件,需要将其更改为:

代码语言:javascript
复制
mfolder = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.xyz.abc/appfiles";

因此,mfolder应该类似于: /mnt/sdcard/Android/data/com.xyz.abc/appfiles

这是正确的,我们是否要在SD卡上创建一个类似于上面的文件夹,以使4.4设备能够写入文件?

mfolder是我们保存到共享首选项中的字符串。

然后我们有这个代码,它运行一次,如果为API>=19,它更改mfolder字符串,然后将旧文件夹中的所有文件复制到新的'kitkat‘文件夹。

代码语言:javascript
复制
if (android.os.Build.VERSION.SDK_INT>=19){
        if (!mfolder.contains("/Android/data/com.xyz.abc/appfiles")){
            if (prefs.getBoolean("kitkatcheck", false)==false){

                //update mfolder from
                      // /mnt/sdcard/appfiles
                      // to
                      // /mnt/sdcard/Android/data/com.xyz.abc/appfiles
                String prekitkatfolder = mfolder;
                String kitkatfolder = mfolder.replace("/appfiles", "/Android/data/com.xyz.abc/appfiles");
                mfolder = kitkatfolder;
                try {
                    File sd = new File(mfolder);
                    if(!sd.exists() || !sd.isDirectory()) {
                        sd.mkdirs();
                    }
                } catch (Exception e) {
                    Toast.makeText(getBaseContext(), "Error creating Kitkat folder!\n" + e.toString(), Toast.LENGTH_LONG).show();
                    return;
                }
                prefEditor.putString("patternfolder", mfolder);
                prefEditor.putBoolean("kitkatcheck", true);
                prefEditor.commit();

                //copy files and folder from old appfiles folder to new.
                AllFiles.clear();
                listFilesAndFilesSubDirectories(prekitkatfolder);
                if (AllFiles.size()>0){
                    for (File child : AllFiles ) {
                        try {

                            File dest = new File(child.toString().replace(prekitkatfolder, kitkatfolder));


                            try {
                                String filePath = dest.getPath().substring(0, dest.getPath().lastIndexOf(File.separator));
                                File subfolder = new File(filePath);
                                if(!subfolder.exists() || !subfolder.isDirectory()) {
                                    subfolder.mkdirs();
                                }
                            } catch (Exception ex) {
                            }

                            copyFile(child, dest);  

                        } catch (Throwable t) {

                        }
                    }

                }


            }

        }

然后我通知用户,他们的文件已经复制到新文件夹中,并且由于新的权限,他们必须手动删除旧的prekitkatfolder文件夹。我猜他们只能做到这一点,如果他们有一个股票文件管理器或如果他们卸载的SD卡,并把它放在PC上,由于新的4.4权限?

此外,对于我们来说,这4.4权限似乎不会影响所有使用Kitkat的用户。有些人仍然可以写入其外部存储上的原始文件夹位置,有些人会收到EACCES (权限被拒绝)错误。有人能解释一下为什么会这样吗?有人会认为这适用于所有使用外部存储的4.4设备?

由于我们没有实际的4.4设备,我们必须使用仿真器(API 19)测试此代码,但我们没有得到EACCES权限被拒绝错误。因此,我们发布了带有上述代码的测试版,并被告知复制的文件最终存储在内部存储中,这怎么可能呢?

如果你知道我们做错了什么,请提前谢谢

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-09-26 16:51:51

更新了解决方案。

这将在KitKat的正确位置设置并创建文件夹。

代码语言:javascript
复制
mfolder = this.getExternalFilesDir("asubfoldername").getAbsolutePath();

然而,这并不是完全证明的,如果Android设备同时有内部和外部辅助存储位置,上面的将使用内部存储位置。这并不是我们想要的,因为我们需要指向可移动SD卡的路径,或者更好的是指向具有最大可用空间的二级存储位置的路径。

代码语言:javascript
复制
File[] possible_kitkat_mounts = getExternalFilesDirs(null);

注意getExternalFilesDirs末尾的"s“。这将创建一个辅助外部存储位置数组。

代码语言:javascript
复制
for (int x = 0; x < possible_kitkat_mounts.length; x++) {
    //Log.d("test", "possible_kitkat_mounts " + possible_kitkat_mounts[x].toString());
    boolean isgood=false;
    if (possible_kitkat_mounts[x] != null){
        isgood = test_mount(possible_kitkat_mounts[x].toString());  
        if (isgood==true){
            arrMyMounts.add(newymounts(Device_get_device_info(possible_kitkat_mounts[x].toString()), possible_kitkat_mounts[x].toString()));
        }   
    }
}                           

//sort arrMyMounts size so we can use largest
Collections.sort(arrMyMounts, new Comparator<mymounts>(){
    public int compare(mymounts obj1, mymounts obj2){
        return (obj1.avaliablesize > obj2.avaliablesize) ? -1: (obj1.avaliablesize > obj2.avaliablesize) ? 1:0 ;
    }
}); 


if (arrMyMounts.size()>0){
    mfolder = arrMyMounts.get(0).name + "/asubfoldername";
    //Log.d("test", "selected kitkat mount " + kitkatfolder);   
}else{
    //do something else...
}

从possible_kitkat_mounts数组中,我们通过test_mount检查是否可以实际写入选定的位置,如果成功,我们将该位置添加到arrMyMounts中。

通过对arrMyMounts进行排序,我们可以获得具有最多可用空间的位置。

嘿,arrMyMounts.get(0).name是一个拥有最多可用空间的kitkat二级存储位置。

票数 7
EN

Stack Overflow用户

发布于 2014-08-30 03:21:54

谷歌在Android 4.4中阻止了对外部存储设备的写入访问。除非他们更改了它,否则没有root就没有办法恢复它。

更多信息:https://groups.google.com/forum/#!msg/android-platform/14VUiIgwUjY/UsxMYwu02z0J

它可能在一些带有Kitkat的设备上工作,这些设备有MiniSD卡插槽。令人困惑的是:(

票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/23514506

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档