sd 卡上的 Android KitKat 4.4 文件夹 [英] Android KitKat 4.4 folder on sd card

查看:36
本文介绍了sd 卡上的 Android KitKat 4.4 文件夹的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

We've just fallen foul of the new permissions that apply to writing files to sd cards (external storage) on Android 4.4 (EACCES Permission Denied)

在 KitKat 之前,我们像这样设置我们的可写文件夹:

Prior to KitKat we set our writable folder like this:

mfolder = Environment.getExternalStorageDirectory().getPath() + "/appfiles";

然而,经过数小时的搜索,我得出结论,无论对错,在 4.4 设备上启用文件写入需要更改为:

However after hours of searching I've come to the conclusion, rightly or wrongly that on 4.4 devices to enable writing of files this needs to be changed to:

mfolder = Environment.getExternalStorageDirectory().getPath() + "/Android/data/com.xyz.abc/appfiles";

所以 mfolder 应该是这样的:/mnt/sdcard/Android/data/com.xyz.abc/appfiles

So mfolder would be something like: /mnt/sdcard/Android/data/com.xyz.abc/appfiles

这样对吗,我们是否在sdcard上创建一个类似上面那个的文件夹来使4.4设备能够写入文件?

Is this correct, do we create a folder like the one above on the sdcard to enable 4.4 devices to write files?

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

mfolder is a String that we save to shared preferences.

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

Then we have this code that runs once if API>=19 that changes the mfolder String and then copies all the files from the old folder to the new 'kitkat' folder.

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!
" + 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 文件夹.由于新的 4.4 权限,我猜他们只有在拥有库存文件管理器或卸载 SD 卡并将其放入 PC 时才能执行此操作?

I then notify the user that their files have been copied to the new folder and that due to the new permissions they would have to manually delete the old prekitkatfolder folder. I guess they will only be able to do this if they have a stock file manager or if they unmounted sd card and place it in a PC, due to the new 4.4 permissions?

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

Also, for us it appears that these 4.4 permissions are not affecting all our users with Kitkat. Some can still write to the original folder location on their external storage and some get the EACCES (Permission Denied) error. Can anyone throw any light on why this might be, one would think it would apply to all 4.4 devices using external storage?

由于我们没有实际的 4.4 设备,我们必须使用模拟器 (API 19) 测试此代码,但我们没有收到 EACCES Permission Denied 错误.所以我们发布了一个带有上述代码的测试版,并被告知复制的文件最终在内部存储中,这怎么可能?

As we have no actual 4.4 device we are having to test this code using the emulator (API 19) but we do not get the EACCES Permission Denied error. So we released a beta version with code above and have been told that the copied files ended up in internal storage, how can that be?

任何想法我们做错了什么,提前致谢

Any ideas what we're doing wrong, thanks in advance

推荐答案

更新的解决方案.

这会在 KitKat 的正确位置设置并创建文件夹.

This sets and also creates the folder in the correct place for KitKat.

mfolder = this.getExternalFilesDir("asubfoldername").getAbsolutePath();

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

However, this isn't full-proof, if the Android device has both an internal and external secondary storage locations, the above will use the internal one. Not really what we want as we require path to removable sdcard or better still the path to the secondary storagelocation with the most free available space.

File[] possible_kitkat_mounts = getExternalFilesDirs(null);

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

Note the "s" on the end of getExternalFilesDirs. This creates an array of secondary external storage locations.

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...
}

从可能的_kitkat_mounts 数组中,我们通过 test_mount 检查我们是否可以真正写入所选位置,如果成功,我们将该位置添加到 arrMyMounts.

From the array of possible_kitkat_mounts we check via test_mount to see if we can actually write to the selected location and if successful we add that location to arrMyMounts.

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

By sorting arrMyMounts we can then get the location with the most available free space.

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

Hey presto, arrMyMounts.get(0).name is a kitkat secondary storage location with the most free space.

这篇关于sd 卡上的 Android KitKat 4.4 文件夹的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