How to open a directory from intent in android? - java

I am trying to open a directory with the help of an intent to show the user what is the content inside that folder but I am unable to do so,
but I don't know why the folder won't open and I get this "Can't use this folder" on the file manager.
open.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + "/" + "XYZ";
Uri uri = Uri.parse(path);
Toast.makeText(MainActivity.this, ""+path, Toast.LENGTH_SHORT).show();
openDirectory(uri);
}
});
The method
public void openDirectory(Uri uriToLoad){
// Choose a directory using the system's file picker.
int result = 1;
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when it loads.
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad);
startActivityForResult(intent, result);
}
I want to open the folder XYZ after clicking on the button

I am trying to open a directory with the help of an intent to show the user what is the content inside that folder
There is no standard Intent action for that, sorry. Your code is trying to let the user select a document tree.
It is also doing that incorrectly, as EXTRA_INITIAL_URI does not take a file:// Uri as a value. That needs to be some Uri that you obtained previously from the Storage Access Framework, such as via some past ACTION_OPEN_DOCUMENT_TREE request.
I don't know why the folder won't open and I get this "Can't use this folder" on the file manager
From Android's standpoint, your EXTRA_INITIAL_URI value is little better than a random string.
But the user won't know where actually XYZ folder is
Then perhaps you should have let the user choose the location in the first place, rather than forcing a particular location. For example, you could use ACTION_CREATE_DOCUMENT to let the user decide where to place the document on the user's device (or the user's cloud storage, the user's network file server, etc.).

As far as I know using Intent you can browse, open and create files, that shared for all apps by the system. In this case for get file path to open, you can use next code like this (pardon for my Kotlin):
private var launcherForResult =
registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
if (result.resultCode == Activity.RESULT_OK) {
result.data.also { uri -> filePath = uri.toString() }
}
}
private fun getFilePath() {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
type = "*/*"
addCategory(Intent.CATEGORY_OPENABLE)
}
launcherForResult.launch(intent)
}
As for the directory, it usually opens the last one that was opened before.
If you don't want other applications to see your files, store them in your application's private directory

Related

Concerns about the FILES AND MEDIA PERMISSIONS on Android as a developer

I'm developing an app that saves data into a database, I'm trying to backup and restore that database which I am able to do, my issue is with the "ominous" permmission popup on API30+
Allow management of all files
Allow this app to access modify and delete files on your device.....
Allow this app to access, modify and delete files on the device or any connected storage devices? this app may access files without asking you.
I'm not trying to do any of these things, I just want permission to do the backup/restore thing
here's my code for requesting permission:
private void requestStoragePermissionExport(){
if( (Build.VERSION.SDK_INT >= 30 )){
try {
Intent intent = new Intent(Manifest.permission.MANAGE_EXTERNAL_STORAGE);
intent.addCategory("android.intent.category.DEFAULT");
intent.setData(Uri.parse(String.format("package:%s",getApplicationContext().getPackageName())));
startActivityForResult(intent, 2296);
} catch (Exception e) {
Intent intent = new Intent();
intent.setAction(Settings.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION);
startActivityForResult(intent, 2296);
}
}else{
ActivityCompat.requestPermissions(this, new String[]{
Manifest.permission.WRITE_EXTERNAL_STORAGE}, BACKUP_CODE);
}
}
is there a better way to handle this?
Google is restricting use of broad file permissions such as MANAGE_EXTERNAL_STORAGE. You can use Storage Access Framework to gain limited access to certain files or directories.
// Request code for selecting a PDF document.
const val PICK_PDF_FILE = 2
fun openFile(pickerInitialUri: Uri) {
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT).apply {
addCategory(Intent.CATEGORY_OPENABLE)
type = "application/pdf"
// Optionally, specify a URI for the file that should appear in the
// system file picker when it loads.
putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri)
}
startActivityForResult(intent, PICK_PDF_FILE)
}
Or if you want to access an entire directory;
fun openDirectory(pickerInitialUri: Uri) {
// Choose a directory using the system's file picker.
val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when it loads.
putExtra(DocumentsContract.EXTRA_INITIAL_URI, pickerInitialUri)
}
startActivityForResult(intent, your-request-code)
}
There are some restrictions to which paths you can access. You can read more about it here
https://developer.android.com/training/data-storage/shared/documents-files
You can just backup your db file to the public Documents directory.
No need for the permissions you mentioned.
Alright so, after a bit of research I found the best solution for myself is as follows:
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS) + File.separator + "foldername"
this doesn't require permissions and works on below and above API 30

Android 11 use "Intent.ACTION_OPEN_DOCUMENT" select file in "Downloads" folder [duplicate]

