Add attachment to gmail app via intent in Android - java

I have tried adding an attachment (csv file) to the mail intent. When the i start the intent and choose Gmail as the app, it says "Permission denied for the attachment". How do i solve this?
This is the code that i'm using
try {
SharedPreferences.Editor editor = sharedPreferences.edit();
editor.putString("address", input.getText().toString());
editor.apply();
String gmail=sharedPreferences.getString("address","");
Uri dat = Uri.fromFile(path);
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.setType("text/html");
sendIntent.putExtra(Intent.EXTRA_EMAIL, gmail);
sendIntent.putExtra(Intent.EXTRA_SUBJECT, "Stuff");
sendIntent.putExtra(Intent.EXTRA_STREAM, dat);
startActivity(Intent.createChooser(sendIntent, "Send email..."));
}catch (Exception e){
System.out.println(e.toString());
}

Your csv file is in private internal storage of your app. No other apps have access. Only your app. So the used email app has no access too. Put the file on another place. Or use a FileProvider.

Related

Android send email with attachments using only email apps

The official docs show how you can send an email with an attachment:
public void composeEmail(String[] addresses, String subject, Uri attachment) {
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_EMAIL, addresses);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_STREAM, attachment);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
It then says:
If you want to ensure that your intent is handled only by an email app (and not other text messaging or social apps), then use the ACTION_SENDTO action and include the "mailto:" data scheme.
Like so:
public void composeEmail(String[] addresses, String subject) {
Intent intent = new Intent(Intent.ACTION_SENDTO);
intent.setData(Uri.parse("mailto:")); // only email apps should handle this
intent.putExtra(Intent.EXTRA_EMAIL, addresses);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
if (intent.resolveActivity(getPackageManager()) != null) {
startActivity(intent);
}
}
But actually, I want a combination of the above... i.e. send an email with an attachment and using only an email app.
But when using intent.setData(Uri.parse("mailto:")) in combination with Intent.ACTION_SEND or Intent.ACTION_SEND_MULTIPLE, nothing happens... no email app (or app chooser) opens at all.
So how do I send an email with attachment (or multiple attachments) whilst also restricting the app to email apps?
That mailto: URI string appears invalid without recipients; try something alike this instead:
intent.setData(Uri.parse("mailto:" + String.join(",", addresses)));
See RFC 6068: The 'mailto' URI Scheme.
Remove if (intent.resolveActivity(getPackageManager()) != null) check and it will open the intent. Usually the OS returns null whether the email handling apps exist or not.

Share image in Facebook programmatically from Android app via Intent

I have this code working well on Android 4.0.4.
// Create the new Intent using the 'Send' action.
Intent share = new Intent(Intent.ACTION_SEND);
// Set the MIME type
share.setType(type);
// Create the URI from the media
java.io.File media = new java.io.File(mediaPath);
Uri uri = Uri.fromFile(media);
// Add the URI and the caption to the Intent.
share.putExtra(Intent.EXTRA_STREAM, uri);
share.putExtra(Intent.EXTRA_TEXT, caption);
// Broadcast the Intent.
mActivity.startActivity(Intent.createChooser(share, "Share to"));
But on Android 4.4.2 it crashes the Facebook app. Facebook app opens, the image is not shown and the FB app is dead.
In log dump I've noticed this message:
E/JHEAD ( 5850): can't open '/data/data/cz.volten.brili.android.free/files/product_preview_shared.jpg'
V/ContextImpl( 5850): ----- packageName = com.facebook.katana is NOT LOCKED -----
Could the reason be some security restrictions, e.g. The FB app does not have rights to access the image in the application folder even though it is invoked from an intent?
If so, what would be a proper location for an image shared between the apps?
Shall I use something like this: how to share image to facebook via intent
Could the reason be some security restrictions, e.g. The FB app does not have rights to access the image in the application folder even though it is invoked from an intent?
Correct. That image is on internal storage for your app, which is private to your app.
If so, what would be a proper location for an image shared between the apps?
You can stick with internal storage, though you will need to use a FileProvider, perhaps with my LegacyCompatCursorWrapper, to serve the file. This sample app demonstrates this, albeit with a PDF rather than an image.
Or, put the file on external storage.
Shall I use something like this: how to share image to facebook via intent
You could, though that would seem to be overkill, compared to using FileProvider.
This is what I usually use
private void initShareIntent(String type) {
boolean found = false;
Intent share = new Intent(android.content.Intent.ACTION_SEND);
share.setType("image/jpeg");
// gets the list of intents that can be loaded.
List<ResolveInfo> resInfo = getPackageManager().queryIntentActivities(share, 0);
if (!resInfo.isEmpty()) {
for (ResolveInfo info : resInfo) {
if (info.activityInfo.packageName.toLowerCase().contains(type) ||
info.activityInfo.name.toLowerCase().contains(type)) {
share.putExtra(Intent.EXTRA_TEXT, "Elevator Express");
share.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(new File(imagePath))); // Optional, just if you wanna share an image.
share.setPackage(info.activityInfo.packageName);
found = true;
break;
}
}
if (!found) {
Toast.makeText(getApplicationContext(), "Facebook does not exist", Toast.LENGTH_SHORT).show();
return;
}
startActivity(Intent.createChooser(share, "Select"));
}
}
and call it like this :
iniShareIntent("face");
This code works for me.....here "updateImage" is my image location.
if (isFacebookExist()) {
if (hashClick.isChecked()) {
SharePhoto sharePhoto = new SharePhoto.Builder()
.setBitmap(updateImage)
.build();
if (ShareDialog.canShow(SharePhotoContent.class)) {
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(sharePhoto)
.setShareHashtag(new ShareHashtag.Builder()
.setHashtag("#HashTag")
.build())
.build();
shareDialog.show(content);
}
} else {
SharePhoto sharePhoto = new SharePhoto.Builder()
.setBitmap(updateImage)
.build();
if (ShareDialog.canShow(SharePhotoContent.class)) {
SharePhotoContent content = new SharePhotoContent.Builder()
.addPhoto(sharePhoto)
.build();
shareDialog.show(content);
}
}
} else {
showToast(" Facebook is not install.");
}
private boolean isFacebookExist() {
PackageManager pm = getPackageManager();
try {
PackageInfo info = pm.getPackageInfo("com.facebook.katana", PackageManager.GET_META_DATA);
} catch (PackageManager.NameNotFoundException e) {
return false;
}
return true;
}

