Cách tạo thư mục tự động trên thẻ SD


189

Tôi đang cố lưu tệp của mình vào vị trí sau
FileOutputStream fos = new FileOutputStream("/sdcard/Wallpaper/"+fileName); nhưng tôi đang gặp ngoại lệ java.io.FileNotFoundException
Tuy nhiên, khi tôi đặt đường dẫn khi "/sdcard/"nó hoạt động.

Bây giờ tôi giả sử rằng tôi không thể tạo thư mục tự động theo cách này.

Ai đó có thể đề nghị làm thế nào để tạo một directory and sub-directorymã sử dụng?

Câu trả lời:


449

Nếu bạn tạo một đối tượng Tệp bao bọc thư mục cấp cao nhất, bạn có thể gọi phương thức đó là mkdirs () để xây dựng tất cả các thư mục cần thiết. Cái gì đó như:

// create a File object for the parent directory
File wallpaperDirectory = new File("/sdcard/Wallpaper/");
// have the object build the directory structure, if needed.
wallpaperDirectory.mkdirs();
// create a File object for the output file
File outputFile = new File(wallpaperDirectory, filename);
// now attach the OutputStream to the file object, instead of a String representation
FileOutputStream fos = new FileOutputStream(outputFile);

Lưu ý: Có thể là khôn ngoan khi sử dụng Môi trường.getExternalStorageDirectory () để nhận thư mục "Thẻ SD" vì điều này có thể thay đổi nếu một điện thoại đi kèm có thứ gì đó không phải là Thẻ SD (chẳng hạn như đèn flash tích hợp, a'la điện thoại Iphone). Dù bằng cách nào bạn cũng nên nhớ rằng bạn cần kiểm tra để chắc chắn rằng nó thực sự ở đó vì Thẻ SD có thể được gỡ bỏ.

CẬP NHẬT: Vì API cấp 4 (1.6), bạn cũng sẽ phải yêu cầu quyền. Một cái gì đó như thế này (trong bảng kê khai) sẽ hoạt động:

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

1
có, các máy tính bảng Samsung được phát hành sau đó sử dụng đèn flash tích hợp
CQM

2
đừng quên thêm vào AndroidManifest.xml quyền viết stackoverflow.com/a/4435708/579646
max4ever

1
Nó xử lý nó không hoạt động nếu tôi có một thư mục con, như /sdcard/com.my.code/data? Làm thế nào tôi có thể giải quyết điều này?
lony

Bên cạnh việc tạo thư mục này quá? Có một lệnh như 'lực lượng' trong unix mkdir không?
lony

4
Không hoạt động trên KitKat, sdcard bên ngoài, vật lý.
celoftis

57

Có cùng một vấn đề và chỉ muốn thêm rằng AndroidManifest.xml cũng cần quyền này:

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

39

Đây là những gì làm việc cho tôi.

 uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" 

trong bảng kê khai của bạn và mã dưới đây

public static boolean createDirIfNotExists(String path) {
    boolean ret = true;

    File file = new File(Environment.getExternalStorageDirectory(), path);
    if (!file.exists()) {
        if (!file.mkdirs()) {
            Log.e("TravellerLog :: ", "Problem creating Image folder");
            ret = false;
        }
    }
    return ret;
}

đường dẫn là tên của thư mục bạn muốn tạo. Nếu bạn đã gửi đường dẫn như MusicD Download .. Nó sẽ tự động trở thành / sdcard / MusicD Download. Shajeel Afzal
shehzy

Nó ném ngoại lệ java.io.IOException: open fail: ENOENT (Không có tệp hoặc thư mục như vậy)
Anand Savigate

24

Trên thực tế, tôi đã sử dụng một phần của @fiXedd asnwer và nó hoạt động với tôi:

  //Create Folder
  File folder = new File(Environment.getExternalStorageDirectory().toString()+"/Aqeel/Images");
  folder.mkdirs();

  //Save the path as a string value
  String extStorageDirectory = folder.toString();

  //Create New file and name it Image2.PNG
  File file = new File(extStorageDirectory, "Image2.PNG");

Đảm bảo rằng bạn đang sử dụng mkdirs () chứ không phải mkdir () để tạo đường dẫn hoàn chỉnh


Làm thế nào là "một phần" của câu trả lời @fixedd? Câu trả lời của anh là sử dụng File.mkdirs(). Sau đó, ông cho thấy một ví dụ về việc sử dụng nó.
Doomsknight

Trên thực tế tôi không thể nhớ sự khác biệt là gì nhưng tôi nghĩ rằng có một số chỉnh sửa ... Nhân tiện, tôi đã đề cập rằng tôi đã sử dụng câu trả lời của anh ấy để có được giải pháp
Amt87

12

Với API 8 trở lên, vị trí của thẻ SD đã thay đổi. Câu trả lời của @ fiXedd là tốt, nhưng để mã an toàn hơn, bạn nên sử dụng Environment.getExternalStorageState()để kiểm tra xem phương tiện có sẵn không. Sau đó, bạn có thể sử dụng getExternalFilesDir()để điều hướng đến thư mục bạn muốn (giả sử bạn đang sử dụng API 8 trở lên).

Bạn có thể đọc thêm trong tài liệu SDK .


8

Đảm bảo lưu trữ ngoài có mặt: http://developer.android.com/guide/topics/data/data-st Storage.html # filesExternal

private boolean isExternalStoragePresent() {

        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;
        }
        if (!((mExternalStorageAvailable) && (mExternalStorageWriteable))) {
            Toast.makeText(context, "SD card not present", Toast.LENGTH_LONG)
                    .show();

        }
        return (mExternalStorageAvailable) && (mExternalStorageWriteable);
    }

