I've asked a similar question before but I figured it out myself. But I now have a new problem, my device updated to android 8.0 and now email intent is not working. I don't want to downgrade my device if possible.
private void sendScreen() {
Date now = new Date();
android.text.format.DateFormat.format("yyyy-MM-dd_hh:mm:ss", now);
try {
// image naming and path to include sd card appending name you choose for file
String mPath = Environment.getExternalStorageDirectory().toString() + "/" + now + ".png";
// create bitmap screen capture
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream);
outputStream.flush();
outputStream.close();
File filelocation = new File(MediaStore.Images.Media.DATA + mPath);
Uri myUri = Uri.parse("file://" + filelocation);
final Intent emailIntent = new Intent(Intent.ACTION_SEND);
// set the type to 'email'
emailIntent .setType("vnd.android.cursor.dir/email");
String to[] = {"Enter your email address"};
emailIntent .putExtra(Intent.EXTRA_EMAIL, to);
// the attachment
emailIntent.putExtra(Intent.EXTRA_STREAM, myUri);
// the mail subject
emailIntent .putExtra(Intent.EXTRA_SUBJECT, "Journey : " + now );
startActivity(Intent.createChooser(emailIntent , "Select your preferred email app.."));
} catch (Throwable e) {
// Several error may come out with file handling or DOM
e.printStackTrace();
}
}
This is my code which worked perfectly on android 7.0. The code takes a screenshot, time stamps it, saves it to the local storage and then attached it to an email app of the users choice. Anyone have a solution? Thanks
This is my code which worked perfectly on android 7.0
It should have crashed with a FileUriExposedException.
now email intent is not working
You did not explain what "is not working" means. I am going to guess that you are crashing with a FileUriExposedException. A file Uri — whether via Uri.fromFile() or your Uri.parse("file://"+...) approach — is not usable on Android 7.0+ by default. Switch to using FileProvider and getUriForFile().
Related
So I am working on a project where if a manager registers a user he gets an email with a QR code (bitmap). The QR code is saved in cache. I want the QR code removed after the QR code is sent to the user, but a "cache" folder gets created (also shows up in gallery), and the image itself gets deleted but it remains there ( you cant see it, but its there as a grey square).
Any idea how to remove the created folder and the created bitmap compeletely?
My code:
BitmapSaver(Context mContext){
this.mContext=mContext;
this.cache = new DiskBasedCache(mContext.getCacheDir(), 1024 * 1024);
}
public static File saveImageToExternalStorage(Context context, Bitmap finalBitmap) {
destFolder =context.getCacheDir().getAbsolutePath();
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
// myDir = new File(root + "/saved_images");
// myDir.mkdirs();
long n = System.currentTimeMillis() / 1000L;
fname = "Image-" + n + ".jpg";
//file2 = new File(destFolder);
file = new File(destFolder+"/"+fname);
if (file.exists())
file.delete();
try {
Log.i("path",destFolder+"/"+fname);
FileOutputStream out = new FileOutputStream(destFolder+"/"+fname);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
MediaScannerConnection.scanFile(context, new String[]{file.toString()}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
Log.i("ExternalStorage", "Scanned " + path + ":");
Log.i("ExternalStorage", "-> uri=" + uri);
url = Uri.parse(path);
Log.i("External",url.toString());
}
});
return file;
}
In Activity after email is sent:
BitmapSaver bms = new BitmapSaver(RegisterActivity.this);
bms.saveImageToExternalStorage(RegisterActivity.this, bitmap);
bms.file.delete();
First of all you need to know what MediaScannerConnection.scanFile does. It will update the file information to the current device, so other applications like gallery, file explorer, etc, can show the correct file information and content.
From your code, when you are saving the temporary file, you are also scanning it, because your app has changed the corresponding file, which is creating the file to be exact. So the file will be available to the other applications right away. But, since the file location is in your application cache directory, it will not accessible by other applications. Usually you must restart your device to update the file information if you don't call MediaScanner.scanFile. If you are creating a temporary file, I think you don't need to call MediaScanner.scanFile, since you will delete it right away.
Then after delete, you also need to re-scan the file again, so other applications will know that the file has been deleted.
Also, despite of using MediaScannerConnection.scanFile directly, if you are supporting android version < KitKat, you should broadcast with intent action Intent.ACTION_MEDIA_MOUNTED instead. And I also recommend that you are broadcasting the data directly, because from my experience MediaScannerConnection.scanFile failed from one of my test devices.
Intent mediaScanIntent;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
mediaScanIntent.setData(Uri.fromFile(new File(imagePath)));
} else {
Uri fileUri = Uri.parse("file://" + imagePath);
mediaScanIntent = new Intent(Intent.ACTION_MEDIA_MOUNTED, fileUri);
}
context.sendBroadcast(mediaScanIntent);
This question already has answers here:
Share audio file (.mp3) via Facebook, email, and SMS/MMS
(7 answers)
Closed 6 years ago.
I have developed an "app" which is a quite popular person from my country's soundboard. It's very simple, it has 6 main buttons which play a different sound and then for each sound there are others 2 buttons, one for sharing the sound through social networks and another for setting the sound as ringtone, alarm or notification. At first, everything was working fine but one day, suddenly, it stopped working the function of sharing (the others functions are still working).
The message that appears is "The format is incompatible" for every single social network I tried to share (or something like that, it's in Spanish). You can download the app follow this link download the app here
The last release code for sharing is the following:
private void shareItAYQueNoEntren() {
Intent sharingIntent = new Intent(android.content.Intent.ACTION_SEND);
sharingIntent.setType("audio/mpeg3");
Uri path = Uri.parse("android.resource://fzmobile.elgordodecentral/raw/" + R.raw.yquenoentren);
sharingIntent.putExtra(Intent.EXTRA_STREAM, path);
startActivity(Intent.createChooser(sharingIntent, "Share by..."));
}
And the extension of the audio file in the raw folder is .mp3 .
How can I solve this trouble?
Try this:
String sharePath = Environment.getExternalStorageDirectory().getPath()
+ "your audio file path here";
Uri uri = Uri.parse(sharePath);
Intent share = new Intent(Intent.ACTION_SEND);
share.setType("audio/*");
share.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(share, "Share Sound File"));
Also do not forget to add permission WRITE_EXTERNAL_STORAGE otherwise you'll get an error while running your application.
Copy the audio file from the resource to external storage and then share it:
InputStream inputStream;
FileOutputStream fileOutputStream;
try {
inputStream = getResources().openRawResource(R.raw.sound);
fileOutputStream = new FileOutputStream(
new File(Environment.getExternalStorageDirectory(), "sound.mp3"));
byte[] buffer = new byte[1024];
int length;
while ((length = inputStream.read(buffer)) > 0) {
fileOutputStream.write(buffer, 0, length);
}
inputStream.close();
fileOutputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
then
Intent intent = new Intent(Intent.ACTION_SEND);
intent.putExtra(Intent.EXTRA_STREAM,
Uri.parse("file://" + Environment.getExternalStorageDirectory() + "/sound.mp3" ));
intent.setType("audio/*");
startActivity(Intent.createChooser(intent, "Share sound"));
Add WRITE_EXTERNAL_STORAGE permission to AndroidManifest.xml file:
I have a Relative layout and Textview on it. Then I convert that relative layout to bitmap image and save in directory.
The problem is when I am sharing the image, in most of app, I found correct image but in case of whatsapp when I am sharing through whatsapp the preview of sharing image is showing me old one until I close the app. Why it's not getting update and when I share the image on whatsapp, preview is old one and the image goes right one. This works fine in FB, Gmail etc...
This is the below code for converting and saving converted bitmap image in file system (directory)
This is for creating Direcory:
File dir = null;
String directorySubPath = "Android/data/com.domainname.appname/sharedResource/";
String imageNameForSave = "/qqq.png";
if (!Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState()))
{
Toast.makeText(this, "Your device doesn't have external storage.", Toast.LENGTH_SHORT).show();
return;
}
else
{
Log.d("SD", "YES", null);
dir = new File(Environment.getExternalStorageDirectory()+File.separator+directorySubPath);
if (!dir.exists()){
dir.mkdirs();
}
else {
Log.d("Q-Design:", "Already created", null);
}
}
This is for code convert layout to bitmap image & save.
rLayout.setDrawingCacheEnabled(true);
Bitmap bmp = Bitmap.createBitmap(rLayout.getDrawingCache());
FileOutputStream out = new FileOutputStream(dir+imageNameForSave);
bmp.compress(Bitmap.CompressFormat.JPEG, 100, out);
out.flush();
out.close();
rLayout.setDrawingCacheEnabled(false);
This is for SHARING that image via Intent:
Uri uri = Uri.parse("file:///" + dir + imageNameForSave);
Intent shareIntent = new Intent(android.content.Intent.ACTION_SEND);
shareIntent.setType("image/jpg");
shareIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "Test Mail");
shareIntent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
shareIntent.putExtra(android.content.Intent.EXTRA_TEXT, "Data Shared with you...");
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
startActivity(Intent.createChooser(shareIntent, "Share via:"));
Use a dynamic name in String imageNameForSave
Ex. String imageNameForSave = "/qqq" + mydate + ext;
Developing Android email plugin for Unity. I have a screenshot in the files/ folder of the app, I want to attach to mail. As it turned out, I cannot attach from there directly. I implemented a FileProvider, but it turned out that it exist only above 4.0.
So I implemented the suggested workaround, to save it to external storage, then attach from there. Saving seems work, even reading seems work, but still, Gmail says "Can't attach empty file". Also When launching email intent, I have an error message, like:
E/HwEmailTag( 7327): AttachmentUtilities->inferMimeTypeForUri->Unable to determine MIME type for uri=/storage/emulated/0/com.eppz.plugins_screenshot.jpg
I tried application/image, image/jpg as intent.setType(), still the same, while Gmail says the file is empty.
Is this something with emulated external storage /storage/emulated/0/? The device has no SD card, but I've read that getExternalStorage() returns a shared / public place for files in such cases either.
It should work. Should I remove dots from filename? Hope not. Here's the corresponding code:
String saveImageAtPathToExternalStorage(String imagePath)
{
Log.i(TAG, "saveImageAtPathToExternalStorage(...)");
// Create bitmap.
File imageFile = new File(imagePath);
Bitmap bitmap = BitmapFactory.decodeFile(imageFile.getAbsolutePath(), new BitmapFactory.Options());
// Output.
String outputFileName = _unityPlayerActivity.getPackageName()+"_screenshot.jpg";
String externalStorageDirectory = Environment.getExternalStorageDirectory().toString();
File outputImageFile = new File(externalStorageDirectory, outputFileName);
String outputImagePath = outputImageFile.getAbsolutePath();
if (outputImageFile.exists()) outputImageFile.delete(); // Delete if existed
try
{
// Write JPG.
FileOutputStream outputStream = new FileOutputStream(outputImageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.flush();
outputStream.close();
Log.i(TAG, "Image written to `"+outputImagePath+"`");
}
catch (Exception e)
{ e.printStackTrace(); }
// Return with output path.
return outputImagePath;
}
public void openMailComposer(String to, String subject, String body, int isHTML, String attachmentImagePath)
{
Log.i(TAG, "openMailComposer(...)");
// Attachment image.
File attachmentImageFile = new File(attachmentImagePath);
if (attachmentImageFile.exists() == false)
{
Log.i(TAG, IMAGE_NOT_FOUND);
SendUnityMessage(OPEN_MAIL_COMPOSER_CALLBACK_METHOD_NAME, IMAGE_NOT_FOUND);
return;
}
// Save to external first.
String externalImagePath = saveImageAtPathToExternalStorage(attachmentImagePath);
final Uri externalImageUri = Uri.parse(externalImagePath);
Log.i(TAG, "externalImageUri `"+externalImageUri+"`");
// Intent.
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/jpeg");
intent.putExtra(Intent.EXTRA_EMAIL, to);
intent.putExtra(Intent.EXTRA_SUBJECT, subject);
intent.putExtra(Intent.EXTRA_TEXT, body);
if (isHTML == 1) intent.putExtra(Intent.EXTRA_HTML_TEXT, body);
// Attach.
intent.putExtra(Intent.EXTRA_STREAM, externalImageUri);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
startActivityForResult(Intent.createChooser(intent, "Send email"), OPEN_MAIL_COMPOSER_REQUEST_CODE);
}
I'm relatively new to Android development, and really want to believe, but having all this hassle compared to having a single line for this in iOS is quiet distressing.
I'm running this on a Huawei MediaPad (TT1 7.0), Android 4.4.2, and I want it to run about Android 2.3+ basically (why I refused using FileProvider earlier).
I'm working on an Android application that should allow the users to share their content via Gmail. I'm using android version 2.2(Froyo).
The problem is that I can't find any working solution for this, I tried almost everything ,but with no luck.
this is the code I'm using:
Intent sharingIntent = new Intent(Intent.ACTION_SEND);;
sharingIntent.setType("application/zip");
sharingIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,
getString(R.string.share_subject));
sharingIntent.putExtra(android.content.Intent.EXTRA_TEXT, getString(R.string.share_body));
String zipFile = FileProvider.URI_AUTHORITY + File.separator + mItemSelected.getLibraryName() + File.separator + mItemSelected.getZipFileName();
sharingIntent.putExtra(Intent.EXTRA_STREAM, android.net.Uri.parse(zipFile));
startActivity(Intent.createChooser(sharingIntent, (getString(R.string.share_chooser))));
}
The problem in this case is that the Gmail app, for no obvious reason, is replacing the mime type of the file, and show the file as text/html, and then my application is not shown in the application list that can deal with this kind of file. Another restriction is that I don't want to use text/html in my intent filter, because I want it to be focused as much as possible, and if it were possible I would define my own mime type...
I did a little research and found this question, but with no answers...
More mime types I tried:
application/x-compressed, application/x-zip-compressed
multipart/x-zip and application/octet-stream
Is there any solution for this problem ??
Thanks.
after a lot of trouble, I discovered that Gmail, launched via Intent, does not like attachments whose prefix is .zip.
So, I succeeded in sending the attachments after renaming it ".vip".
Here is a piece of code (outFile is a zipped file renamed as ".vip"):
enter
private void sendMail(File outFile) {
Uri uriToZip = Uri.fromFile(outFile);
String sendText = "Dear friend,\n\n...";
Intent sendIntent = new Intent(Intent.ACTION_SEND);
sendIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[] { "checcodotti#gmail.com" });
sendIntent.putExtra(android.content.Intent.EXTRA_TEXT, sendText);
sendIntent.putExtra(android.content.Intent.EXTRA_SUBJECT,"Log of the test " + expFilename);
// sendIntent.setType("image/jpeg");
// sendIntent.setType("message/rfc822");
sendIntent.setType("*/*");
sendIntent.putExtra(android.content.Intent.EXTRA_STREAM, uriToZip);
startActivity(Intent.createChooser(sendIntent, "Send Attachment !:"));
}
Please let me know if it helps.
Regards
FD
I improve my previous answer for the part concerning "zipping". Now the are no problems with .zip attachments sent via GMail or whatever. Try this:
{
int lung;
FileInputStream in;
FileOutputStream out;
byte[] buffer = new byte[DIM_BUFFER];
// compress the file to send
String inPath = ctx.getApplicationContext().getFilesDir().getAbsolutePath();
outFile = new File(outPath,TestEdit.ZIPNAME);
// outFile = new File(outPath,filename + ".vip");
in = new FileInputStream(inFile);
ZipEntry entry = new ZipEntry(filename + ".csv");
try{
out = new FileOutputStream(outFile);
// GZIPOutputStream zos;
ZipOutputStream zos;
zos = new ZipOutputStream(new BufferedOutputStream(out) );
zos.putNextEntry(entry);
try {
while ((lung=in.read(buffer)) > 0) {
Log.v(TAG, "Lunghezza di in=" + lung + ". Lungh di buffer=" + buffer.length );
if (buffer.length == lung) {
zos.write(buffer);
} else {
// Gestione del caso in cui il buffer non sia pieno
for (int b = 0; b < lung; b++) {
zos.write(buffer[b]);
}
}
}
} finally {
zos.closeEntry();
zos.close();
in.close();
out.close();
}
}
}