sd卡上的Android KitKat 4.4文件夹

我们刚刚陷入了适用于在Android 4.4上写入文件到SD卡(外部存储)的新权限(EACCES Permission Denied)

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

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

然而,经过几个小时的search,我已经得出结论,无论是在4.4设备上的文件写入都需要改变:

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

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

这是正确的,我们创build一个像上面的SD卡上的文件夹,以使4.4设备写入文件?

mfolder是一个string,我们保存到共享偏好。

然后我们有这个代码运行一次,如果API> = 19更改mfolderstring,然后将所有文件从旧文件夹复制到新的'kitkat'文件夹。

 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文件夹。 我想他们将只能做到这一点,如果他们有一个股票文件pipe理器,或者如果他们卸载SD卡,并将其放置在一台PC,由于新的4.4权限?

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

由于我们没有真正的4.4设备,我们不得不使用模拟器(API 19)来testing这个代码,但是我们没有得到EACCES Permission Denied错误。 所以我们发布了一个上面的代码的testing版本,并被告知复制的文件最终在内部存储,这怎么可能?

任何想法我们做错了,在此先感谢

Solutions Collecting From Web of "sd卡上的Android KitKat 4.4文件夹"

更新解决scheme

这设置,也创buildKitKat的正确位置的文件夹。

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

但是,这并不是完整的,如果Android设备同时具有内部和外部的辅助存储位置,上面将使用内部辅助存储位置。 不是我们想要的,因为我们需要path到可移动的SD卡或更好的path到二级存储空间最可用的位置。

 File[] possible_kitkat_mounts = getExternalFilesDirs(null); 

请注意getExternalFilesDirs结尾处的“s”。 这将创build一个辅助外部存储位置的数组。

 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进行sorting,我们可以获得最具可用空间的位置。

嘿presto,arrMyMounts.get(0).name是一个kitkat辅助存储空间最大的位置。

Google在Android 4.4中阻止了对外部存储设备的写入访问。 直到他们改变它,没有办法恢复没有根。

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

它可能正在使用Kitkat的一些设备上有小型卡插槽。 这是混乱:(