6

Đừng quên đảm bảo rằng bạn không có ký tự đặc biệt trong tên tệp / thư mục của bạn. Đã xảy ra với tôi với ":" khi tôi đang đặt tên thư mục bằng cách sử dụng biến (s)

không cho phép các ký tự trong tên tệp / thư mục

"* /: <>? \ |

Bạn có thể thấy mã này hữu ích trong trường hợp như vậy.

Đoạn mã dưới đây sẽ xóa tất cả ":" và thay thế chúng bằng "-"

//actualFileName = "qwerty:asdfg:zxcvb" say...

    String[] tempFileNames;
    String tempFileName ="";
    String delimiter = ":";
    tempFileNames = actualFileName.split(delimiter);
    tempFileName = tempFileNames[0];
    for (int j = 1; j < tempFileNames.length; j++){
        tempFileName = tempFileName+" - "+tempFileNames[j];
    }
    File file = new File(Environment.getExternalStorageDirectory(), "/MyApp/"+ tempFileName+ "/");
    if (!file.exists()) {
        if (!file.mkdirs()) {
        Log.e("TravellerLog :: ", "Problem creating Image folder");
        }
    }

+1 ya tôi cũng đã thử với: và đã gặp lỗi và cuối cùng đã tìm thấy vấn đề đó và đã xóa: và tất cả các ký tự đặc biệt khác.
Ganapathy C

6

Tôi phải đối mặt với cùng một vấn đề. Có hai loại quyền trong Android:

  • Nguy hiểm (truy cập vào danh bạ, ghi vào bộ nhớ ngoài ...)
  • Bình thường (Quyền bình thường được Android tự động phê duyệt trong khi quyền nguy hiểm cần được người dùng Android chấp thuận.)

Đây là chiến lược để có được các quyền nguy hiểm trong Android 6.0

  • Kiểm tra nếu bạn có sự cho phép
  • Nếu ứng dụng của bạn đã được cấp quyền, hãy tiếp tục và thực hiện bình thường.
  • Nếu ứng dụng của bạn chưa có sự cho phép, hãy yêu cầu người dùng phê duyệt
  • Nghe sự chấp thuận của người dùng trong onRequestPermissionsResult

Đây là trường hợp của tôi: Tôi cần ghi vào bộ nhớ ngoài.

