0

I am trying to create a directory on the external sdcard in my Samsung S4. Doing something like this,

public void createTestFile(){
File appDir = new File(Environment.getExternalStorageDirectory() + "/external_sd", "TestFile");
appDir.mkdir();
}

does not create a directory on my external sdcard. According to several other StackOverflow posts, and the Samsung developer's forum (http://developer.samsung.com/forum/board/thread/view.do?boardName=GeneralB&messageId=162934&messageNumber=1381&startId=zzzzz~&searchType=TITLE&searchText=sdcard) it should.

Checking the application manifest I have the following permission,

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

What am I missing here? This device is rooted and I am running a recent CyanogenMod 12.1 nightly. The permissions for /sdcard, /external_sd, and /extSdCard appear correct.

I've also tried,

File appDir = new File(Environment.getExternalStorageDirectory().getParent() + "/external_sd", "TestFile"); 

as well as .getAbsolutePath(), and .getPath() with no luck whatsoever. What am I missing here? It's got to be simple...

Update 11/21/2015 7:00pm Tried the following,

public void createTestFile(){
String showPath = Environment.getExternalStorageDirectory().getParent();// "../storage/emulated"
//String finalPath = showPath+"/0"; // "../storage/emulated/0" This works- writes to internal sdcard.
//String finalPath = showPath+"/1"; // "../storage/emulated/1" Doesn't work- does not write to external sdcard.
String finalPath = showPath+"/external_sd"; // "../storage/emulated/external_sd" Doesn't work either...
File appDir = new File(finalPath, "testFile");
appDir.mkdir();
}

I thought for sure that having my finalPath string = "/storage/emulated/1" or "/storage/emulated/external_sd" would have written a directory to the removeable sdcard, but neither did. Functionally, it seems as if /external_sd is read-only, however checking permissions I find that owner/group/users are all checked. Suggestions?

Second update 11/21/2015 8:10pm After a quick review of /proc/mounts I found the following storage/sdcard references,

/dev/fuse /storage/sdcard1 ...
/dev/fuse /storage/emulated/0 ...
/dev/fuse /storage/emulated/0/Android/obb ... 
/dev/fuse /storage/emulated/legacy ...
/dev/fuse /storage/emulated/legacy/Android/obb ... 

Based on this I revised,

File appDir = new File(Environment.getExternalStorageDirectory().getParent() + "/external_sd", "TestFile");

to,

File appDir = new File(/storage/sdcard1, "testFile");

and was able to finally create a directory on my removeable sdcard. This is clearly a dirty, kludgy fix. Suggestions on a better way? Full /proc/mount for the external sdcard are below. TIA

/dev/fuse /storage/sdcard1 fuse rw,nosuid,nodev,noexec,noatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
portsample
  • 1,986
  • 4
  • 19
  • 35
  • Does external_sd folder exist? What if you try first: File appDir = new File(Environment.getExternalStorageDirectory(), "MyNewDir"); if(!appDir.exists()) { appDir.mkdirs(); } – mayo Nov 21 '15 at 22:03
  • 'does not create a directory on my external sdcard.'. Then where is it created instead? There are no functions in Android to easily determine the path to removable storage. Mostly it is impossible. – greenapps Nov 21 '15 at 22:26
  • @mayo- /external_sd is the default directory on Samsung phones created for the external removeable sdcard. Writing a file to the "internal" sdcard is no problem using 'File appDir = new File(Environment.getExternalStorageDirectory(), "TestFile"); 'The directory "/external_sdcard" exists, observable via browser. Thanks. – portsample Nov 21 '15 at 23:12
  • Does this code creates directory on other devices ? If not then there looks some problem with your way of assigning directory name in your code. – Arslan Ashraf Nov 22 '15 at 04:47

2 Answers2

0

Crude, but works.

public void createNewFile(){
    String szFilePath;
    //if jactivelte (Samsung S4 Active) with CyanogenMod 12.1 ROM, then write to removable sdcard
     if (android.os.Build.DEVICE.contains("jactivelte")){
         szFilePath = "/storage/sdcard1";
     }else{ //any other ROM, will *likely* write to internal sdcard
         szFilePath = Environment.getExternalStorageDirectory().getAbsolutePath();
     }
     File appDir = new File(szFilePath, "testFile");
     appDir.mkdir();
}

Open to accepting other answers that default file creation to removable sdcard if one is present.

portsample
  • 1,986
  • 4
  • 19
  • 35
0

Better solution.

public void createRemoveableSdcardFile(View view) {     
    if(Build.VERSION.SDK_INT >=19){
        File[] fo = getExternalFilesDirs(null);
        File f =fo[1];  
        File appDir = new File(f, "TargetFile");
        appDir.mkdir();  
        makeTimestamp();
        File exportDir = new File(f, "TargetFile/" + szDateTime);
        exportDir.mkdir();      
    }else if(Build.VERSION.SDK_INT < 19){
        String szFilePath = System.getenv("SECONDARY_STORAGE");     
        File appDir = new File(szFilePath, "TargetFile");
        appDir.mkdir();  
        makeTimestamp();
        File exportDir = new File(szFilePath, "TargetFile/" + szDateTime);
        exportDir.mkdir();
    }
public void makeTimestamp(){    
    Date T = new Date();        
    SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
    szDateTime = sdf.format(T); 
}
portsample
  • 1,986
  • 4
  • 19
  • 35