Android Studio, Genymotion - sending email with txt file attachment: display in gmail, but doesn't send

Java, Android Studio, Genymotion.
Dear colleagues,
i'm sending email (Intent) with txt attach from android application. Txt file was created by application earlier.
In genymotion in gmail client this attachment (file around 1 Kb) is displaying, but real mail is coming without attachment.
Code snippets:
// file creating
...
final String FILENAME = "file";
...
try {
// отрываем поток для записи
BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(openFileOutput(FILENAME, MODE_PRIVATE)));
// writing any data
bw.write ("\n");
...
Log.d(LOG_TAG, "file is created");
bw.close();
}
// sending email with intent
public void sendEmailwithMailClient (){
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
// sending email
emailIntent.setType("plain/text");
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, new String[]{"example#rambler.ru"});
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, getString(R.string.app_name));
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Hello!");
File file = new File(getFilesDir(), FILENAME);
// if (!file.exists() || !file.canRead()) {
// return;}
Uri uri = Uri.fromFile(file);
emailIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(emailIntent, "Pick an Email provider"));
}
Do i correctly define Uri for attachment via getFilesDir() and FILENAME?
Why email is loosing attachment during sending? It's issue of Genymotion or in reality i'm not attaching anything to mail and attach displaying in Genymotion is just a fake?
Thank you in advance!
You cannot attach a file from the your apps private storage.
You need to save it to external storage and then attach.
File file = new File(getFilesDir(), FILENAME);
is creating your file in /data/data/package_name/files directory.
Which is not accessible form the other apps.
If you still want to share the file from the apps private storage you need to create your ContentProvider.

not entering the condition if(intent.resolve(getPackageManager()){} neither else{}

Hey I want my app to locate someone on a map so I made an intent but it's not working and I've no error so I'm a bit lost. I think I've no app that can perform a map location on my emulator but even then I should have that said in my logs. Here is the code:
private void openLocationInMap(){
Log.d("map","in fct");
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
final String BASE_URL ="geo:0,0?q=";
Log.d("map","1");
String locationData = sharedPreferences.getString(getString(R.string.pref_location_key),
getString(R.string.pref_location_default));
Log.d("map","2");
Uri uriGeolocalisation = Uri.parse(BASE_URL).buildUpon()
.appendQueryParameter("q", locationData).build();
Log.d("map","3");
Intent intent = new Intent (Intent.ACTION_VIEW);
intent.setData(uriGeolocalisation);
Log.d("map","4");
if(intent.resolveActivity(getPackageManager()) != null) {
Log.d("map", "in if");
startActivity(intent);
}else{
Log.d("map", "couldn't open intent");
}
Log.d("map","5");
}
And in my log debug I get :
in fct, 1,2,3,4.
Edit: if that can help it works on my phone but still not working on the emulator. I'm guessing it's because I don't have google map on my emulator but still I should see something in the logs which I don't.

Android ActivityNotFoundException failing to catch on Intent in OS 4.1.2 (works on 4.0.3)?

Thanks for taking a look. I am a very old programmer but absolute newbie to Android/Java. Although I haven't found a way to make code colorful and pretty here yet ;).
I am starting an activity to open a file with a bogus/fake extension (mime type) so I can force this ActivityNotFoundException exception (to test).
Somehow, this exception never happens on my Samsung Galaxy S3 (OS 4.1.2). Adobe Reader opens up and errors that the file is not a PDF (it's not). However on an older ASUS Transformer tablet running 4.0.3 the exception is caught properly.
The code in question is like so:
// this file exists (check omitted)..
File docFile = new File("/path/to/file.bogusextension");
// intent
Intent intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
// getting doc Uri
Uri fileUri = Uri.fromFile(docFile);
// getting doc mimeType
MimeTypeMap mime = MimeTypeMap.getSingleton();
String extension = MimeTypeMap.getFileExtensionFromUrl(fileUrl);
String mimeType = mime.getMimeTypeFromExtension(extension);
intent.setDataAndType(fileUri, mimeType);
// this is for an adobe native extension, just getting FREContext
// in the class below and mapping functions
DocLauncherExtensionContext extensionContext = (DocLauncherExtensionContext) context;
Activity activity = extensionContext.getActivity();
try
{
activity.startActivity(intent);
}
catch (ActivityNotFoundException e)
{
Toast.makeText(context.getActivity(), "This never happens!", Toast.LENGTH_LONG).show();
}
Is there anything blatent wrong with this code that would allow a file with any extension what-so-ever to be constantly thrown at Adobe Reader? I have cleared my defaults (Settings->Application Manager->Reset). Everything I startActivity is just hurled at Adobe Reader.
Any thoughts appreciated! Thank you!
Intent intent = new Intent();
needs to become:
Intent intent = new Intent(Intent.ACTION_VIEW);
You were putting data and an ActionCode into the intent, however you never told it what it was an intent for.

Categories

Resources