Reputation: 539
I looked over similar questions and tried to write this simple code. This code takes an bitmap image of the view then allows the user to attach it to email. for some reason I get the message "can't attach an empty file" in the email application. I'm fairly new to this and I read a few examples and tried different things but non worked. I suspect that something might be wrong with my path.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.asamater.myapplication" >
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<ScrollView
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:id="@+id/scrollView"
android:layout_centerVertical="true"
android:layout_centerHorizontal="true" >
<LinearLayout
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/linearLayout">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText"
android:text="Q1" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton2" />
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText2"
android:text="Q2" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton3" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton4" />
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText3"
android:text="Q3" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton5" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton6" />
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText4"
android:text="Q3" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton7" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton8" />
</RadioGroup>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/editText5"
android:text="Q4" />
<RadioGroup
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp">
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton10" />
<RadioButton
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="New RadioButton"
android:id="@+id/radioButton9" />
</RadioGroup>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Email"
android:id="@+id/button"
android:layout_alignTop="@id/radioButton9"
android:onClick="email" />
</LinearLayout>
</ScrollView>
</RelativeLayout>
.
package com.example.asamater.myapplication;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.HorizontalScrollView;
import android.widget.ScrollView;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.BitSet;
import java.util.Random;
public class MainActivity extends AppCompatActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void email(View view){
ScrollView z = (ScrollView) findViewById(R.id.scrollView);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Bitmap bitmap = getBitmapFromView(z,totalHeight,totalWidth);
String path = saveImageToStorage(bitmap);
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "[email protected]");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "report");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, " ");
emailIntent.setType("image/jpeg");
File bitmapFile = new File(Environment.getExternalStorageDirectory()+
"/"+ path);
Uri myUri = Uri.fromFile(bitmapFile);
emailIntent.putExtra(Intent.EXTRA_STREAM, myUri);
startActivity(Intent.createChooser(emailIntent, "Send your email in:"));
}
private String saveImageToStorage(Bitmap bitmap) {
String root = Environment.getExternalStorageDirectory().toString();
File myDir = new File(root + "/req_images");
myDir.mkdirs();
String fname = "Image-Report.jpg";
File file = new File(myDir, fname);
Log.i("myActivity", "" + file);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
return root + "/req_images" + fname;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public Bitmap getBitmapFromView(View view, int totalHeight, int totalWidth) {
Bitmap returnedBitmap = Bitmap.createBitmap(totalWidth,totalHeight , Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
}
Upvotes: 1
Views: 2684
Reputation: 13932
Manifest needs:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.example.asamater.myapplication" >
<!-- Permissions need to be added too-->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
Replace your email method with this then delete the saveImageToStorage Method:
public void email(View view){
ScrollView z = (ScrollView) findViewById(R.id.scrollView);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Bitmap bitmap = getBitmapFromView(z,totalHeight,totalWidth);
// Create the file directory
File myDir = new File(Environment.getExternalStorageDirectory() + "/req_images");
myDir.mkdirs();
// For multiple files you want to create a timestamp so the name is unique
DateFormat format = new SimpleDateFormat("yyyy_MM_dd_H_mm_ss", Locale.getDefault());
Date curDate = new Date();
String displayDate = format.format(curDate);
String fname = displayDate+ "_Image-Report.jpg"; // now this is dynamic
// create the file in the directory
File file = new File(myDir, fname);
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "[email protected]");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "report");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, " ");
/*
* The important part where you create the file and save it
*/
emailIntent.setType("image/*"); // accept any image
try {
boolean fileCreated = file.createNewFile();
if (fileCreated) {
// write the bitmap to that file
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream);
outputStream.close();
}
} catch (IOException ex) {
Log.d("SAVE FAILED", "could not save file");
}
// then attach the file to the intent
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
startActivity(Intent.createChooser(emailIntent, "Send your email in:"));
}
Upvotes: 3
Reputation: 539
This work!
public void email(View view){
ScrollView z = (ScrollView) findViewById(R.id.scrollView);
int totalHeight = z.getChildAt(0).getHeight();
int totalWidth = z.getChildAt(0).getWidth();
Bitmap bitmap = getBitmapFromView(z,totalHeight,totalWidth);
File file = BitmapSaver.saveImageToExternalStorage(this, bitmap);
Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL, "[email protected]");
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, "report");
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, " ");
emailIntent.setType("image/*"); // accept any image
//attach the file to the intent
emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
startActivity(Intent.createChooser(emailIntent, "Send your email in:"));
}
The BitmapSaver class:
/**
* Created by ASamater on 01/09/2015.
*/
public class BitmapSaver {
public static File saveImageToExternalStorage(Context context, Bitmap finalBitmap) {
String root = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES).toString();
File myDir = new File(root + "/saved_images");
myDir.mkdirs();
long n = System.currentTimeMillis() / 1000L;
String fname = "Image-" + n + ".jpg";
File file = new File(myDir, fname);
if (file.exists())
file.delete();
try {
FileOutputStream out = new FileOutputStream(file);
finalBitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
out.flush();
out.close();
}
catch (Exception e) {
e.printStackTrace();
}
// Tell the media scanner about the new file so that it is
// immediately available to the user.
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);
}
});
return file;
}
}
Upvotes: 1