Android Sharing files without FileProvider - android

I have tried to share a file using the Android Sharesheet, and the guide says I should use the FileProvider.
But in my situation, I can't use the FileProvider due to APK size.
Is there any way to share a file via the Android Sharesheet without using the FileProvider?
A file that I want to share is in the external storage such as "/sdcard/abc/file.zip".
I have already tried this, but it didn't work.
Uri uri = Uri.parse("file://" + file_path); // FileUriExposedException
// Uri uri = Uri.parse("content://" + file_path); // when sharing via GMail app, a toast appears with message "Couldn't attach file"
Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND);
intent.setType("application/zip");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "Share"));

Related

Show a different filename when opening file with ACTION_VIEW intent on android

I have a file stored in my App's storage like this:
/storage/emulated/0/Android/data/com.example.myapp/files/App files/90210_John_s_Resume.pdf
the 90210 at the beginning is a file ID for internal purposes only, and I give the user the option to save this file to Downloads folder, where I remove the 90210 prefix. But I also provide the user to preview the file using ACTION_VIEW intent. This causes an issue where the file name in the previewed app still has the 90210 prefix. Is there a way to overcome this?
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri fileUri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider", finalFile);//NO I18N
intent.setDataAndType(fileUri, URLConnection.guessContentTypeFromName(fileUri.toString()));
context.startActivity(intent);

How to open a 3D-PDF file with an external app via Android Intent

I have downloaded a 3D-PDF file within my Android app, which I want to open in an external app via an Intent. I'm using "3D PDF Reader" as the external app.
This is the source code in Java:
Uri fileUri = FileProvider.getUriForFile(MainActivity.this,
BuildConfig.APPLICATION_ID + ".provider", file);
try {
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(fileUri, "application/pdf");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
} catch (ActivityNotFoundException e) {
showMessage("Keine App zur Anzeige von PDF-Dokumenten gefunden!");
}
And the error message is: "Sorry, 3D content could not be loaded from this PDF. The document is either secured or contains no 3D content."
I am able to show normal PDF files in an external app with this code. When I use the app "Total Commander" (a file manager app) to click on the 3D-PDF, which was downloaded by my app, I am able to load the 3D-PDF file in the external app ("3D PDF Reader"). So it must be possible to achieve my goal.
Any help is very much appreciated.

Share content: Permission Denial when using Intent.createChooser

I am currently adapting my app to Android 11.
When I want to share a file, I get the following error message in logcat:
Permission Denial: reading androidx.core.content.FileProvider uri
content://... from pid=20333, uid=1000 requires the provider be
exported, or grantUriPermission()
But my app is still working and sharing works without problems.
The problem only occurs when I use:
startActivity(Intent.createChooser(intent, "share"));
It does not occur when I use:
startActivity(intent);
In the AndroidManifest.xml of course I set android:requestLegacyExternalStorage to true. targetSdkVersion is 29.
Uri uri = FileProvider.getUriForFile(this, AUTHORITY_FILE, file);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, "subject");
intent.putExtra(Intent.EXTRA_STREAM, uri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intent, "share")); // error
startActivity(intent); // no error
Use ShareCompat.IntentBuilder. It is doing all the right things for you.
For the underlying issue, see https://issuetracker.google.com/issues/173137936
Uri uri = FileProvider.getUriForFile(context, AUTHORITY_FILE, file);
//TODO: Use the proper MIME type. text/plain is for sharing text via EXTRA_TEXT!
// If the file actually contains text, use the type "text/*".
new ShareCompat.IntentBuilder(context)
.setType("text/plain")
.addStream(uri)
.setSubject("subject")
.setChooserTitle("share")
.startChooser();

Android intent doesn't work on .apk files

I'm developing a File Manager, and I open files this way:
fileName = fileToOpen.getName();
fileName = fileName.substring(fileName.lastIndexOf('.') + 1);
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri uri = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID + ".provider", fileToOpen);
intent.setDataAndType(uri, MimeTypeMap.getSingleton().getMimeTypeFromExtension(fileName));
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
This can handle almost all extension, but when I click on .apk files an ActivityNotFoundException gets thrown. I would like to launch the android installation screen.
Only on Android 7.0+ will the package installer know how to work with content Uri values. For earlier versions of Android, you have no choice but to have the APK on external storage somewhere and use a file Uri.

Open folder on card

I thought this was something really simple, but it's giving me more work than the rest of the whole app.
I just want a button to open the "Downloaded Files" folder of my app. That's all. No file picker, nothing complicated. All the button has to do is open a folder with the default app (or open the app chooser if there's no default).
I tried different solutions I saw here on StackOverflow, but nothing seems to work for me.
Example 1:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/MyDownloadedFiles/");
intent.setDataAndType(uri, "text/plain");
startActivity(Intent.createChooser(intent, getString(R.string.action_downloaded)));
On my Android 4.4, this opens the KitKat file picker, and doesn't even open in the folder I want... it seems to be defaulting to the card root. But I'm sure the folder exists and the path being given to the Intent is indeed correct.
Example 2:
Intent intent = new Intent(Intent.ACTION_VIEW);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath() + "/MyDownloadedFiles/");
intent.setDataAndType(uri, "text/plain");
startActivity(Intent.createChooser(intent, getString(R.string.action_downloaded)));
This one opens some blank activity with a popup saying: "Error occurred when getting file Content: MyDownloadedFiles".
How can I make my app to simply have a shortcut to a folder where it puts contents into?
wow.. Finally!! After many things I tried, the only way it worked was by wrapping the URI string into a File first, and then do a Uri.fromFile:
File file = new File(Environment.getExternalStorageDirectory().getPath() + "/MyDownloadedFiles/");
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "*/*");
startActivity(Intent.createChooser(intent, getString(R.string.action_downloaded)));
I think this one could work for you:
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath()
+ "/yourFolder/");
intent.setDataAndType(uri, "*/*");
startActivity(Intent.createChooser(intent, "Open /sdcard/yourFolder"));

Categories

Resources