Android 在/sdcard中创建目录失败

Android 在/sdcard中创建目录失败,android,file,directory,io,Android,File,Directory,Io,我一直试图以编程方式在/sdcard中创建一个目录,但它不起作用。下面的代码总是输出未创建的目录。 boolean success = (new File("/sdcard/map")).mkdir(); if (!success) { Log.i("directory not created", "directory not created"); } else { Log.i("directory created", "directory created"); } 您是否具

我一直试图以编程方式在
/sdcard
中创建一个目录,但它不起作用。下面的代码总是输出未创建的
目录。

boolean success = (new File("/sdcard/map")).mkdir(); 
if (!success) {
    Log.i("directory not created", "directory not created");
} else {
    Log.i("directory created", "directory created");
}

您是否具有写入清单中SD卡的权限?

中查找写外部存储,它不是已经创建了吗?如果文件夹也已存在,则Mkdir返回false

这里有三件事要考虑:

  • 不要假设sd卡安装在
    /sdcard
    (默认情况下可能是正确的,但最好不要硬编码)。您可以通过查询系统获取SD卡的位置:

    Environment.getExternalStorageDirectory();
    
  • 您必须通过在AndroidManifest.xml文件中添加uses权限条目来通知Android您的应用程序需要写入外部存储:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

  • SD卡的正确路径是

    /mnt/sdcard/
    
    但是,正如前面所回答的,您不应该硬编码它。如果您使用的是Android 2.1或更高版本,请使用

    getExternalFilesDir(String type) 
    
    否则:

    Environment.getExternalStorageDirectory()
    
    仔细阅读

    此外,您还需要使用此方法或类似的方法

    boolean mExternalStorageAvailable = false;
    boolean mExternalStorageWriteable = false;
    String state = Environment.getExternalStorageState();
    
    if (Environment.MEDIA_MOUNTED.equals(state)) {
        // We can read and write the media
        mExternalStorageAvailable = mExternalStorageWriteable = true;
    } else if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
        // We can only read the media
        mExternalStorageAvailable = true;
        mExternalStorageWriteable = false;
    } else {
        // Something else is wrong. It may be one of many other states, but all we need
        //  to know is we can neither read nor write
        mExternalStorageAvailable = mExternalStorageWriteable = false;
    }
    
    然后检查是否可以访问SD卡。如前所述,请阅读官方文件

    另一个选择,也许你需要使用而不是


    创建由该文件的尾随文件名命名的目录,包括创建该目录所需的完整目录路径。

    重新启动您的Android设备。在我重新启动设备后,事情开始对我起作用。

    使用mkdirs()而不是mkdir()。它对我起作用:)


    我犯了一个错误,把这两个都包括在内:

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    
    
    以及:

    
    

    按上述顺序。因此,当我获取第二个权限(READ)时,问题就消失了。

    如果Android 6和compile target>=23出现这种情况,请不要忘记我们现在正在使用。因此,在清单中授予权限是不够的。

    在我将Android手机升级到6.0(API级别23)后,我也遇到了同样的问题。以下解决方案对我有效。希望它也能帮助你

    File f = new File(Environment.getExternalStorageDirectory().getAbsolutePath()
            + "/FoderName");
    if (!f.exists()) {
        f.mkdirs();
    }
    
    请检查您的android版本。如果大于等于6.0(API级别23),则不仅需要包括

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    更多信息请阅读android api>=23中的“

        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    
    
    而不是

        <app:uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    

    有很多事情你需要担心 1.如果您使用的是Android Bellow棉花糖,则必须在清单文件中设置渗透。 2.如果你使用的是更高版本的Android,那么现在就意味着从棉花糖到奥利奥 您必须转到应用程序信息并在那里手动设置应用程序存储权限。 如果您想在运行时设置它,可以通过下面的代码来实现

    public  boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
        } else {
    
            Log.v(TAG,"Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG,"Permission is granted");
        return true;
    }
    
    public boolean isstoragepermissiongrated(){
    如果(Build.VERSION.SDK_INT>=23){
    if(checkSelfPermission(android.Manifest.permission.WRITE\u外部存储)
    ==PackageManager.权限(已授予){
    Log.v(标记“已授予许可”);
    返回true;
    }否则{
    Log.v(标记“权限被撤销”);
    ActivityCompat.requestPermissions(这个新字符串[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
    返回false;
    }
    }
    
    否则{//如果Android 6.0和API>=23发生错误,则会自动在sdk上授予权限;在AndroidManifest.xml中授予权限还不够

    您必须授予运行时权限,您可以在此处查阅更多信息

    谷歌在Android上有一个新功能:外部存储的过滤视图。快速修复方法是在AndroidManifest.xml文件中添加此代码:

    <manifest ... >
        
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
        <!-- This attribute is "false" by default on apps targeting Android Q. -->
        <application android:requestLegacyExternalStorage="true">
         ...
         ...
        </application>
    </manifest>
    

    如文档中所述

    是的,我在应用程序标记的清单文件中添加了这一行,但它仍然没有创建目录。如果您使用api 23运行应用程序,您必须首先向用户Bishoy请求权限-这不完全正确。您必须仅在运行时向PI 23及以上版本。如果您的目标是较低的SDK,那么即使在SDK 23+上运行,您也不必请求运行时权限。在任何版本的Android中,
    Environment
    上都没有
    getExternalFilesDir()
    。您可能会考虑
    getExternalFilesDir()
    上下文中的
    ,它是在2.2中添加的。但是,该方法有些不正确——它提供给您的目录将在应用程序升级过程中删除其内容。我希望这将在Gingerbread.Thx中得到修复。我快速浏览了数据存储部分,并假设它与getExternalStorageDirectory()一样被访问,这就是我使用的。正如前面提到的,我已经测试了状态。状态显示我已安装,但我无法创建文件夹在Froyo之前,SD卡安装在/sdcard。从Froyo开始,SD卡安装在/mnt/sdcard,并创建到/sdcard的软链接,以便应用程序在安装点发生变化时仍能正常运行。对于一些ason这个代码在我的myTouch手机上不适用…嗯.mkdir()始终返回false。我认为您应该检查权限,并且磁盘未安装在PC文件系统上。我应该在XML文件中的什么位置放置uses权限块?我有类似的问题,发现如果我的手机通过USB连接到我的计算机,它将无法创建目录。当我断开手机连接并运行再次,它正确地创建了文件夹和文件。我包括了写入外部存储和读取外部存储权限。您只需要第一个权限。+1,这对我正在使用的设备有效。但奇怪的是,为什么会发生这种情况?我想我调试了我的应用程序,其中一个写入锁被锁定,从未释放。使用mediaScan或sendbroadcast to Media_mount以使用新目录刷新媒体存储仅当您以SDK 23及更高版本为目标时才需要运行时权限请求。当应用程序以更低版本的SDK为目标时,无需运行时请求,ContextCompat.checkSelfPermission将始终返回tru
    public static final int MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE = 1;
    public int mkFolder(String folderName){ // make a folder under Environment.DIRECTORY_DCIM
        String state = Environment.getExternalStorageState();
        if (!Environment.MEDIA_MOUNTED.equals(state)){
            Log.d("myAppName", "Error: external storage is unavailable");
            return 0;
        }
        if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)) {
            Log.d("myAppName", "Error: external storage is read only.");
            return 0;
        }
        Log.d("myAppName", "External storage is not read only or unavailable");
    
        if (ContextCompat.checkSelfPermission(this, // request permission when it is not granted. 
                Manifest.permission.WRITE_EXTERNAL_STORAGE)
                != PackageManager.PERMISSION_GRANTED) {
            Log.d("myAppName", "permission:WRITE_EXTERNAL_STORAGE: NOT granted!");
            // Should we show an explanation?
            if (ActivityCompat.shouldShowRequestPermissionRationale(this,
                    Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
    
                // Show an expanation to the user *asynchronously* -- don't block
                // this thread waiting for the user's response! After the user
                // sees the explanation, try again to request the permission.
    
            } else {
    
                // No explanation needed, we can request the permission.
    
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                        MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
    
                // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
                // app-defined int constant. The callback method gets the
                // result of the request.
            }
        }
        File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM),folderName);
        int result = 0;
        if (folder.exists()) {
            Log.d("myAppName","folder exist:"+folder.toString());
            result = 2; // folder exist
        }else{
            try {
                if (folder.mkdir()) {
                    Log.d("myAppName", "folder created:" + folder.toString());
                    result = 1; // folder created
                } else {
                    Log.d("myAppName", "creat folder fails:" + folder.toString());
                    result = 0; // creat folder fails
                }
            }catch (Exception ecp){
                ecp.printStackTrace();
            }
        }
        return result;
    }
    
    @Override
    public void onRequestPermissionsResult(int requestCode,
                                           String permissions[], int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE: {
                // If request is cancelled, the result arrays are empty.
                if (grantResults.length > 0
                        && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
    
                    // permission was granted, yay! Do the
                    // contacts-related task you need to do.
    
                } else {
    
                    // permission denied, boo! Disable the
                    // functionality that depends on this permission.
                }
                return;
            }
    
            // other 'case' lines to check for other
            // permissions this app might request
        }
    }
    
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
        <app:uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
    public  boolean isStoragePermissionGranted() {
    if (Build.VERSION.SDK_INT >= 23) {
        if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                == PackageManager.PERMISSION_GRANTED) {
            Log.v(TAG,"Permission is granted");
            return true;
        } else {
    
            Log.v(TAG,"Permission is revoked");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
            return false;
        }
    }
    else { //permission is automatically granted on sdk<23 upon installation
        Log.v(TAG,"Permission is granted");
        return true;
    }
    
                           (or)
    
    <manifest ... >
        
        <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    
        <!-- This attribute is "false" by default on apps targeting Android Q. -->
        <application android:requestLegacyExternalStorage="true">
         ...
         ...
        </application>
    </manifest>
    
    Environment.getExternalStorageDirectory();