How to share Videos to any app using Intent? - android

Issue: What happens is after sharing the video when i launch the app to check the shared video it shows me error of "Unable to import" and "The video is no longer available".
Android Version: Oreo(8.0)
Code: I am trying with the following code to share videos with other apps using intent:
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("video/*");
share.putExtra(Intent.EXTRA_SUBJECT, "abc");
share.putExtra(Intent.EXTRA_TITLE, "abcd");
File imageFileToShare = new File(Environment.getExternalStorageDirectory() + "/mygallery/" + "airp.mp4");
Uri uri = FileProvider.getUriForFile(Main2Activity.this, "abc.dcf.fileprovider", imageFileToShare);
share.putExtra(Intent.EXTRA_STREAM, uri);
share.setPackage("com.abc.in");
startActivity(Intent.createChooser(share, "Message"));
The above code is working fine to share Images but its not working to share videos.
What i have tried: I have tried by sharing various file types like 3gp, mkv, mp4 but nothing is working out and I have also went through various similar questions but no solution is working in case of videos.
Please help me with this issue and also if there is any alternate way to do so?

You can add this to your OnCreate
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
If that doesn't work for you,
Add Provider to Manifest by doing this
<provider
android:name="android.support.v4.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>
Remember to use android:name="androidx.core.content.FileProvider" if you're using androidx
Create a file in xml directory (res/xml) and name provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="."/>
</paths>
Replace
Uri uri = FileProvider.getUriForFile(Main2Activity.this, "abc.dcf.fileprovider", imageFileToShare);
with this
Uri uri = FileProvider.getUriForFile(Main2Activity.this, BuildConfig.APPLICATION_ID + ".provider",imageFileToShare);

Related

Android: Send e-mail via intent with file as attachment

There are many posts on this topic, but I can't find the solution for my problem...
Following: I would like to send a file out of my app via an e-mail attachment.
Sending the file via Whatsapp, save to Google Drive,... works, but not for K-9 Mail or Gmail ("Unable to attache file" Toast message is displayed).
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
intentShareFile.setType("application/zip");
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("/sdcard/Download/ExportFile.zip"));
//intentShareFile.putExtra(Intent.EXTRA_TEXT, "message");
intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intentShareFile.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(Intent.createChooser(intentShareFile, "Share File"));
I don't understand why it works for all apps, except e-mail apps.
Can anyone help me out?Thanks in advance.
I think your issue is related to the path of the file you are using here (i.e Uri.parse("/sdcard/Download/ExportFile.zip"))
There is a code example to send an email with an attachment on the Android Developers docs here. In the example they pass the Uri as follows:
Uri.parse("content://path/to/email/attachment"). Notice this is called a ContentUri, read more about it form here.
Hope this turns useful for you!
Amr EIZawawy is right. I need to create the Uri of the file and use the File Provider API.
I don't know if I did too much, but this is my solution:
Create a file called "file_paths.xml" in a directory "xml" (create first) within your "res" directory (sibling of layout directory).
The file needs to contain the path to the file you want to share. For the external Download directory this is:
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="download" path="Download/"/>
</paths>
// The internal path you'd be <files-path name.../> see [FileProvider][1] for all possibilities
Define the File provider within the AndroidManifest.xml with a meta-data link to the just created XML file:
<application
...
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.<your-app-package-name>.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" /> // Link to the above created file
</provider>
...
Implement the code:
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
intentShareFile.setType("application/zip");
File fileDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
File newFile = new File(fileDirectory, "ExportFile.zip");
String authority = "com.bennoss.myergometertrainer.fileprovider"; // Must be the same as in AndroidManifest.
Uri contentUri = FileProvider.getUriForFile(getContext(), authority, newFile);
intentShareFile.putExtra(Intent.EXTRA_STREAM, contentUri);
//intentShareFile.putExtra(Intent.EXTRA_TEXT, "xxx");
intentShareFile.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(intentShareFile, "Share File"));
For more information see: FileProvider

Android PDF not accepted when sending as Intent.ACTION_SEND

I have a PDF file I am trying to share through Intent.ACTION_SEND. Though when I click on one of the options (gmail, google drive, etc). It says "Request contains no data."
**Updated Code Below
case R.id.share_item:
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
shareIntent.putExtra(Intent.EXTRA_STREAM, displayedFile.getAbsolutePath());
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "Share PDF using.."));
return true;
}
I assume the issue must be with my putExtra? That being said the URL for my file definitely works because I can successfully use that path for printing PDFs.
Edit:
I've Updated my code a smidge.
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
Uri uri = Uri.parse(displayedFile.getAbsolutePath());
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "Share PDF using.."));
This gets me "file format not accepted" from Whatsapp and "Unable to attach file" from Gmail.
Wondering if the issue is with calling from Internal Storage or not using FileProvider.
Edit 2:
Trying to add this code but I am getting a crash
Uri outputPdfUri = FileProvider.getUriForFile(this,
PdfViewActivity.this.getPackageName() + ".provider", sharingFile);
I've also added this to my Manifest and file_paths
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="com.example.androidextensiontest.files"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
Alright sharing my own answer because I spent hours on this.
case R.id.share_item:
//these policy guidlines do not follow google Guidelines, recommended to change system
//https://stackoverflow.com/questions/48117511/exposed-beyond-app-through-clipdata-item-geturi
StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
StrictMode.setVmPolicy(builder.build());
final Intent shareIntent = new Intent(Intent.ACTION_SEND);
shareIntent.setType("application/pdf");
File sharingFile = new File(displayedFile.getPath());
Uri outputPdfUri = FileProvider.getUriForFile(this, PdfViewActivity.this.getPackageName() + ".provider", displayedFile);
shareIntent.putExtra(Intent.EXTRA_STREAM, outputPdfUri);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
//Write Permission might not be necessary
shareIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivity(Intent.createChooser(shareIntent, "Share PDF using.."));
return true;
}
This share_item button pulls from my saved file in Internal Storage. They key was getting the manifest and xml file written correctly.
Make sure this goes within your application tags in your AndroidManifest.xml - As well as notice I am using Androidx, change that line accordingly. I also never figured out the android:authorities line, but I found the filled in answer was the most common on Github.
<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/file_paths" />
</provider>
Lastly file_paths.xml - create an xml package inside your red folder, and post this code. For some reason other code was what made my file sharing not work.
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="projection" path="." />
</paths>