This question already has answers here:
Android Kotlin: Getting a FileNotFoundException with filename chosen from file picker?
(5 answers)
Android - Get real path of a .txt file selected from the file explorer
(1 answer)
Closed 1 year ago.
I am struggling to access files in downloads folder that user can select.
Using the following to give user to select file
Intent intent;
if (SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) {
intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
} else {
intent = new Intent(Intent.ACTION_GET_CONTENT);
}
// Filter to only show results that can be "opened", such as a
// file (as opposed to a list of contacts or timezones)
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Filter to show only application/pdf, using the image MIME data type.
intent.setType(PDF_MIME_TYPE);
if (activity != null) {
activity.startActivityForResult(intent, requestCode);
}
As you might know then the following method is called when user selects the file
#Override
public void onActivityResult(int requestCode, int resultCode, Intent data)
(Expected): Please see the following I can get a decent path from selecting another folder I created "fromPC"(observe it is a file named:"815" and extension "PDF"):
(Problem): When doing the exact same code but selecting "Downloads" folder I only get "873" at the end but the file name I selected was "PaymentNotification" and extension "PDF":
Reading online but nothing quite as specific as this.
So I am not sure how to let user select a file example PDF from "Downloads" folder after the scope storage change in new Android thanks in advance for the answer?
If there are a way to get a "File"(java.io) from within the "onActivityResult" method it would also solve my problem?

How to open a file in external storage from an application? (Android)

I've added a button to my application which is supposed to open the download folder of the phone, and from there you should be able to click on files that were stored there, from the same app. Right now im saving some data there.
Problem is; I cant open the saved files in the folder.
I can see the files stored right there, but when I press one of them you immediatley go back to the app and not the file that you pressed.
Is there something I'm missing? Are you not supposed to open files stored in external storage from another app?
I've tried adding permissions in manifest and checkSelfpermission for checks in runtime, but with no success.
Here's the button for opening download folder:
private void openSavedLocation(){
if (ContextCompat.checkSelfPermission(ExportAndImport.this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(ExportAndImport.this, new String[] {Manifest.permission.READ_EXTERNAL_STORAGE}, 1);
}
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS).getPath());
intent.setDataAndType(uri, "text/xml");
startActivity(Intent.createChooser(intent, "Open Folder"));}
I can open the file perfectly when Im opening it outside the app, not via this "createChooser". What could i be missing?
Any help is appreciated.
but when I press one of them you immediatley go back to the app and not the file that you pressed
That is what your code does. ACTION_GET_CONTENT says "let the user pick a piece of content". It does not say "open that piece of content in some other app". There is no single Intent action for saying "let the user pick a piece of content, then open that piece of content in some other app".
Is there something I'm missing?
If you want to try to open the XML in some other app:
Use startActivityForResult(), not startActivity(), for your ACTION_GET_CONTENT request (and get rid of the createChooser() bit)
Override onActivityResult() to get the result of the user's choice
If the user chose something (i.e., you get RESULT_OK in onActivityResult()), create an ACTION_VIEW Intent wrapped around the Uri that you get from the Intent passed into onActivityResult(), and call startActivity() on the ACTION_VIEW Intent
If, instead, your objective is to open this XML in your app, you would:
Use startActivityForResult(), not startActivity(), for your ACTION_GET_CONTENT request (and get rid of the createChooser() bit)
Override onActivityResult() to get the result of the user's choice
If the user chose something (i.e., you get RESULT_OK in onActivityResult()), get the Uri of the content from the Intent passed into onActivityResult(), then use ContentResolver to do something useful with that Uri (e.g., openInputStream() to read in the content)
Here's the button for opening download folder
ACTION_GET_CONTENT uses the MIME type. It will not necessarily honor your supplied starting Uri.

Launch Microsoft Word from app

I am trying to use the Microsoft word app available for android but cant seem to find the Intent options documented
I have a file and wish to open with Word:
private void editfile(final String file, final String field) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
Uri uri = Uri.parse(file);
intent.setDataAndType(uri,"appliction/*");
activity.startActivity(intent);
}
This launches Word, but doesn't open the selected file - in fact all the files in my storage are greyed out and not selectable (but can be selected if I run Word outside my app)
Is there an interface guide? anyone with any experience of using?

How to browse to file explorer in android through code

Hi I want to browse to a file explorer and select a pdf or image present in some directory.
I want the code to do the same.
the below code takes me to gallery and help me choose image but I want to move to file explorer then select file and accordingly I want the code in onactivityResult after selecting.
browsePic.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View v) {
Intent i = new Intent(
Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI
);
startActivityForResult(i, LOAD_IMAGE_RESULTS);
}
});
I believe you can throw out an open intent for a file chooser using the following.
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
try{
startActivityForResult(intent, LOAD_IMAGE_RESULTS);
} catch (ActivityNotFoundException e){
Toast.makeText(YourActivity.this, "There are no file explorer clients installed.", Toast.LENGTH_SHORT).show();
}
The trouble is however, this assumes your user has a file browser open to accepting intents installed on their device, when often no such apps are installed on a device by default.
As in the code above, you may have to throw up a dialog if no Activities exist that can accept this intent, explaining that they need to install a file browser. You could even recommend one that you know works with your application.
I hope this helps.
i think you could do something like this
File strDir = new File("/mnt/"); // where your folder you want to browse inside android
if( strDir.isDirectory()){
//do something
}

Categories