Add support for application/* attachments

pull/848/head
Alex Baker 7 years ago
parent f733660480
commit 5ca9b1e83f

@ -190,6 +190,7 @@
<category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.DEFAULT"/>
<data android:mimeType="text/plain" /> <data android:mimeType="text/plain" />
<data android:mimeType="image/*" /> <data android:mimeType="image/*" />
<data android:mimeType="application/*" />
</intent-filter> </intent-filter>
<intent-filter> <intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE"/> <action android:name="android.intent.action.SEND_MULTIPLE"/>

@ -1,7 +1,11 @@
package com.todoroo.astrid.activity; package com.todoroo.astrid.activity;
import static android.content.Intent.ACTION_SEND;
import static android.content.Intent.ACTION_SEND_MULTIPLE;
import static com.google.common.collect.Lists.newArrayList; import static com.google.common.collect.Lists.newArrayList;
import static com.todoroo.andlib.utility.AndroidUtilities.atLeastMarshmallow; import static com.todoroo.andlib.utility.AndroidUtilities.atLeastMarshmallow;
import static org.tasks.files.FileHelper.copyToUri;
import static org.tasks.files.FileHelper.getFilename;
import static org.tasks.intents.TaskIntents.getTaskListIntent; import static org.tasks.intents.TaskIntents.getTaskListIntent;
import android.content.Context; import android.content.Context;
@ -9,13 +13,18 @@ import android.content.Intent;
import android.net.Uri; import android.net.Uri;
import android.os.Bundle; import android.os.Bundle;
import androidx.core.app.TaskStackBuilder; import androidx.core.app.TaskStackBuilder;
import com.google.common.base.Strings;
import com.google.common.io.Files;
import com.todoroo.astrid.data.Task; import com.todoroo.astrid.data.Task;
import com.todoroo.astrid.service.TaskCreator; import com.todoroo.astrid.service.TaskCreator;
import java.util.ArrayList; import java.util.ArrayList;
import javax.inject.Inject; import javax.inject.Inject;
import org.tasks.data.TaskAttachment; import org.tasks.data.TaskAttachment;
import org.tasks.files.FileHelper;
import org.tasks.injection.ActivityComponent; import org.tasks.injection.ActivityComponent;
import org.tasks.injection.ForApplication;
import org.tasks.injection.InjectingAppCompatActivity; import org.tasks.injection.InjectingAppCompatActivity;
import org.tasks.preferences.Preferences;
import timber.log.Timber; import timber.log.Timber;
/** /**
@ -24,7 +33,15 @@ import timber.log.Timber;
*/ */
public final class ShareLinkActivity extends InjectingAppCompatActivity { public final class ShareLinkActivity extends InjectingAppCompatActivity {
@Inject @ForApplication Context context;
@Inject TaskCreator taskCreator; @Inject TaskCreator taskCreator;
@Inject Preferences preferences;
private static TaskStackBuilder getEditTaskStack(Context context, Task task) {
Intent intent = getTaskListIntent(context, null);
intent.putExtra(MainActivity.OPEN_TASK, task);
return TaskStackBuilder.create(context).addNextIntent(intent);
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
@ -57,11 +74,20 @@ public final class ShareLinkActivity extends InjectingAppCompatActivity {
Task task = taskCreator.createWithValues(text.toString()); Task task = taskCreator.createWithValues(text.toString());
getEditTaskStack(this, task).startActivities(); getEditTaskStack(this, task).startActivities();
} }
} else if (action.equals(Intent.ACTION_SEND) || action.equals(Intent.ACTION_SEND_MULTIPLE)) { } else if (ACTION_SEND.equals(action)) {
String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT); String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
Task task = taskCreator.createWithValues(subject); Task task = taskCreator.createWithValues(subject);
task.setNotes(intent.getStringExtra(Intent.EXTRA_TEXT)); task.setNotes(intent.getStringExtra(Intent.EXTRA_TEXT));
task.putTransitory(TaskAttachment.KEY, getAttachments(intent)); if (hasAttachments(intent)) {
task.putTransitory(TaskAttachment.KEY, copyAttachment(intent));
}
getEditTaskStack(this, task).startActivities();
} else if (ACTION_SEND_MULTIPLE.equals(action)) {
Task task = taskCreator.createWithValues(intent.getStringExtra(Intent.EXTRA_SUBJECT));
task.setNotes(intent.getStringExtra(Intent.EXTRA_TEXT));
if (hasAttachments(intent)) {
task.putTransitory(TaskAttachment.KEY, copyMultipleAttachments(intent));
}
getEditTaskStack(this, task).startActivities(); getEditTaskStack(this, task).startActivities();
} else { } else {
Timber.e("Unhandled intent: %s", intent); Timber.e("Unhandled intent: %s", intent);
@ -69,26 +95,33 @@ public final class ShareLinkActivity extends InjectingAppCompatActivity {
finish(); finish();
} }
private static TaskStackBuilder getEditTaskStack(Context context, Task task) { private ArrayList<Uri> copyAttachment(Intent intent) {
Intent intent = getTaskListIntent(context, null); Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);
intent.putExtra(MainActivity.OPEN_TASK, task); String filename = getFilename(context, uri);
return TaskStackBuilder.create(context).addNextIntent(intent); if (Strings.isNullOrEmpty(filename)) {
String subject = intent.getStringExtra(Intent.EXTRA_SUBJECT);
filename =
Strings.isNullOrEmpty(subject)
? uri.getLastPathSegment()
: subject.substring(0, Math.min(subject.length(), FileHelper.MAX_FILENAME_LENGTH));
} }
String basename = Files.getNameWithoutExtension(filename);
private ArrayList<Uri> getAttachments(Intent intent) { return newArrayList(copyToUri(context, preferences.getAttachmentsDirectory(), uri, basename));
String type = intent.getType();
if (type != null) {
String action = intent.getAction();
if (action.equals(Intent.ACTION_SEND)) {
if (type.startsWith("image/")) {
return newArrayList(intent.<Uri>getParcelableExtra(Intent.EXTRA_STREAM));
} }
} else if (action.equals(Intent.ACTION_SEND_MULTIPLE)) {
if (type.startsWith("image/")) { private ArrayList<Uri> copyMultipleAttachments(Intent intent) {
return intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM); ArrayList<Uri> result = new ArrayList<>();
ArrayList<Uri> uris = intent.getParcelableArrayListExtra(Intent.EXTRA_STREAM);
if (uris != null) {
for (Uri uri : uris) {
result.add(copyToUri(context, preferences.getAttachmentsDirectory(), uri));
} }
} }
return result;
} }
return new ArrayList<>();
private boolean hasAttachments(Intent intent) {
String type = intent.getType();
return type != null && (type.startsWith("image/") || type.startsWith("application/"));
} }
} }

