Through my application the user can choose a file from the filemanager and process the choosen file ( Example: A PDF document ) for other steps like printing or to email.
To do this I used the below code to display the intent, from which the user can choose a file from file-manager option.
protected void showFileChooser(String title, String type) {
Log.i(TAG, "FileChooserActivity showFileChooser(title,type)");
if (TextUtils.isEmpty(title)) title = getString(R.string.select_file);
if (TextUtils.isEmpty(type)) type = "*/*";
// Implicitly allow the user to select a particular kind of data
final Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// Specify the MIME data type filter (Must be lower case)
intent.setType(type.toLowerCase());
// Only return URIs that can be opened with ContentResolver
intent.addCategory(Intent.CATEGORY_OPENABLE);
// Display intent chooser
try {
startActivityForResult(
Intent.createChooser(intent, title),6384);
} catch (android.content.ActivityNotFoundException e) {
Log.i(TAG,"FileChooserActivity showFileChooser(title,type) Exception" +Log.getStackTraceString(e));
onFileError(e);
}
}
Problem in Android Kitkat version ( 4.4 ) :
Using the above code , I can access all files from the file manager ( i.e., both sub folder's and root folder) in android 4.3 and all android versions except Android 4.4.
In Android 4.4 , I can access files from the root folder, where as I cant access the files from the subfolders. I get java.io.FileNotFoundException as exception.
Note:
I installed Astro File Manager and through this I can access both root and sub-folders in Android 4.4. But I cant access the sub-folder files through Androids default file manager.
Related
I am working on an application which shows the list of whatsapp status in the app. Now my questions it that after the scoped storage we can't access that specific path so what to do now? Or all the whatsapp status saver applications won't work in future?
Right now i am access the statuses folder like this.
String whatsappStatus = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses");
But it is not working on android 11 of course.If i use
All files access
to access all files on phone google play don't allow it unless it's the last solution which is not the case here.
Is there any hope that whatsapp would store the status in public directly in future or they would allow access to that specific directly?
private void checkWhatsAppPermission(){
// Choose a directory using the system's file picker.
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.
Uri wa_status_uri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia/document/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses");
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, wa_status_uri);
startActivityForResult(intent, 10001);
}
You can check a working example here.
https://play.google.com/store/apps/details?id=com.larntech.whatsappstatussaver
You should use runtime permission which is storage access framework permission read documents
Choose a directory using the system's file picker.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
Uri wa_status_uri = Uri.parse("content://com.android.externalstorage.documents/tree/primary%3AAndroid%2Fmedia/document/primary%3AAndroid%2Fmedia%2Fcom.whatsapp%2FWhatsApp%2FMedia%2F.Statuses");
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, wa_status_uri);
startActivityForResult(intent, 10001);
new path
String whatsappStatus = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses");
and put one condition like this
if (android.os.Build.VERSION.SDK_INT < 30) {
String whatsappStatus = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/WhatsApp/Media/.Statuses");
}else {
String whatsappStatus = (Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/.Statuses");
}
I have code which attempts to open GPX files:
public void performFileSearch(String type) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("application/*");
String[] mimeTypes = new String[]{type.equals("KMZ")?"application/vnd.google-earth.kmz":"application/gpx+xml"};
intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(Intent.createChooser(intent, "Choose file"), DIR_ACCESS_REQUEST_CODE);
} else {
Log.d("****File","Unable to resolve Intent.ACTION_OPEN_DOCUMENT");
}
}
and it works fine for files downloaded on the device itself. But if a GPX file is copied from my Windows desktop, the file is greyed out on the Android listing, with an incorrect file type (see screenshot below).
Even with the same file (e.g. the 'ElmFarm' one in the listing shown), downloaded from the same server, it appears correctly if downloaded from Chrome on the browser. If downloaded from Chrome on Windows, or from Safari on iPhone, then copied to the Android phone (using Windows file explorer, or via an email) it shows as type 'bin' (or 'csv') and can't be loaded into my app. If I use the 'Device File Explorer' in Android Studio, the contents of these files are identical.
What is going wrong here? Looks like a Mime type is embedded in the files somewhere, but where, and why are they changing?
I need to open a specific folder in Android 10, so that only the files inside that folder can be seen in my app.
I have tried this:
try {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
File f = new File(getExternalFilesDir(null) + "/MyFolder");
Uri uri = FileProvider.getUriForFile(getApplicationContext(),getApplicationContext().getPackageName()+".provider",f);
Toast.makeText(MainActivity.this,f.getPath(),Toast.LENGTH_LONG).show();
intent.setDataAndType(uri,"text/plain");
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
}
catch (Exception e) {
Log.d("Exception",e.toString());
Toast.makeText(MainActivity.this, e.toString(), Toast.LENGTH_LONG).show();
}
But, it opens the entire tree.
What I actually want is to open that folder. The files in the folder should be openable by other apps. Any help will be appreciated.
I need to open a specific folder in Android 10, so that only the files inside that folder can be seen in my app
Sorry, but that is not an option.
The closest thing to what you want is EXTRA_INITIAL_URI. However:
It takes a document or tree Uri that you obtained previously from the Storage Access Framework, not a FileProvider Uri; and
It does not prevent users from navigating elsewhere — it just controls the starting point
I am trying to open a file manager that will show the folder that I send to it via Intent. The file manager should act like a file manager and not a file picker, i.e. it will not return to my app once I decide to select a file from the given folder, but it will present standard options that are normally available when file manager is launched from the launcher icon.
I have tried the following:
File folder = getOutputFolder();
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
// I have tried: ACTION_VIEW, ACTION_GET_CONTENT, ACTION_OPEN_DOCUMENT
Uri uri;
if (Build.VERSION.SDK_INT >= 26) {
String authority = getString(R.string.app_fileprovider);
uri = FileProvider.getUriForFile(this, authority, folder);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
uri = Uri.fromFile(folder);
}
// this with ACTION_GET_CONTENT, works as *picker* on API 28
// on API 29 it does not open destination folder
// intent.setData(uri);
intent.setDataAndType(uri, "*/*");
// I have tried the following: image/*, file/*, */*, resource/folder
// and DocumentsContract.Document.MIME_TYPE_DIR
startActivity(Intent.createChooser(intent, getString(R.string.open_output_folder)));
All combinations that I have tried act as a file picker, and that's not what I am looking for. More than that, some combinations open the destination folder, some not. The behavior is different depending on API level as well.
Is there a standard way to achieve what I am looking for?
I have tried to open particular folder in gallary as below code but it didn't work for me, and getting error for Unable to find item.
fun openDirectoryInGallery(context: Context, directory: String) {
val intent = Intent(Intent.ACTION_VIEW)
val file = if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
File(Environment.getExternalStoragePublicDirectory(
Environment.DIRECTORY_PICTURES), directory)
} else {
File(Environment.DIRECTORY_PICTURES.plus(File.separator).plus(directory))
}
intent.setDataAndType(Uri.withAppendedPath(Uri.fromFile(file), directory), "*/*")
intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK
startActivity(context, Intent.createChooser(intent, "Open folder"), Bundle())
}
There has never been support for this in the OS. This is a question of the installed apps on the device.
There has never been a requirement that a device have a gallery app that is able to respond to ACTION_VIEW for a directory.
Your app should be crashing with a FileUriExposedException on Android 7.0+, and the existence of that exception is why fewer and fewer apps are bothering to support the file scheme.
On Android 10+, the file scheme (and Uri.fromFile() by extension) is simply pointless, as if your app can access the file, other apps cannot.
Finally, Environment.DIRECTORY_PICTURES.plus(File.separator).plus(directory) is not a valid filesystem path.
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"SelectPicture"),PICK_IMAGE_REQUEST);