Android: Cannot share image from SD card

I try to share a picture from my SD card.
Class MainActivity.java
Intent shareIntent = new Intent(Intent.ACTION_SEND);
File baseDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM);
String fileName = "/cats.jpg";
File file = new File(baseDir + fileName);
Uri uri = Uri.fromFile(file);
shareIntent.setType("image/*");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(shareIntent.createChooser(shareIntent, "Send Picture"));
I add to my Manifest.xml:
uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
The image "cats" is in
MySmartphone\Card\DCIM\cats.jpg
When I start my App, I can choose an application to share my picture. But when I open one, it cannot send or open the image.I got often a toast "not supported" or "error to share picture". I think my uri or file is wrong, but I cannot find my mistake. I have no problem to send text.
My uri:
file:///data/user/0/com.example.jana.showpicture/files/cats.jpg
My file: /storage/emulated/0/cats.jpg
Probably you are building for Android API 24 and above. Since API 24 a new kind of security was added. See:
https://developer.android.com/about/versions/nougat/android-7.0-changes.html#perm
You now need to do a bit more, add this in your AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.jana.showpicture.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths" />
</provider>
/res/xml/provider_paths.xml:
<paths>
<external-path
name="external_files"
path="." />
</paths>
And Java:
Uri uri = FileProvider.getUriForFile(activity,"com.example.jana.showpicture.provider",
file);
shareIntent .setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY |
Intent.FLAG_GRANT_READ_URI_PERMISSION);

New Image File From URI Does Not Exist

So I'm using the Android Crop library (https://github.com/jdamcd/android-crop) to allow a user to take a picture and then crop it.
I need to create two files: one that contains the original image from the camera and one that contains the cropped image. I do this by defining two Files and two URI's that I then pass into the Android Crop library:
// Camera file.
Calendar calendar = Calendar.getInstance();
cameraCaptureFile = new File(getExternalCacheDir(), "camera-capture-" + calendar.getTime().getTime() + ".tmp");
cameraCaptureUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", cameraCaptureFile);
grantUriPermission(getPackageName(), cameraCaptureUri, FLAG_GRANT_WRITE_URI_PERMISSION & FLAG_GRANT_READ_URI_PERMISSION);
// Cropped file.
croppedFile = new File(getExternalCacheDir(), "cropped.png");
croppedFileUri = FileProvider.getUriForFile(this, getPackageName() + ".provider", croppedFile);
grantUriPermission(getPackageName(), croppedFileUri, FLAG_GRANT_WRITE_URI_PERMISSION & FLAG_GRANT_READ_URI_PERMISSION);
// Start cropping library.
Crop.of(cameraCaptureUri, croppedFileUri)
// Cropping complete lets get our cropped file.
File croppedPng = new File(croppedFileUri.getPath());
The problem is that croppedPng.exists() always returns false; however, when I go into the device storage browser and navigation to Android/data/com.mycompany/cache both the original and cropped files are there as expected.
I'm not quite sure what to make of this since my app was able to create the two files but then it cannot read them? Does not make sense.
Just for completion here are my other configurations related to this problem:
provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="external_files" path="." />
</paths>
AndroidManifest.xml
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.mycompany.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>

Upload excel file to Dropbox or Google Drive?

I'm currently developing an application which creates an excel file(with apache poi) from the sqlite database in android. Everything is working well, except that I can't send the file to another app.
I implemented an fileprovider so I other apps can have permission to my file:
AndroidManifest.xml:
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.example.ria.masterdetailnoten"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths"></meta-data>
</provider>
file_paths.xml:
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<files-path name="backup" path="backup/"/>
</paths>
ExcelFile.java:
Uri uriFile = FileProvider.getUriForFile(ct, "com.example.ria.masterdetailnoten", backupFile);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setDataAndType(uriFile, "application/vnd.ms-excel");
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.createChooser(intent, "Choose");
ct.startActivity(intent);
I know for sure that my file is being created and I can read it again with Apache POI. So the only things which doesn't work is sending the intent to another app.
As an example if I choose Google Drive in the intent chooser then following error appears:
"Upload failed: request contained no data."
If I open it with the Mailbox App following error appears:
"Mailbox could not read the selected file"
I hope you can help me guys, I appreciate your help!
Have you tried using: putExtra(Intent.EXTRA_STREAM, uriFile) instead of: setData(AndType)?
I've managed to work this out with intent.selector = Intent(Intent.ACTION_SEND).apply { data = Uri.parse("file:") }

Categories

Resources