@ -7,7 +7,6 @@
package com.todoroo.astrid.files; package com.todoroo.astrid.files;
import static android.app.Activity.RESULT_OK; import static android.app.Activity.RESULT_OK;
import static org.tasks.data.TaskAttachment.createNewAttachment;
import static org.tasks.dialogs.AddAttachmentDialog.REQUEST_AUDIO; import static org.tasks.dialogs.AddAttachmentDialog.REQUEST_AUDIO;
import static org.tasks.dialogs.AddAttachmentDialog.REQUEST_CAMERA; import static org.tasks.dialogs.AddAttachmentDialog.REQUEST_CAMERA;
import static org.tasks.dialogs.AddAttachmentDialog.REQUEST_GALLERY; import static org.tasks.dialogs.AddAttachmentDialog.REQUEST_GALLERY;
@ -76,7 +75,7 @@ public class FilesControlSet extends TaskEditControlFragment {
if (savedInstanceState == null) { if (savedInstanceState == null) {
if (task.hasTransitory(TaskAttachment.KEY)) { if (task.hasTransitory(TaskAttachment.KEY)) {
for (Uri uri : (ArrayList<Uri>) task.getTransitory(TaskAttachment.KEY)) { for (Uri uri : (ArrayList<Uri>) task.getTransitory(TaskAttachment.KEY)) {
copyToAttachmentDirectory(uri); newAttachment(uri);
} }
} }
} }
@ -164,9 +163,12 @@ public class FilesControlSet extends TaskEditControlFragment {
} }
private void copyToAttachmentDirectory(Uri input) { private void copyToAttachmentDirectory(Uri input) {
Uri output = copyToUri(context, preferences.getAttachmentsDirectory(), input); newAttachment(copyToUri(context, preferences.getAttachmentsDirectory(), input));
}
private void newAttachment(Uri output) {
TaskAttachment attachment = TaskAttachment attachment =
createNewAttachment(taskUuid, output, FileHelper.getFilename(context, output)); new TaskAttachment(taskUuid, output, FileHelper.getFilename(context, output));
taskAttachmentDao.createNew(attachment); taskAttachmentDao.createNew(attachment);
addAttachment(attachment); addAttachment(attachment);
} }

