mirror of
https://github.com/M66B/FairEmail.git
synced 2024-12-26 09:47:13 +00:00
Accept send intents
This commit is contained in:
parent
510bc3be43
commit
e86a05b5da
4 changed files with 200 additions and 95 deletions
|
@ -52,9 +52,19 @@
|
|||
|
||||
<activity
|
||||
android:name=".ActivityCompose"
|
||||
android:exported="false"
|
||||
android:exported="true"
|
||||
android:launchMode="standard"
|
||||
android:parentActivityName=".ActivityView" />
|
||||
android:parentActivityName=".ActivityView">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.SEND" />
|
||||
<action android:name="android.intent.action.SENDTO" />
|
||||
<action android:name="android.intent.action.SEND_MULTIPLE" />
|
||||
|
||||
<data android:mimeType="*/*" />
|
||||
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<service android:name=".ServiceSynchronize" />
|
||||
|
||||
|
|
|
@ -19,9 +19,14 @@ package eu.faircode.email;
|
|||
Copyright 2018 by Marcel Bokhorst (M66B)
|
||||
*/
|
||||
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
import android.os.Bundle;
|
||||
import android.text.TextUtils;
|
||||
import android.view.MenuItem;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
import androidx.fragment.app.FragmentManager;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
@ -42,8 +47,44 @@ public class ActivityCompose extends ActivityBase implements FragmentManager.OnB
|
|||
getSupportFragmentManager().addOnBackStackChangedListener(this);
|
||||
|
||||
if (getSupportFragmentManager().getFragments().size() == 0) {
|
||||
Bundle args;
|
||||
if (Intent.ACTION_SEND.equals(getIntent().getAction()) ||
|
||||
Intent.ACTION_SENDTO.equals(getIntent().getAction()) ||
|
||||
Intent.ACTION_SEND_MULTIPLE.equals(getIntent().getAction())) {
|
||||
args = new Bundle();
|
||||
|
||||
args.putString("action", "new");
|
||||
args.putLong("account", -1);
|
||||
|
||||
if (getIntent().hasExtra(Intent.EXTRA_EMAIL))
|
||||
args.putString("to", TextUtils.join(", ", getIntent().getStringArrayExtra(Intent.EXTRA_EMAIL)));
|
||||
|
||||
if (getIntent().hasExtra(Intent.EXTRA_CC))
|
||||
args.putString("cc", TextUtils.join(", ", getIntent().getStringArrayExtra(Intent.EXTRA_CC)));
|
||||
|
||||
if (getIntent().hasExtra(Intent.EXTRA_BCC))
|
||||
args.putString("bcc", TextUtils.join(", ", getIntent().getStringArrayExtra(Intent.EXTRA_BCC)));
|
||||
|
||||
if (getIntent().hasExtra(Intent.EXTRA_SUBJECT))
|
||||
args.putString("subject", getIntent().getStringExtra(Intent.EXTRA_SUBJECT));
|
||||
|
||||
if (getIntent().hasExtra(Intent.EXTRA_TEXT))
|
||||
args.putString("body", getIntent().getStringExtra(Intent.EXTRA_TEXT)); // Intent.EXTRA_HTML_TEXT
|
||||
|
||||
if (getIntent().hasExtra(Intent.EXTRA_STREAM))
|
||||
if (Intent.ACTION_SEND_MULTIPLE.equals(getIntent().getAction()))
|
||||
args.putParcelableArrayList("attachments", getIntent().getParcelableArrayListExtra(Intent.EXTRA_STREAM));
|
||||
else {
|
||||
ArrayList<Uri> uris = new ArrayList<>();
|
||||
uris.add((Uri) getIntent().getParcelableExtra(Intent.EXTRA_STREAM));
|
||||
args.putParcelableArrayList("attachments", uris);
|
||||
}
|
||||
|
||||
} else
|
||||
args = getIntent().getExtras();
|
||||
|
||||
FragmentCompose fragment = new FragmentCompose();
|
||||
fragment.setArguments(getIntent().getExtras());
|
||||
fragment.setArguments(args);
|
||||
|
||||
FragmentTransaction fragmentTransaction = getSupportFragmentManager().beginTransaction();
|
||||
fragmentTransaction.replace(R.id.content_frame, fragment).addToBackStack("compose");
|
||||
|
|
|
@ -41,6 +41,9 @@ public interface DaoAccount {
|
|||
@Query("SELECT * FROM account WHERE id = :id")
|
||||
EntityAccount getAccount(long id);
|
||||
|
||||
@Query("SELECT * FROM account WHERE `primary`")
|
||||
EntityAccount getPrimaryAccount();
|
||||
|
||||
@Query("SELECT * FROM account WHERE `primary`")
|
||||
LiveData<EntityAccount> livePrimaryAccount();
|
||||
|
||||
|
|
|
@ -68,6 +68,7 @@ import java.util.List;
|
|||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.MessageRemovedException;
|
||||
import javax.mail.internet.AddressException;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
@ -328,6 +329,12 @@ public class FragmentCompose extends FragmentEx {
|
|||
args.putLong("id", getArguments().getLong("id", -1));
|
||||
args.putLong("account", getArguments().getLong("account", -1));
|
||||
args.putLong("reference", getArguments().getLong("reference", -1));
|
||||
args.putString("to", getArguments().getString("to"));
|
||||
args.putString("cc", getArguments().getString("cc"));
|
||||
args.putString("bcc", getArguments().getString("bcc"));
|
||||
args.putString("subject", getArguments().getString("subject"));
|
||||
args.putString("body", getArguments().getString("body"));
|
||||
args.putParcelableArrayList("attachments", getArguments().getParcelableArrayList("attachments"));
|
||||
draftLoader.load(this, args);
|
||||
} else {
|
||||
Bundle args = new Bundle();
|
||||
|
@ -455,92 +462,10 @@ public class FragmentCompose extends FragmentEx {
|
|||
new SimpleTask<Void>() {
|
||||
@Override
|
||||
protected Void onLoad(Context context, Bundle args) throws IOException {
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
Uri uri = args.getParcelable("uri");
|
||||
cursor = context.getContentResolver().query(uri, null, null, null, null, null);
|
||||
if (cursor == null || !cursor.moveToFirst())
|
||||
return null;
|
||||
|
||||
Long id = args.getLong("id");
|
||||
EntityAttachment attachment = new EntityAttachment();
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityMessage draft = db.message().getMessage(id);
|
||||
Log.i(Helper.TAG, "Attaching to id=" + draft.id);
|
||||
|
||||
attachment.message = draft.id;
|
||||
attachment.sequence = db.attachment().getAttachmentCount(draft.id) + 1;
|
||||
attachment.name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(attachment.name.toLowerCase());
|
||||
if (extension != null)
|
||||
attachment.type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
if (attachment.type == null)
|
||||
attachment.type = "application/octet-stream";
|
||||
|
||||
String size = cursor.getString(cursor.getColumnIndex(OpenableColumns.SIZE));
|
||||
|
||||
attachment.size = (size == null ? null : Integer.parseInt(size));
|
||||
attachment.progress = 0;
|
||||
|
||||
attachment.id = db.attachment().insertAttachment(attachment);
|
||||
Log.i(Helper.TAG, "Created attachment seq=" + attachment.sequence +
|
||||
" name=" + attachment.name + " type=" + attachment.type);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
try {
|
||||
File file = EntityAttachment.getFile(context, attachment.id);
|
||||
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
is = context.getContentResolver().openInputStream(uri);
|
||||
os = new BufferedOutputStream(new FileOutputStream(file));
|
||||
|
||||
int size = 0;
|
||||
byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE];
|
||||
for (int len = is.read(buffer); len != -1; len = is.read(buffer)) {
|
||||
size += len;
|
||||
os.write(buffer, 0, len);
|
||||
|
||||
// Update progress
|
||||
if (attachment.size != null)
|
||||
db.attachment().setProgress(attachment.id, size * 100 / attachment.size);
|
||||
}
|
||||
|
||||
attachment.size = size;
|
||||
attachment.progress = null;
|
||||
attachment.available = true;
|
||||
db.attachment().updateAttachment(attachment);
|
||||
} finally {
|
||||
try {
|
||||
if (is != null)
|
||||
is.close();
|
||||
} finally {
|
||||
if (os != null)
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
// Reset progress on failure
|
||||
attachment.progress = null;
|
||||
db.attachment().updateAttachment(attachment);
|
||||
throw ex;
|
||||
}
|
||||
|
||||
return null;
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
Long id = args.getLong("id");
|
||||
Uri uri = args.getParcelable("uri");
|
||||
addAttachment(context, id, uri);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -570,6 +495,95 @@ public class FragmentCompose extends FragmentEx {
|
|||
actionLoader.load(this, args);
|
||||
}
|
||||
|
||||
private void addAttachment(Context context, long id, Uri uri) throws IOException {
|
||||
EntityAttachment attachment = new EntityAttachment();
|
||||
|
||||
String name = null;
|
||||
String s = null;
|
||||
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = context.getContentResolver().query(uri, null, null, null, null, null);
|
||||
if (cursor != null && cursor.moveToFirst()) {
|
||||
name = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
|
||||
s = cursor.getString(cursor.getColumnIndex(OpenableColumns.SIZE));
|
||||
}
|
||||
|
||||
} finally {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
|
||||
DB db = DB.getInstance(context);
|
||||
try {
|
||||
db.beginTransaction();
|
||||
|
||||
EntityMessage draft = db.message().getMessage(id);
|
||||
Log.i(Helper.TAG, "Attaching to id=" + draft.id);
|
||||
|
||||
attachment.message = draft.id;
|
||||
attachment.sequence = db.attachment().getAttachmentCount(draft.id) + 1;
|
||||
attachment.name = name;
|
||||
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(attachment.name.toLowerCase());
|
||||
if (extension != null)
|
||||
attachment.type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
|
||||
if (attachment.type == null)
|
||||
attachment.type = "application/octet-stream";
|
||||
|
||||
|
||||
attachment.size = (s == null ? null : Integer.parseInt(s));
|
||||
attachment.progress = 0;
|
||||
|
||||
attachment.id = db.attachment().insertAttachment(attachment);
|
||||
Log.i(Helper.TAG, "Created attachment=" + attachment.name + ":" + attachment.sequence + " type=" + attachment.type);
|
||||
|
||||
db.setTransactionSuccessful();
|
||||
} finally {
|
||||
db.endTransaction();
|
||||
}
|
||||
|
||||
try {
|
||||
File file = EntityAttachment.getFile(context, attachment.id);
|
||||
|
||||
InputStream is = null;
|
||||
OutputStream os = null;
|
||||
try {
|
||||
is = context.getContentResolver().openInputStream(uri);
|
||||
os = new BufferedOutputStream(new FileOutputStream(file));
|
||||
|
||||
int size = 0;
|
||||
byte[] buffer = new byte[ATTACHMENT_BUFFER_SIZE];
|
||||
for (int len = is.read(buffer); len != -1; len = is.read(buffer)) {
|
||||
size += len;
|
||||
os.write(buffer, 0, len);
|
||||
|
||||
// Update progress
|
||||
if (attachment.size != null)
|
||||
db.attachment().setProgress(attachment.id, size * 100 / attachment.size);
|
||||
}
|
||||
|
||||
attachment.size = size;
|
||||
attachment.progress = null;
|
||||
attachment.available = true;
|
||||
db.attachment().updateAttachment(attachment);
|
||||
} finally {
|
||||
try {
|
||||
if (is != null)
|
||||
is.close();
|
||||
} finally {
|
||||
if (os != null)
|
||||
os.close();
|
||||
}
|
||||
}
|
||||
} catch (IOException ex) {
|
||||
// Reset progress on failure
|
||||
attachment.progress = null;
|
||||
db.attachment().updateAttachment(attachment);
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
private SimpleTask<EntityMessage> draftLoader = new SimpleTask<EntityMessage>() {
|
||||
@Override
|
||||
protected EntityMessage onLoad(Context context, Bundle args) throws IOException {
|
||||
|
@ -594,7 +608,14 @@ public class FragmentCompose extends FragmentEx {
|
|||
return draft;
|
||||
|
||||
EntityMessage ref = db.message().getMessage(reference);
|
||||
if (ref != null) {
|
||||
if (ref == null) {
|
||||
if (account < 0) {
|
||||
EntityAccount a = db.account().getPrimaryAccount();
|
||||
if (a == null)
|
||||
throw new IllegalArgumentException(context.getString(R.string.title_no_account));
|
||||
account = a.id;
|
||||
}
|
||||
} else {
|
||||
account = ref.account;
|
||||
|
||||
// Reply to sender, not to known self
|
||||
|
@ -626,7 +647,34 @@ public class FragmentCompose extends FragmentEx {
|
|||
draft.folder = drafts.id;
|
||||
draft.msgid = EntityMessage.generateMessageId(); // for multiple appends
|
||||
|
||||
if (ref != null) {
|
||||
if (ref == null) {
|
||||
try {
|
||||
String to = args.getString("to");
|
||||
draft.to = (TextUtils.isEmpty(to) ? null : InternetAddress.parse(to));
|
||||
} catch (AddressException ex) {
|
||||
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
String cc = args.getString("cc");
|
||||
draft.cc = (TextUtils.isEmpty(cc) ? null : InternetAddress.parse(cc));
|
||||
} catch (AddressException ex) {
|
||||
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
||||
try {
|
||||
String bcc = args.getString("bcc");
|
||||
draft.bcc = (TextUtils.isEmpty(bcc) ? null : InternetAddress.parse(bcc));
|
||||
} catch (AddressException ex) {
|
||||
Log.w(Helper.TAG, ex + "\n" + Log.getStackTraceString(ex));
|
||||
}
|
||||
|
||||
draft.subject = args.getString("subject");
|
||||
body = args.getString("body");
|
||||
if (!TextUtils.isEmpty(body))
|
||||
body = "<pre>" + body.replaceAll("\\r?\\n", "<br />") + "</pre>";
|
||||
|
||||
} else {
|
||||
draft.thread = ref.thread;
|
||||
|
||||
if ("reply".equals(action) || "reply_all".equals(action)) {
|
||||
|
@ -656,16 +704,19 @@ public class FragmentCompose extends FragmentEx {
|
|||
}
|
||||
}
|
||||
|
||||
if ("new".equals(action))
|
||||
body = "";
|
||||
|
||||
draft.received = new Date().getTime();
|
||||
draft.seen = false;
|
||||
draft.ui_seen = false;
|
||||
draft.ui_hide = false;
|
||||
|
||||
draft.id = db.message().insertMessage(draft);
|
||||
draft.write(context, body);
|
||||
draft.write(context, body == null ? "" : body);
|
||||
|
||||
if (args.containsKey("attachments")) {
|
||||
ArrayList<Uri> uris = args.getParcelableArrayList("attachments");
|
||||
for (Uri uri : uris)
|
||||
addAttachment(context, draft.id, uri);
|
||||
}
|
||||
|
||||
EntityOperation.queue(db, draft, EntityOperation.ADD);
|
||||
|
||||
|
|
Loading…
Reference in a new issue