the app opens gmail and put all the data in but don't bring the attachment and I don't see issues.
Here is the code :
String filelocation = root.getAbsolutePath() + filename;
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setType("text/plain");
String message = "File to be shared is " + filename + ".";
intent.putExtra(Intent.EXTRA_SUBJECT, "Subject");
intent.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + filelocation));
intent.putExtra(Intent.EXTRA_TEXT, message);
intent.setData(Uri.parse("mailto:xyz#gmail.com"));
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
} catch (Exception e) {
System.out.println("is exception raises during sending mail" + e);
}
I also uploaded image .
Thanks in advance .
Try to access the file using Provider :
Add a provider in your manifest under </application>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="#string/authority" //<string name="authority">'<packagename>'.provider</string>
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_paths" />
</provider>
and create a Path xml under res/xml/file_path.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>
then try to access the file using provider
Uri uri=FileProvider.getUriForFile(
this,
this.getPackageName().toString() + ".provider",
image_FilePath
);
Intent i = Intent(Intent.ACTION_SEND);
i.putExtra(Intent.EXTRA_STREAM, uri);
i.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
this.startActivity(Intent.createChooser(i, "Share:"));
Hope its works ...
UPDATE
Everything is working now! I'm a little slow but thanks to the incredible patience of #blackapps I've gotten it to work. First here is how the file is created:
try {
File outputFile = new File(getFilesDir(), "myFile.txt");
FileWriter fileWriter = new FileWriter(outputFile, false);
//use fileWriter.write to write strings to the file
fileWriter.close();
sendEmail(outputFile);
} catch (ClassNotFoundException e) {
Log.e(TAG, e.getMessage());
} catch (IOException e) {
Log.e(TAG, e.getMessage());
}
And then here's the method to send the text file by email.
private void sendEmail(File outputFile) {
Intent emailSelectorIntent = new Intent(Intent.ACTION_SENDTO);
emailSelectorIntent.setData(Uri.parse("mailto:"));
Intent emailIntent = new Intent(Intent.ACTION_SEND);
emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[]{"goodweathercorp#gmail.com"});
emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Logcat");
Uri uri = FileProvider.getUriForFile(this, getPackageName() + ".fileProvider", outputFile);
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM, uri);
emailIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
emailIntent.setSelector(emailSelectorIntent);
if (emailIntent.resolveActivity(getPackageManager()) != null) {
startActivity(Intent.createChooser(emailIntent, "Choose email client"));
} else {
Toast.makeText(this, "No email apps detected", Toast.LENGTH_LONG).show();
}
}
Also you must add this to manifest:
</application>
....
<provider
android:enabled="true"
android:name="androidx.core.content.FileProvider"
android:authorities="com.braapproductions.braaaaap.fileProvider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/paths" />
</provider>
</application>
And finally in values>xml> create a file called paths.xml:
<paths>
<files-path name="files" path="/"/>
</paths>
I want to install app in my projects.
But my code don't work in api 24 or higher.
What is its solution?
My code is:
String timestamp = new SimpleDateFormat("yyyy.MM.dd.HH.mm.ss").format(new Date());
String dir = Environment.getExternalStorageDirectory() + "/" + context.getResources().getString(R.string.cache_path);
String appName = appModel.getAppUrl().substring(appModel.getAppUrl().lastIndexOf('/') + 1, appModel.getAppUrl().length());
appName = timestamp + "_" + appName;
private void appInstaller(String dir, String appName) {
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N) {
File file = new File(dir, appName);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
startActivity(intent);
} else {
Intent intent = new Intent(Intent.ACTION_INSTALL_PACKAGE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setDataAndType(Uri.fromFile(new File(Environment.getExternalStorageDirectory() + "/" + dir + "/" + appName)), "application/vnd.android.package-archive");
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
}
Manifest:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
This question is like my question. But does not work its solution for me!
Thanks about to help me!
I resolved this problem and this way is true for me:
First:
private static final String APP_DIR = Environment.getExternalStorageDirectory().getAbsolutePath() + "/MyAppFolderInStorage/";
private void install() {
File file = new File(APP_DIR + fileName);
if (file.exists()) {
Intent intent = new Intent(Intent.ACTION_VIEW);
String type = "application/vnd.android.package-archive";
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
Uri downloadedApk = FileProvider.getUriForFile(getContext(), "ir.greencode", file);
intent.setDataAndType(downloadedApk, type);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
intent.setDataAndType(Uri.fromFile(file), type);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
getContext().startActivity(intent);
} else {
Toast.makeText(getContext(), "ّFile not found!", Toast.LENGTH_SHORT).show();
}
}
Second: For android 7 and above you should define a provider in manifest like below!
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="ir.greencode"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/paths" />
</provider>
Third: Define path.xml in res/xml folder like below! I'm using this path for internal storage if you want to change it to something else there is a few way! You can go to this FileProvider
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
<external-path name="your_folder_name" path="MyAppFolderInStorage/"/>
</paths>
Forth: You should add this permission in manifest:
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
I have an Android Studio project with the option to share videos by whatsapp.
This is my code:
private void shareFile(File file){
String titulo = file.getName();
String path = file.getAbsolutePath();
Uri uri = Uri.parse(path);
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("video/*");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, title);
shareIntent.putExtra(android.content.Intent.EXTRA_TITLE, title);
shareIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(shareIntent);
}
But when I share it I receive the message from Whatsapp: this file format is not compatible.
I do not understand what happens, before it worked.
ANDROIDMANIFEST.XML
<provider
android:name="android.support.v4.content.FileProvider"
android:grantUriPermissions="true"
android:exported="false"
android:authorities="${applicationId}">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/file_provider_paths"/>
</provider>
FILE_PROVIDER_PATHS.XML in res/xml
<paths>
<cache-path name="cache" path="/" />
<files-path name=”files” path=”/” />
</paths>
USE YOUR FILEPROVIDER
// create new Intent
Intent intent = new Intent(Intent.ACTION_VIEW);
// set flag to give temporary permission to external app to use your FileProvider
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
// generate URI, I defined authority as the application ID in the Manifest, the last param is file I want to open
String uri = FileProvider.getUriForFile(this, BuildConfig.APPLICATION_ID, file);
// I am opening a PDF file so I give it a valid MIME type
intent.setDataAndType(uri, "video/*");
// validate that the device can open your File!
PackageManager pm = getActivity().getPackageManager();
if (intent.resolveActivity(pm) != null) {
startActivity(intent);
}
I have a list of files in my android app and I want to be able to get the selected items and send them via email or any other sharing app. Here is my code.
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_EMAIL, getListView().getCheckedItemIds());
sendIntent.setType("text/plain");
startActivity(sendIntent);
this is the code for sharing file in android
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
File fileWithinMyDir = new File(myFilePath);
if(fileWithinMyDir.exists()) {
intentShareFile.setType("application/pdf");
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+myFilePath));
intentShareFile.putExtra(Intent.EXTRA_SUBJECT,
"Sharing File...");
intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File...");
startActivity(Intent.createChooser(intentShareFile, "Share File"));
}
Below is another method to share PDF file if you have put file provider in manifest
Uri pdfUri;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
pdfUri = FileProvider.getUriForFile(PDFViewerActivity.this, fileprovider, pdfFile);
} else {
pdfUri = Uri.fromFile(pdfFile);
}
Intent share = new Intent();
share.setAction(Intent.ACTION_SEND);
share.setType("application/pdf");
share.putExtra(Intent.EXTRA_STREAM, pdfUri);
startActivity(Intent.createChooser(share, "Share file"));
sendIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(exportPath));
also you can make zip file of all file and attach zip file for send multiple file in android
For those who trying in Kotlin here is the way:
Start the intent like below:
fun startFileShareIntent(filePath: String) { // pass the file path where the actual file is located.
val shareIntent = Intent(Intent.ACTION_SEND).apply {
type = FILE_TYPE // "*/*" will accepts all types of files, if you want specific then change it on your need.
flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
putExtra(
Intent.EXTRA_SUBJECT,
"Sharing file from the AppName"
)
putExtra(
Intent.EXTRA_TEXT,
"Sharing file from the AppName with some description"
)
val fileURI = FileProvider.getUriForFile(
context!!, context!!.packageName + ".provider",
File(filePath)
)
putExtra(Intent.EXTRA_STREAM, fileURI)
}
startActivity(shareIntent)
}
In Manifest inside the application tag:
<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>
Under res-->xml--> provider_paths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<files-path name="files" path="." />
<external-path name="external_files" path="."/>
</paths>
This is work for every single file!
private void shareFile(File file) {
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
intentShareFile.setType(URLConnection.guessContentTypeFromName(file.getName()));
intentShareFile.putExtra(Intent.EXTRA_STREAM,
Uri.parse("file://"+file.getAbsolutePath()));
//if you need
//intentShareFile.putExtra(Intent.EXTRA_SUBJECT,"Sharing File Subject);
//intentShareFile.putExtra(Intent.EXTRA_TEXT, "Sharing File Description");
startActivity(Intent.createChooser(intentShareFile, "Share File"));
}
Thanks Tushar-Mate!
First you should define File Provider, see https://medium.com/#ali.dev/open-a-file-in-another-app-with-android-fileprovider-for-android-7-42c9abb198c1.
The code checks that a device contains applications which can receive the file, see How to check if an intent can be handled from some activity?.
fun sharePdf(file: File, context: Context) {
val uri = getUriFromFile(file, context)
if (uri != null) {
val intent = Intent().apply {
action = Intent.ACTION_SEND
type = "application/pdf" // For PDF files.
putExtra(Intent.EXTRA_STREAM, uri)
putExtra(Intent.EXTRA_SUBJECT, file.name)
putExtra(Intent.EXTRA_TEXT, file.name)
// Grant temporary read permission to the content URI.
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
}
// Validate that the device can open your File.
val activityInfo = intent.resolveActivityInfo(context.packageManager, intent.flags)
if (activityInfo?.exported == true) {
context.startActivity(Intent.createChooser(intent,
"Share PDF file")
}
}
}
fun getUriFromFile(file: File, context: Context): Uri? =
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
Uri.fromFile(file)
} else {
try {
FileProvider.getUriForFile(context, context.packageName + ".provider", file)
} catch (e: Exception) {
throw if (e.message?.contains("ProviderInfo.loadXmlMetaData") == true) {
Error("FileProvider is not set or doesn't have needed permissions")
} else {
e
}
}
}
Use ACTION_SEND_MULTIPLE for delivering multiple data to someone
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, arrayUri);
intent.setType("text/plain");
startActivity(intent);
The arrayUri is the Array List of Uri of files to Send.
Here is an example to share or save a text file:
private void shareFile(String filePath) {
File f = new File(filePath);
Intent intentShareFile = new Intent(Intent.ACTION_SEND);
File fileWithinMyDir = new File(filePath);
if (fileWithinMyDir.exists()) {
intentShareFile.setType("text/*");
intentShareFile.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://" + filePath));
intentShareFile.putExtra(Intent.EXTRA_SUBJECT, "MyApp File Share: " + f.getName());
intentShareFile.putExtra(Intent.EXTRA_TEXT, "MyApp File Share: " + f.getName());
this.startActivity(Intent.createChooser(intentShareFile, f.getName()));
}
}
File directory = new File(Environment.getExternalStorageDirectory() + File.separator + BuildConfig.APPLICATION_ID + File.separator + DIRECTORY_VIDEO);
String fileName = mediaModel.getContentPath().substring(mediaModel.getContentPath().lastIndexOf('/') + 1, mediaModel.getContentPath().length());
File fileWithinMyDir = new File(directory, fileName);
if (fileWithinMyDir.exists()) {
Uri fileUri = FileProvider.getUriForFile(this, getApplicationContext().getPackageName() + ".provider", fileWithinMyDir);
Intent intent = ShareCompat.IntentBuilder.from(this)
.setStream(fileUri) // uri from FileProvider
.setType("text/html")
.getIntent()
.setAction(Intent.ACTION_SEND) //Change if needed
.setDataAndType(fileUri, "video/*")
.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivity(intent);
val uriArrayList: ArrayList<Uri> = ArrayList()
GlobalScope.launch(Dispatchers.IO) {
runCatching {
itemsList!!.forEach {
uriArrayList.add(
FileProvider.getUriForFile(
mContext,
APPLICATION_ID + ".provider",
File(it.path)
)
)
}
}.onSuccess {
requireActivity().runOnUiThread {
if (uriArrayList.size > 0) {
val intent = Intent()
intent.action = Intent.ACTION_SEND_MULTIPLE
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriArrayList)
intent.flags = Intent.FLAG_GRANT_READ_URI_PERMISSION
intent.type = "image/*|application/pdf/*"
startActivity(Intent.createChooser(intent, resources.getString(R.string.share)))
}
}
}
.onFailure {
Log.e("SHARING_FAILED", it)
}
}
First of all you have to write provider code in app manifest file for sharing on android 7.0 and above
<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>
here provider_paths are:
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-path name="/storage/emulated/0" path="."/>
<root-path name="root" path="." />
<files-path name="files" path="."/>
</paths>
Read this article about Sending Content to Other Apps
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
sendIntent.setType("text/plain");
startActivity(Intent.createChooser(sendIntent, getResources().getText(R.string.send_to)));