@ -164,7 +164,6 @@ public class TaskCreator {
break; break;
case GoogleTask.KEY: case GoogleTask.KEY:
case CaldavTask.KEY: case CaldavTask.KEY:
case TaskAttachment.KEY:
task.putTransitory(key, value); task.putTransitory(key, value);
break; break;
default: default:

@ -3,6 +3,7 @@ package org.tasks.data;
import android.net.Uri; import android.net.Uri;
import androidx.room.ColumnInfo; import androidx.room.ColumnInfo;
import androidx.room.Entity; import androidx.room.Entity;
import androidx.room.Ignore;
import androidx.room.PrimaryKey; import androidx.room.PrimaryKey;
import com.google.common.base.Strings; import com.google.common.base.Strings;
import com.todoroo.andlib.data.Table; import com.todoroo.andlib.data.Table;
@ -39,12 +40,13 @@ public final class TaskAttachment {
@ColumnInfo(name = "content_type") @ColumnInfo(name = "content_type")
private String contentType = ""; private String contentType = "";
public static TaskAttachment createNewAttachment(String taskUuid, Uri uri, String fileName) { public TaskAttachment() {}
TaskAttachment attachment = new TaskAttachment();
attachment.setTaskId(taskUuid); @Ignore
attachment.setName(fileName); public TaskAttachment(String taskUuid, Uri uri, String fileName) {
attachment.setUri(uri); taskId = taskUuid;
return attachment; name = fileName;
setUri(uri);
} }
public Long getId() { public Long getId() {

@ -39,6 +39,8 @@ import timber.log.Timber;
public class FileHelper { public class FileHelper {
public static final int MAX_FILENAME_LENGTH = 40;
public static Intent newFilePickerIntent(Activity activity, Uri initial, String... mimeTypes) { public static Intent newFilePickerIntent(Activity activity, Uri initial, String... mimeTypes) {
if (atLeastKitKat()) { if (atLeastKitKat()) {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
@ -127,7 +129,7 @@ public class FileHelper {
} }
} }
public static String getFilename(Context context, Uri uri) { public @Nullable static String getFilename(Context context, Uri uri) {
switch (uri.getScheme()) { switch (uri.getScheme()) {
case ContentResolver.SCHEME_FILE: case ContentResolver.SCHEME_FILE:
return uri.getLastPathSegment(); return uri.getLastPathSegment();
@ -147,9 +149,8 @@ public class FileHelper {
public static String getExtension(Context context, Uri uri) { public static String getExtension(Context context, Uri uri) {
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) { if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
String extension = String mimeType = context.getContentResolver().getType(uri);
MimeTypeMap.getSingleton() String extension = MimeTypeMap.getSingleton().getExtensionFromMimeType(mimeType);
.getExtensionFromMimeType(context.getContentResolver().getType(uri));
if (!Strings.isNullOrEmpty(extension)) { if (!Strings.isNullOrEmpty(extension)) {
return extension; return extension;
} }
@ -164,8 +165,11 @@ public class FileHelper {
} }
public static String getMimeType(Context context, Uri uri) { public static String getMimeType(Context context, Uri uri) {
String filename = getFilename(context, uri); String mimeType = context.getContentResolver().getType(uri);
String extension = Files.getFileExtension(filename); if (!Strings.isNullOrEmpty(mimeType)) {
return mimeType;
}
String extension = getExtension(context, uri);
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension); return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
} }
@ -233,14 +237,20 @@ public class FileHelper {
} }
public static Uri copyToUri(Context context, Uri destination, Uri input) { public static Uri copyToUri(Context context, Uri destination, Uri input) {
ContentResolver contentResolver = context.getContentResolver();
MimeTypeMap mime = MimeTypeMap.getSingleton();
String filename = getFilename(context, input); String filename = getFilename(context, input);
String baseName = Files.getNameWithoutExtension(filename); return copyToUri(context, destination, input, Files.getNameWithoutExtension(filename));
String extension = Files.getFileExtension(filename); }
String mimeType = mime.getMimeTypeFromExtension(extension);
public static Uri copyToUri(Context context, Uri destination, Uri input, String basename) {
ContentResolver contentResolver = context.getContentResolver();
try { try {
Uri output = newFile(context, destination, mimeType, baseName, extension); Uri output =
newFile(
context,
destination,
getMimeType(context, input),
basename,
getExtension(context, input));
InputStream inputStream = contentResolver.openInputStream(input); InputStream inputStream = contentResolver.openInputStream(input);
OutputStream outputStream = contentResolver.openOutputStream(output); OutputStream outputStream = contentResolver.openOutputStream(output);
ByteStreams.copy(inputStream, outputStream); ByteStreams.copy(inputStream, outputStream);

Loading…
Cancel
Save