I am trying to put selected files(not exclusive to images, it can be any file) from file chooser intent to a zip file. I need full file path to do this, but intent only gives uri paths.
I have tried .getPath() but that does not give the real path of the file
I have tried getRealPathFromRealURI: android get real path by Uri.getPath()
I have tried File file = new File(), file.getPath()
This is my code:
public void onActivityResult(int requestCode, int resultCode, Intent result){
if(requestCode == 111) {
if(null != result) { // checking empty selection
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
if(null != result.getClipData()) { // checking multiple selection or not
for(int i = 0; i < result.getClipData().getItemCount(); i++) {
String uri = result.getClipData().getItemAt(i).getUri().getPath();
uriList.add(uri);
Log.d("PATH: ",uri);
}
confirmationDialog();
} else {
String uri = result.getData().getPath();
uriList.add(uri);
Log.d("PATH: ",uri);
confirmationDialog();
}
}else{Toast.makeText(getApplicationContext(),
"An error has occured: API level requirements not met",Toast.LENGTH_SHORT).show();};
}
}
}
It should give the real path for example: "/sdcard/filename.example"
Instead, it gives me: "/document/9016-4ef8:filename.example"
Uri selectedImage = data.getData();
String[] filePathColumn = { MediaStore.Images.Media.DATA };
Cursor cursor = getContentResolver().query(selectedImage,filePathColumn, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
System.out.println("picturePath +"+ picturePath ); //path of sdcard
Found here: Get Real Path For Uri Android
Pick / Get the file's actual path:
val intent = Intent(Intent.ACTION_GET_CONTENT)
intent.type = "*/*"
startActivityForResult(intent, 1)
onActivityResult:
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 1 && resultCode == Activity.RESULT_OK) {
val file = data?.data?.let {
getFileFromUri(requireContext().contentResolver, uri, requireContext().cacheDir)
}
}
}
Get File:
private fun getFileFromUri(contentResolver: ContentResolver, uri: Uri, directory: File): File {
val file =
File.createTempFile("suffix", ".prefix", directory)
file.outputStream().use {
contentResolver.openInputStream(uri)?.copyTo(it)
}
return file
}
Once we get the file, We can get the actual path of the file.
Okay, I fixed it by using another file explorer aside from the built-in file explorer, in my case I used Cx File Explorer, different file explorers return different values.
Related
I am downloading a PDF file from a server and passing the response body bytestream into the function below, which is storing the PDF file successfully in the user downloads folder.
#RequiresApi(Build.VERSION_CODES.Q)
fun saveDownload(pdfInputStream: InputStream) {
val values = ContentValues().apply {
put(MediaStore.Downloads.DISPLAY_NAME, "test")
put(MediaStore.Downloads.MIME_TYPE, "application/pdf")
put(MediaStore.Downloads.IS_PENDING, 1)
}
val resolver = context.contentResolver
val collection = MediaStore.Downloads.getContentUri(MediaStore.VOLUME_EXTERNAL_PRIMARY)
val itemUri = resolver.insert(collection, values)
if (itemUri != null) {
resolver.openFileDescriptor(itemUri, "w").use { parcelFileDescriptor ->
ParcelFileDescriptor.AutoCloseOutputStream(parcelFileDescriptor)
.write(pdfInputStream.readBytes())
}
values.clear()
values.put(MediaStore.Downloads.IS_PENDING, 0)
resolver.update(itemUri, values, null, null)
}
}
Now once this function returns I want to open the saved PDF file. I've tried several ways to get this to work but the pickers always say that there is nothing to open the file. I think that there is either still a permissions issue going on (maybe I'm using the FileProvider wrong?), or perhaps the path is wrong, or it could be something else entirely.
Here's a couple of examples of what I've tried:
fun uriFromFile(context: Context, file: File): Uri {
return FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID + ".provider", file)
}
a)
val openIntent = Intent(Intent.ACTION_VIEW)
openIntent.putExtra(Intent.EXTRA_STREAM, uriFromFile(this, File(this.getExternalFilesDir(DIRECTORY_DOWNLOADS)?.absolutePath.toString(), "test")))
openIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
openIntent.type = "application/pdf"
startActivity(Intent.createChooser(openIntent, "share.."))
b)
val shareIntent = Intent(Intent.ACTION_SEND)
shareIntent.putExtra(Intent.EXTRA_STREAM, uriFromFile(this, File(this.getExternalFilesDir(null)?.absolutePath.toString(), "test.pdf")))
shareIntent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
shareIntent.type = "application/pdf"
startActivity(Intent.createChooser(shareIntent, "share.."))
c)
val file = File(itemUri.toString()) //itemUri from the saveDownload function
val target = Intent(Intent.ACTION_VIEW)
val newFile = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID + ".provider", file);
target.setDataAndType(newFile, "application/pdf")
target.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
val intent = Intent.createChooser(target, "Open File")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
ContextCompat.startActivity(this, intent, null)
d)
val target = Intent(Intent.ACTION_VIEW)
target.setDataAndType(Uri.parse("content://media/external_primary/downloads/2802"), "application/pdf"
target.flags = Intent.FLAG_ACTIVITY_NO_HISTORY
val intent = Intent.createChooser(target, "Open File")
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
ContextCompat.startActivity(this, intent, null)
(also tried /test.pdf on the end of this URI, and replacing media with my authority name)
I have also added this to my manifest file within the application tags:
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
#xml/provider_paths is as follows, although I have tried various combinations in addition to this including the paths as ".":
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-files-path name="files_root" path="/"/>
<files-path name="files_root" path="/"/>
<external-path name="files_root" path="/"/>
</paths>
As a side note, there is definitely pickers available capable of opening PDFs, and going into the file explorer and opening it from there works fine. When attempting to share instead of opening the sharing also fails.
Follow this step and code, it will manage everything from downloading your pdf and opening it.
Create a class name as DownloadTask and put the complete code given below
public class DownloadTask {
private static final String TAG = "Download Task";
private Context context;
private String downloadFileUrl = "", downloadFileName = "";
private ProgressDialog progressDialog;
long downloadID;
private BroadcastReceiver onDownloadComplete = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//Fetching the download id received with the broadcast
long id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1);
//Checking if the received broadcast is for our enqueued download by matching download id
if (downloadID == id) {
downloadCompleted(downloadID);
}
}
};
public DownloadTask(Context context, String downloadUrl) {
this.context = context;
this.downloadFileUrl = downloadUrl;
downloadFileName = downloadFileUrl.substring(downloadFileUrl.lastIndexOf('/') + 1);//Create file name by picking download file name from URL
Log.e(TAG, downloadFileName);
context.registerReceiver(onDownloadComplete, new IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE));
downloadFile(downloadFileUrl);
}
public void downloadFile(String url) {
try {
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getAbsolutePath(), downloadFileName);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url))
.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED)// Visibility of the download Notification
.setDestinationInExternalPublicDir(
Environment.DIRECTORY_DOWNLOADS,
downloadFileName
)
.setDestinationUri(Uri.fromFile(file))
.setTitle(downloadFileName)// Title of the Download Notification
.setDescription("Downloading")// Description of the Download Notification
.setAllowedOverMetered(true)// Set if download is allowed on Mobile network
.setAllowedOverRoaming(true);// Set if download is allowed on roaming network
request.allowScanningByMediaScanner();
DownloadManager downloadManager = (DownloadManager) context.getSystemService(DOWNLOAD_SERVICE);
downloadID = downloadManager.enqueue(request);// enqueue puts the download request in the queue.
progressDialog = new ProgressDialog(context);
progressDialog.setMessage("Downloading...");
progressDialog.setCancelable(false);
progressDialog.show();
} catch (Exception e) {
Log.d("Download", e.toString());
}
}
void downloadCompleted(long downloadID) {
progressDialog.dismiss();
new AlertDialog.Builder(context)
.setTitle("Document")
.setMessage("Document Downloaded Successfully")
.setPositiveButton("Open", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
openDownloadedAttachment(downloadID);
}
})
// A null listener allows the button to dismiss the dialog and take no further action.
.setNegativeButton(android.R.string.no, null)
.setIcon(android.R.drawable.ic_dialog_alert)
.show();
context.unregisterReceiver(onDownloadComplete);
}
Uri path;
private void openDownloadedAttachment(final long downloadId) {
DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE);
DownloadManager.Query query = new DownloadManager.Query();
query.setFilterById(downloadId);
Cursor cursor = downloadManager.query(query);
if (cursor.moveToFirst()) {
int downloadStatus = cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS));
String downloadLocalUri = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_LOCAL_URI));
String downloadMimeType = cursor.getString(cursor.getColumnIndex(DownloadManager.COLUMN_MEDIA_TYPE));
if ((downloadStatus == DownloadManager.STATUS_SUCCESSFUL) && downloadLocalUri != null) {
path = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", new File(Uri.parse(downloadLocalUri).getPath()));
//path = Uri.parse(downloadLocalUri);
Intent pdfIntent = new Intent(Intent.ACTION_VIEW);
pdfIntent.setDataAndType(path, downloadMimeType);
pdfIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_TOP);
try {
context.startActivity(pdfIntent);
} catch (ActivityNotFoundException e) {
Toast.makeText(context, "No Application available to view PDF", Toast.LENGTH_SHORT).show();
}
}
}
cursor.close();
}
}
And then download your pdf like this from your activity.
new DownloadTask(this, "PDF_URL");
And from your fragment
new DownloadTask(getContext(), "PDF_URL");
After download completed it will open your pdf automatically.
According to Android Developer, MediaStore isn't being used for accessing non-media files such as pdf files:
If your app works with documents and files that don't exclusively
contain media content, such as files that use the EPUB or PDF file
extension, use the ACTION_OPEN_DOCUMENT intent action, as described in
the guide on how to store and access documents and other files.
Moreover, there isn't any official solution to access non-media files by means of using Cursor and Content Provider. However, there is an official and clean code approach which I've tested it on Android 11 and worked as expected. here is:
public class retrieve_pdf_file {
#RequiresApi(Build.VERSION_CODES.Q)
public static void get(Activity activity) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/pdf");
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, MediaStore.Downloads.EXTERNAL_CONTENT_URI);
activity.startActivityForResult(intent, main_activity.PICK_PDF_FILE);
}
public static void get(Activity activity, String filename) { // filename is used for lower that API level 29
// older that API level 29 approaches
File file = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
// TODO
}
}
And also, to get the selected pdf file's Uri you must listen for the activity's result:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (requestCode == PICK_PDF_FILE && resultCode == Activity.RESULT_OK) {
System.out.println("request code: PICK_PDF_FILE && result code: OK");
// The result data contains a URI for the document or directory that
// the user selected.
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
// Perform operations on the document using its URI.
System.out.println(uri);
} else {
System.out.println("resultData is null");
}
} else {
System.out.println("result code: NOT OK");
}
}
This is the official solution that can be found in Android Developer for API level 29 or higher.
Here is the code that i use to open doc file with Uri.
fun viewPDFIntent(fileUri: Uri?, context: Context, title: String?, type: String) {
val viewPDFIntent = Intent(Intent.ACTION_VIEW).apply {
setDataAndType(fileUri, type)
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
}
context.startActivity(Intent.createChooser(viewPDFIntent, title))
}
Here type for pdf is "application/pdf".
You are getting created pdf uri in itemUri variable, pass this to first argument of this function.
I get pictures url from gallery or camera on android but I can't convert them to file. When i developing an app with Java in android, sometimes I need to get pictures from gallery and camera to my application. But when i try to do this I'm getting errors.
Isn't there a standard here? The code works at one api level and does not works another one. Or when I take the URI of some images and convert it to file, I get an error regardless of the api level. I wonder if there is a fundamental solution to this problem?
I am starting intent with this
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(intent,IMAGE_RESULT);
And then I'm catching data with this code:
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == Activity.RESULT_OK) {
if (requestCode == IMAGE_RESULT) {
String filePath = ImageFilePath.getPath(OwnProfileActivity.this, data.getData());
selectedFile = new File(filePath);
showProgressDialog();
Handler handler = new Handler();
handler.postDelayed(this::chaneProfileImage, 1000);
}
}
}
May I suggest something like this, but of course this is if you have a bitmap:
private fun getImageUriFromBitmap(image: Bitmap): Uri? {
val bytes = ByteArrayOutputStream()
image.compress(Bitmap.CompressFormat.PNG, 100, bytes)
val relativeLocation = Environment.DIRECTORY_PICTURES + File.pathSeparator + "NotifyMe"
val contentValues = ContentValues().apply {
put(MediaStore.MediaColumns.DISPLAY_NAME, "notifyMe_${System.currentTimeMillis()}")
put(MediaStore.MediaColumns.MIME_TYPE, "image/png")
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
put(MediaStore.MediaColumns.RELATIVE_PATH, relativeLocation)
put(MediaStore.MediaColumns.IS_PENDING, 1)
}
}
return context?.contentResolver?.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, contentValues)
}
Then you can create the file with the uri
val file = File(uri.path)
source: https://gist.github.com/franciscobarrios/9f6634c87ca6e56ed70cd96807dd1dcb
I am accessing pictures of the device's gallery via my app, when the picture is accessed the metadata of the picture will be read and stored in metadata. The problem I'm facing is that whenever the program tries to read the metadata I'm getting the following error java.io.FileNotFoundException: /storage/emulated/0/Snapchat/Snapchat-1185425082.jpg (Permission denied).
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data){
super.onActivityResult(requestCode, resultCode, data);
if(resultCode == RESULT_OK && requestCode == PICK_IMAGE){
imageUri = data.getData();
imageView.setImageURI(imageUri);
File picturesfile = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
picturesfile.setReadable(true);
picturesfile.setExecutable(true);
String[] projection = {MediaStore.Images.Media.DATA};
try {
Cursor cursor = getContentResolver().query(imageUri, projection, null, null, null);
cursor.moveToFirst();
int columnIndex = cursor.getColumnIndex(projection[0]);
path = cursor.getString(columnIndex);
Log.d("Picture Path", path);
}
catch(Exception e) {
Log.e("Path Error", e.toString());
}
File jpegFile = new File(path);
jpegFile.setReadable(true);
jpegFile.setExecutable(true);
try {
metadata = ImageMetadataReader.readMetadata(jpegFile);
for (Directory directory : metadata.getDirectories()) {
for (Tag hoi : directory.getTags()) {
Log.d("tags ", hoi.toString());
}
}
} catch (ImageProcessingException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
if(resultCode == RESULT_OK && requestCode == 0){
Bitmap bitmap = (Bitmap)data.getExtras().get("data");
imageView.setImageBitmap(bitmap);
}
}
Tactically, it would appear that you do not have the READ_EXTERNAL_STORAGE permission, which you need to request in the manifest and at runtime.
Beyond that:
There is no requirement for your query() to return a DATA column
There is no requirement that the DATA column have a value
There is no requirement that the DATA column have a filesystem path
There is no requirement that the filesystem path in the DATA column be a file that you can access, even with READ_EXTERNAL_STORAGE
In particular, it is guaranteed that your code will fail on Android Q, and it is very likely to fail for lots of users on lots of other devices as well.
Use the Uri (imageUri) with ContentResolver to get an InputStream (or perhaps a FileDescriptor) to pass to your library.
I am trying to fetch a file this way:
final Intent chooseFileIntent = new Intent(Intent.ACTION_GET_CONTENT);
String[] mimetypes = {"application/pdf"};
chooseFileIntent.setType("*/*");
chooseFileIntent.addCategory(Intent.CATEGORY_OPENABLE);
if (chooseFileIntent.resolveActivity(activity
.getApplicationContext().getPackageManager()) != null) {
chooseFileIntent.putExtra(Intent.EXTRA_MIME_TYPES, mimetypes);
activity.startActivityForResult(chooseFileIntent, Uploader.PDF);
}
Then in onActivityResult :
#Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
}
According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath(), the file name I'm expecting is my_file.pdf, but instead I'm getting this :
/document/acc=1;doc=28
So what to do? Thanks for your help.
I am trying to fetch a file
Not with that code. That code is asking the user to pick a piece of content. This may or may not be a file.
According to many threads I'm supposed to fetch the file name from the intent with data.getData().getPath()
That was never correct, though it tended to work on older versions of Android.
So what to do?
Well, that depends.
If you wish to only accept files, integrate a file chooser library instead of using ACTION_GET_CONTENT. (UPDATE 2019-04-06: since Android Q is banning most filesystem access, this solution is no longer practical)
If you are willing to allow the user to pick a piece of content using ACTION_GET_CONTENT, please understand that it does not have to be a file and it does not have to have something that resembles a filename. The closest that you will get:
If getScheme() of the Uri returns file, your original algorithm will work
If getScheme() of the Uri returns content, use DocumentFile.fromSingleUri() to create a DocumentFile, then call getName() on that DocumentFile — this should return a "display name" which should be recognizable to the user
To get the real name and to avoid getting a name that looks like "image: 4431" or even just a number, you can write code as recommended by CommonsWare.
The following is an example of a code that selects a single pdf file, prints its name and path to the log, and then sends the file by email using its uri.
private static final int FILEPICKER_RESULT_CODE = 1;
private static final int SEND_EMAIL_RESULT_CODE = 2;
private Uri fileUri;
private void chooseFile() {
Intent fileChooser = new Intent(Intent.ACTION_GET_CONTENT);
fileChooser.setType("application/pdf");
startActivityForResult(Intent.createChooser(fileChooser, "Choose one pdf file"), FILEPICKER_RESULT_CODE);
}
#Override
protected void onActivityResult(int requestCode, int resultCode, #Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILEPICKER_RESULT_CODE) {
if (resultCode == RESULT_OK) {
fileUri = data != null ? data.getData() : null;
if (fileUri != null) {
DocumentFile d = DocumentFile.fromSingleUri(this, fileUri);
if (d != null) {
Log.d("TAG", "file name: " + d.getName());
Log.d("TAG", "file path: " + d.getUri().getPath());
sendEmail(fileUri);
}
}
}
}
}
private void sendEmail(Uri path) {
String email = "example#gmail.com";
Intent intent = new Intent(android.content.Intent.ACTION_SEND);
intent.setType("application/octet-stream");
intent.putExtra(android.content.Intent.EXTRA_SUBJECT, "PDF file");
String[] to = { email };
intent.putExtra(Intent.EXTRA_EMAIL, to);
intent.putExtra(Intent.EXTRA_TEXT, "This is the pdf file...");
intent.putExtra(Intent.EXTRA_STREAM, path);
startActivityForResult(Intent.createChooser(intent, "Send mail..."), SEND_EMAIL_RESULT_CODE);
}
hope it helps.
In my application i want to create subdirectories in choosen directory. Im using SAF (Storage Access Framework): choose directory and create one subdirectory works fine.
Choose directory:
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, REQUEST_CODE_PATH_TO_DATA);
Create subdirectory:
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode != Activity.RESULT_OK) {
return;
}
if (requestCode == REQUEST_CODE_PATH_TO_DATA) {
if (data == null) {
return;
}
DocumentFile pickedDir = DocumentFile.fromTreeUri(getActivity(), data.getData());
getActivity().grantUriPermission(getActivity().getPackageName(), data.getData(), Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getActivity().getContentResolver().takePersistableUriPermission(data.getData(), Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
pickedDir.createDirectory("Portfolio");
String pathToPickedDir = "";
for (DocumentFile file : pickedDir.listFiles()) {
if (file.isDirectory() && file.getName().endsWith("Portfolio")) {
pathToPickedDir = file.getUri().toString();
}
}
}
}
URI from pickedDir is:
content://com.android.externalstorage.documents/tree/314E-7741%3ADCIM
And URI from created subdirectory "Portfolio" is:
content://com.android.externalstorage.documents/tree/314E-7741%3ADCIM/document/314E-7741%3ADCIM%2FPortfolio
And then when im trying to create subdirectory in "Portfolio" i can't do that, because the directory is created in the folder that was initially selected, not in the "Portfolio" folder.
DocumentFile pickedDir = DocumentFile.fromTreeUri(getActivity(), pathToPickedDir);
pickedDir.createDirectory("Patient");
What am I doing wrong? Thank you for your help.
Only way that i found is using "for" cycle:
for (DocumentFile file : pickedDir.listFiles()) {
if (file.isDirectory() && file.getName().equals("Portfolio")) {
file.createDirectory("Subdirectory");
}
}
The following should work in your case:
DocumentFile portfolioDir = pickedDir.createDirectory("Portfolio");
portfolioDir.createDirectory("Patient");
In your code, you are not using the directory object returned by DocumentFile.createDirectory(), which is the object of the newly created directory, in which you want to create a sub-directory.