por - no puedo adjuntar archivos en gmail android
Android: no se puede adjuntar un archivo en el correo electrónico (7)
De forma predeterminada, los archivos guardados en el almacenamiento interno son privados para su aplicación y otras aplicaciones no pueden acceder a ellos (ni tampoco el usuario).
Puedo ver el archivo "/ data / data / package_name / files / in file explore in DDMS, pero cuando adjunté el URI del archivo anterior usando imageUri en el correo electrónico, entonces vi que el archivo adjunto es de 0kb. He usado el las API de correo electrónico predeterminadas de Android.
¿Puede alguien sugerirme cómo adjuntar un archivo en un correo electrónico que es privado para la aplicación?
aunque tengo éxito en guardar el archivo en la tarjeta SD y adjuntar el archivo desde la tarjeta SD, funciona bien.
Pero si la tarjeta SD no está disponible y guarda el archivo en el almacenamiento interno, ¿cómo puedo adjuntarlos en el correo electrónico?
String FILENAME = "hello_file.txt";
String string = "hello world!";FileOutputStream fos = openFileOutput(FILENAME, Context.MODE_PRIVATE);
fos.write(string.getBytes());
fos.close();
File imageFile = getFileStreamPath(FILENAME );
Uri imageUri = Uri.fromFile(imageFile);
final Intent emailIntent = new Intent(android.content.Intent.ACTION_SEND);
emailIntent.setType("*/*");
emailIntent.putExtra(android.content.Intent.EXTRA_STREAM,imageUri);
this.startActivityForResult(Intent.createChooser(emailIntent, "Send mail..."),SUB_ACTIVITY);
Intente utilizar Context.MODE_WORLD_READABLE en lugar de Context.MODE_PRIVATE al guardar el archivo. Luego, otras aplicaciones tendrán acceso al archivo.
Cuando intenta adjuntar un archivo desde el almacenamiento interno, GMail escribe un error en el registro:
ERROR/Gmail(...): file:// attachment paths must point to file:///mnt/sdcard.
La aplicación de correo electrónico le mostrará el archivo adjunto, incluso si no existiera físicamente.
En cuanto a un almacenamiento externo, la documentación dice que:
Todos los dispositivos compatibles con Android admiten un "almacenamiento externo" compartido que puede usar para guardar archivos. Puede ser un medio de almacenamiento extraíble (como una tarjeta SD) o un almacenamiento interno (no extraíble).
Eso significa que no tiene que preocuparse de que el dispositivo no tenga un almacenamiento externo. Aún así, el almacenamiento externo puede no estar disponible a veces. Consulte http://developer.android.com/guide/topics/data/data-storage.html#filesExternal
También he experimentado este problema usando archivos internos y aunque he usado openFileInput con MODE_WORLD_READABLE en /data/data//files/testFileName.txt y usé URI.parse con el extra "/" (ver a continuación), la prueba recibida se envió por correo electrónico todavía carece del archivo adjunto deseado. Lo siento, pero no hay respuesta, excepto tratar de usar archivos externos en la tarjeta SD, ¡que es mi próximo experimento!
Código:
File tmpFile = new File(context.getFilesDir(), mfileName);
Log.d(TAG, tmpFile.toString());
// This shows: /data/data/org.eddiem.adeveloper.flatfiletest/files/testFile.csv
//File tmpFile2 = new File(context.getFileStreamPath(mfileName), mfileName);
//Log.v(TAG, tmpFile2.toString());
// This also shows: /data/data/org.eddiem.adeveloper.flatfiletest/files/testFile.csv
//Uri uri = Uri.fromFile(new File(context.getFileStreamPath(mfileName), mfileName));
Uri uri = Uri.parse("file://" + tmpFile.toString());
//Uri uri = Uri.fromFile(new File(Environment.getExternalStorageDirectory(),
// mfileName));
Log.d(TAG, "Uri-path is: " + uri.getPath()); // or .toString()
Intent i = new Intent(android.content.Intent.ACTION_SEND);
i.setType("text/plain");
i.putExtra(Intent.EXTRA_EMAIL, new String[]{"[email protected]"});
i.putExtra(Intent.EXTRA_SUBJECT, "Test Email - with Attachment");
i.putExtra(Intent.EXTRA_TEXT, "This is a test Email with an Attachment.");
i.putExtra(Intent.EXTRA_STREAM, uri);
//startActivity(Intent.createChooser(i, "Select application"));
startActivity(Intent.createChooser(i, "Send mail"));
Este Código puede ayudarlo a tener una idea acerca del archivo adjunto:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
buttonSend = (Button) findViewById(R.id.buttonSend);
textTo = (EditText) findViewById(R.id.editTextTo);
textSubject = (EditText) findViewById(R.id.editTextSubject);
textMessage = (EditText) findViewById(R.id.editTextMessage);
buttonSend.setOnClickListener( new OnClickListener() {
@Override
public void onClick(View v) {
String to = textTo.getText().toString();
String subject = textSubject.getText().toString();
String message = textMessage.getText().toString();
Intent i = new Intent(Intent.ACTION_SEND);
i.setType("plain/text");
File data = null;
try {
Date dateVal = new Date();
String filename = dateVal.toString();
data = File.createTempFile("Report", ".csv");
FileWriter out = (FileWriter) GenerateCsv.generateCsvFile(
data, "Name,Data1");
i.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(data));
i.putExtra(Intent.EXTRA_EMAIL, new String[] { to });
i.putExtra(Intent.EXTRA_SUBJECT, subject);
i.putExtra(Intent.EXTRA_TEXT, message);
startActivity(Intent.createChooser(i, "E-mail"));
} catch (IOException e) {
e.printStackTrace();
}
}
});
}
public class GenerateCsv
{
public static FileWriter generateCsvFile(File sFileName,String fileContent)
{
FileWriter writer = null;
try {
writer = new FileWriter(sFileName);
writer.append(fileContent);
writer.flush();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return writer;
}
}
El código anterior requiere que agregues el siguiente permiso a tu archivo de manifiesto:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
Android: Attaching files from internal cache to Gmail
package com.stephendnicholas.gmailattach;
import java.io.File;
import java.io.FileNotFoundException;
import android.content.ContentProvider;
import android.content.ContentValues;
import android.content.UriMatcher;
import android.database.Cursor;
import android.net.Uri;
import android.os.ParcelFileDescriptor;
import android.util.Log;
public class CachedFileProvider extends ContentProvider {
private static final String CLASS_NAME = "CachedFileProvider";
// The authority is the symbolic name for the provider class
public static final String AUTHORITY = "com.stephendnicholas.gmailattach.provider";
// UriMatcher used to match against incoming requests
private UriMatcher uriMatcher;
@Override
public boolean onCreate() {
uriMatcher = new UriMatcher(UriMatcher.NO_MATCH);
// Add a URI to the matcher which will match against the form
// ''content://com.stephendnicholas.gmailattach.provider/*''
// and return 1 in the case that the incoming Uri matches this pattern
uriMatcher.addURI(AUTHORITY, "*", 1);
return true;
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode)
throws FileNotFoundException {
String LOG_TAG = CLASS_NAME + " - openFile";
Log.v(LOG_TAG,
"Called with uri: ''" + uri + "''." + uri.getLastPathSegment());
// Check incoming Uri against the matcher
switch (uriMatcher.match(uri)) {
// If it returns 1 - then it matches the Uri defined in onCreate
case 1:
// The desired file name is specified by the last segment of the
// path
// E.g.
// ''content://com.stephendnicholas.gmailattach.provider/Test.txt''
// Take this and build the path to the file
String fileLocation = getContext().getCacheDir() + File.separator
+ uri.getLastPathSegment();
// Create & return a ParcelFileDescriptor pointing to the file
// Note: I don''t care what mode they ask for - they''re only getting
// read only
ParcelFileDescriptor pfd = ParcelFileDescriptor.open(new File(
fileLocation), ParcelFileDescriptor.MODE_READ_ONLY);
return pfd;
// Otherwise unrecognised Uri
default:
Log.v(LOG_TAG, "Unsupported uri: ''" + uri + "''.");
throw new FileNotFoundException("Unsupported uri: "
+ uri.toString());
}
}
// //////////////////////////////////////////////////////////////
// Not supported / used / required for this example
// //////////////////////////////////////////////////////////////
@Override
public int update(Uri uri, ContentValues contentvalues, String s,
String[] as) {
return 0;
}
@Override
public int delete(Uri uri, String s, String[] as) {
return 0;
}
@Override
public Uri insert(Uri uri, ContentValues contentvalues) {
return null;
}
@Override
public String getType(Uri uri) {
return null;
}
@Override
public Cursor query(Uri uri, String[] projection, String s, String[] as1,
String s1) {
return null;
}
}
<provider android:name="CachedFileProvider" android:authorities="com.stephendnicholas
public static void createCachedFile(Context context, String fileName,
String content) throws IOException {
File cacheFile = new File(context.getCacheDir() + File.separator
+ fileName);
cacheFile.createNewFile();
FileOutputStream fos = new FileOutputStream(cacheFile);
OutputStreamWriter osw = new OutputStreamWriter(fos, "UTF8");
PrintWriter pw = new PrintWriter(osw);
pw.println(content);
pw.flush();
pw.close();
}
public static Intent getSendEmailIntent(Context context, String email,
String subject, String body, String fileName) {
final Intent emailIntent = new Intent(
android.content.Intent.ACTION_SEND);
//Explicitly only use Gmail to send
emailIntent.setClassName("com.google.android.gm","com.google.android.gm.ComposeActivityGmail");
emailIntent.setType("plain/text");
//Add the recipients
emailIntent.putExtra(android.content.Intent.EXTRA_EMAIL,
new String[] { email });
emailIntent.putExtra(android.content.Intent.EXTRA_SUBJECT, subject);
emailIntent.putExtra(android.content.Intent.EXTRA_TEXT, body);
//Add the attachment by specifying a reference to our custom ContentProvider
//and the specific file of interest
emailIntent.putExtra(
Intent.EXTRA_STREAM,
Uri.parse("content://" + CachedFileProvider.AUTHORITY + "/"
+ fileName));
return emailIntent;
}
enter code here
Estaba enfrentando el mismo problema y el siguiente funcionó para mí.
Primero envíe Broadcast para notificar al dispositivo que el archivo se ha creado / montado.
Por ejemplo:
sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED,Uri.parse("file://"+storagePath)));
Luego use el código para enviar correo con archivo adjunto.
Intent email = new Intent(Intent.ACTION_SEND);
email.putExtra(Intent.EXTRA_EMAIL, "Receiver Email Address" );
email.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
email.putExtra(Intent.EXTRA_SUBJECT, "Subject");
email.putExtra(Intent.EXTRA_TEXT,"Email Text");
//Mime type of the attachment (or) u can use sendIntent.setType("*/*")
//email.setType("text/plain");
email.setType("application/YourMimeType");
//Full Path to the attachment
email.putExtra(Intent.EXTRA_STREAM, Uri.parse("file://"+storagePath));
try
{
startActivity(Intent.createChooser(email, "Send Message..."));
}
catch (android.content.ActivityNotFoundException ex)
{
}
Para compartir un archivo privado, debe usar ContentProvider para proporcionar acceso a su archivo por otras aplicaciones. Este es un gran ejemplo: Android: adjuntar archivos de caché interna a Gmail .
Además, aunque el tutorial menciona que debe declarar su proveedor en el archivo de manifiesto de Android, no especifica que deba estar en <application>
, así que asegúrese de que cuando declare que está dentro de <application> </application>
.