Đầu tiên, tôi kiểm tra xem tôi có được phép không:

...
private static final int REQUEST_WRITE_STORAGE = 112;
...
boolean hasPermission = (ContextCompat.checkSelfPermission(activity,
            Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED);
if (!hasPermission) {
    ActivityCompat.requestPermissions(parentActivity,
                new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
                REQUEST_WRITE_STORAGE);
}

Sau đó kiểm tra sự chấp thuận của người dùng:

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    super.onRequestPermissionsResult(requestCode, permissions, grantResults);
    switch (requestCode)
    {
        case REQUEST_WRITE_STORAGE: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED)
            {
                //reload my activity with permission granted or use the features what required the permission
            } else
            {
                Toast.makeText(parentActivity, "The app was not allowed to write to your storage. Hence, it cannot function properly. Please consider granting it this permission", Toast.LENGTH_LONG).show();
            }
        }
    }    
}

5

Tôi đã phải đối mặt với cùng một vấn đề, không thể tạo thư mục trên Galaxy S nhưng đã có thể tạo thành công trên Nexus và Samsung Droid. Cách tôi sửa nó bằng cách thêm dòng mã sau:

File dir = new File(Environment.getExternalStorageDirectory().getPath()+"/"+getPackageName()+"/");
dir.mkdirs();

5
File sdcard = Environment.getExternalStorageDirectory();
File f=new File(sdcard+"/dor");
f.mkdir();

điều này sẽ tạo một thư mục có tên dor trong sdcard của bạn. sau đó để tìm nạp tệp cho eg- filename.json được chèn thủ công trong thư mục dor . Giống:

 File file1 = new File(sdcard,"/dor/fitness.json");
 .......
 .....

<used-allow android: name = "ERIC.WRITE_EXTERNAL_STORAGE" />

và đừng quên thêm mã vào bảng kê khai


4
     //Create File object for Parent Directory
File wallpaperDir = new File(Environment.getExternalStorageDirectory().getAbsoluteFile() +File.separator + "wallpaper");
if (!wallpaperDir.exists()) {
wallpaperDir.mkdir();
}


File out = new File(wallpaperDir, wallpaperfile);
FileOutputStream outputStream = new FileOutputStream(out);

3

Chỉ cần hoàn thành bài của Vijay ...


Rõ ràng

uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"

Chức năng

public static boolean createDirIfNotExists(String path) {
    boolean ret = true;

    File file = new File(Environment.getExternalStorageDirectory(), path);
    if (!file.exists()) {
        if (!file.mkdirs()) {
            Log.e("TravellerLog :: ", "Problem creating Image folder");
            ret = false;
        }
    }
    return ret;
}

Sử dụng

createDirIfNotExists("mydir/"); //Create a directory sdcard/mydir
createDirIfNotExists("mydir/myfile") //Create a directory and a file in sdcard/mydir/myfile.txt

Bạn có thể kiểm tra lỗi

if(createDirIfNotExists("mydir/")){
     //Directory Created Success
}
else{
    //Error
}

3

Điều này sẽ tạo thư mục trong sdcard với tên Thư mục bạn cung cấp.

File file = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Folder name");
        if (!file.exists()) {
            file.mkdirs();
        }

1

Bạn có thể sử dụng / sdcard / thay vì Môi trường.getExternalStorageDirectory ()

private static String DB_PATH = "/sdcard/Android/data/com.myawesomeapp.app/";

File dbdir = new File(DB_PATH);
dbdir.mkdirs();

4
Không, bạn không nên sử dụng đường dẫn được mã hóa cứng thay vì gọi API thích hợp. Làm như vậy giới thiệu một sự phụ thuộc không khôn ngoan vào các chi tiết của một triển khai cụ thể.
Chris Stratton

1
ivmage.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            // TODO Auto-generated method stub
            Intent i = new Intent(
                    Intent.ACTION_PICK,
                    android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);

            startActivityForResult(i, RESULT_LOAD_IMAGE_ADD);

        }
    });`
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.