首页 文章

无法在android上的外部存储上创建文件夹

提问于
浏览
14

我的开发手机是 Nexus 5 ,正在运行 Android 4.4.2 .

在我的应用程序中,我试图在外部存储上创建一个文件夹,用于存储我的应用程序的调试信息 . 基本上它将包含应用程序执行的所有命令,因此当用户遇到问题时,我可以选择让他们从调试文件夹中发送信息进行分析 .

我开始尝试将文件写入文件夹,但发现创建文件夹时出错 . 起初我正在使用 mkdir() ,然后我搬到了 mkdirs() ,这也没用 .

我的清单里有 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> .

以下是创建文件夹的代码:

File folder = new File(Environment.getExternalStorageDirectory() + "/DebugData");

    String path = folder.getPath();

    if(!folder.mkdirs() || !folder.exists()){        
            Log.e(LOG_TAG, path + " failed");
        } else {
            Log.d(LOG_TAG, path + " succeeded");
        }

这是我也尝试过的:

//Check SD card state
    String state = Environment.getExternalStorageState();
    if (Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) || !Environment.MEDIA_MOUNTED.equals(state)) {
        Log.e(LOG_TAG, "Error: external storage is read only or unavailable");
    } else {
        Log.d(LOG_TAG, "External storage is not read only or unavailable");
    }

这将返回外部存储 not 只读或不可用 .

我也试过不同的路径,比如 File folder = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), "Folder1");

This is where it became really confusing.

我尝试在不同的手机上开发 . 首先,我 grab 了 Galaxy S4 GT-i9505 运行 Android 4.2.2 并且它有效 . 我能够创建文件夹并写入它们 . 这告诉我代码正在运行 . 通过在S4和Nexus 5上运行代码返回的路径也是相同的 .

然后我认为它可能是特定于Android版本的 . 所以我抓了一个带有 Android 4.4.2Nexus 4 ,代码也在处理它 . 创建了文件夹并允许我写信给他们 .

这些手机都没有根,并且都是库存标准 . 在Nexus 5上没有任何特殊的应用程序或任何我可以想到的设置可能会导致权限问题 . 连接设置为媒体设备(MTP) .

EDIT:

我应该补充一点,我已经尝试过以下也没有用的:

  • 将文件写入外部存储的根目录

  • 在外部存储根目录中创建文件并写入该文件

  • 在概述的路径中创建文件夹并将文件写入其中

  • 在概述的路径中创建文件并写入文件

我对导致这种情况的原因感到困惑,还有什么我可以测试或更改以解决问题吗?

EDIT 2:

事实证明,问题是由于我认为是索引 .

基本上我测试的所有其他设备允许我重新连接USB连接并查看创建的文件和文件夹 .

出于某种原因,我的Nexus 5没有索引文件夹/文件,即使它们存在 .

我下载了不同的第三方文件资源管理器应用程序,并注意到所有文件夹和文件都在那里 .

因此,要通过USB调试查看这些文件夹和文件,我必须重新启动手机以重新索引它们,这看起来很烦人,但它比不工作更好 .

谢谢 .

7 回答

  • 1

    就这是与Nexus的索引问题而言,这对我有用:

    MediaScannerConnection.scanFile(this, new String[] { file.toString() }, null,
            new MediaScannerConnection.OnScanCompletedListener() {
                public void onScanCompleted(String path, Uri uri) {
                    Log.i("ExternalStorage", "Scanned " + path + ":");
                    Log.i("ExternalStorage", "-> uri=" + uri);
                }
    });
    

    您应该在创建和保存文件后直接调用它 . 通过使用扫描仪,我只需通过重新插入设备就能看到新创建的文件和目录 .

    根据docs

    MediaScannerConnection为应用程序提供了一种将新创建或下载的媒体文件传递到媒体扫描程序服务的方法 . 媒体扫描程序服务将从文件中读取元数据并将文件添加到媒体内容提供程序 .

    希望这有助于其他人 .

  • 1

    事实证明,问题是由于我认为是索引 .

    基本上我测试的所有其他设备允许我重新连接USB连接并查看创建的文件和文件夹 .

    出于某种原因,我的Nexus 5没有索引文件夹/文件,即使它们存在 .

    我下载了不同的第三方文件资源管理器应用程序,并注意到所有文件夹和文件都在那里 .

    因此,要通过USB调试查看这些文件夹和文件,我必须重新启动手机以重新索引它们,这看起来很烦人,但它比不工作更好 .

  • 7

    有同样的问题 . 原来我在Android 6上测试并没有检查运行时WRITE_EXTERNAL_STORAGE权限 .

  • 4

    首先,新的 File() 只是为文件连接创建对象 .
    你想使用这个文件,文件存在或 createNewFile() .
    如果要使用此文件创建目录,则检查文件是否存在, isDirectory() 之后是 mkDir() .
    其次,检查 Environment.getExternalStorageDirectory 是可变路径 .
    您可以使用 DDMSADB 进行工作 .
    另外,我认为您为读取外部存储添加了错误的权限 .

  • 0

    如果您运行的是api> = 23的Android设备,则需要请求权限用户调用mkdir()函数之前 . 我之前的答案与示例代码可以找到https://stackoverflow.com/a/38694026/5089713

  • 3

    对于Android sdk 23及更高版本,您应该检查用户是否已授予外部存储权限 .

    private void createFolder() {
        if (isStoragePermissionGranted()) {
            File folder = new File(Environment.getExternalStorageDirectory()+ File.separator + "DebugData");
    
            if(!folder.exists()){
                folder.mkdir();
            }
        }
    
    public  boolean isStoragePermissionGranted() {
        if (Build.VERSION.SDK_INT >= 23) {
            if (checkSelfPermission(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)
                    == PackageManager.PERMISSION_GRANTED) {
                return true;
            } else {
                ActivityCompat.requestPermissions(this,
                        new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 1);
                return false;
            }
        }
        else { //permission is automatically granted on sdk<23 upon installation
            return true;
        }
    }
    

    上面的代码对我有用,我希望它对你有用 .

  • 2

    通常,我这样做:

    /**
     * Return a dedicated directory named "MyApp" at the top of external storage
     */
    public static file getDataDir() {
        File sdcard = Environment.getExternalStorageDirectory();
        if( sdcard == null || !sdcard.isDirectory() ) {
            // TODO: warning popup
            Log.w(TAG, "Storage card not found " + sdcard);
            return null;
        }
        File dataDir = new File(sdcard, "MyApp");
        if( !confirmDir(dataDir) ) {
            // TODO: warning popup
            Log.e(TAG, "Unable to create " + dataDir);
            return null;
        }
        return dataDir;
    }   
    
    private static boolean confirmDir(File dir) {
        if (dir.isDirectory()) return true;  // already exists
        if (dir.exists()) return false;      // already exists, but is not a directory
        return dir.mkdirs();                 // create it
    }
    

    另外,将此权限添加到清单:

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

    如果你想要你的应用程序的私有存储(通常在/ data /下)(而不是在SD卡上),那么请查看 getDir()getFilesDir()fileList()openFileInput()openFileOutput() 等 .

    还有辅助函数来获取API 8及更高版本的sdcard中的私有目录: getExternalFilesDir()getExternalCacheDir() 等 .

相关问题