mirror of
https://github.com/moparisthebest/k-9
synced 2024-11-23 18:02:15 -05:00
If we can't find an app to view an attachment try again with a file:// URI
Sadly, some apps only support the 'file' scheme in their intent filters. Among them is Android's own package installer.
This commit is contained in:
parent
44ecf5d588
commit
6a1905b7b7
@ -223,16 +223,10 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
|||||||
*/
|
*/
|
||||||
public void writeFile(File directory) {
|
public void writeFile(File directory) {
|
||||||
try {
|
try {
|
||||||
String filename = Utility.sanitizeFilename(name);
|
File file = writeAttachmentToStorage(directory);
|
||||||
File file = Utility.createUniqueFile(directory, filename);
|
|
||||||
Uri uri = AttachmentProvider.getAttachmentUri(account, part.getAttachmentId());
|
|
||||||
InputStream in = context.getContentResolver().openInputStream(uri);
|
|
||||||
OutputStream out = new FileOutputStream(file);
|
|
||||||
IOUtils.copy(in, out);
|
|
||||||
out.flush();
|
|
||||||
out.close();
|
|
||||||
in.close();
|
|
||||||
displayAttachmentSavedMessage(file.toString());
|
displayAttachmentSavedMessage(file.toString());
|
||||||
|
|
||||||
new MediaScannerNotifier(context, file);
|
new MediaScannerNotifier(context, file);
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (K9.DEBUG) {
|
if (K9.DEBUG) {
|
||||||
@ -242,20 +236,55 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void showFile() {
|
private File writeAttachmentToStorage(File directory) throws IOException {
|
||||||
Intent intent = constructViewIntent();
|
String filename = Utility.sanitizeFilename(name);
|
||||||
|
File file = Utility.createUniqueFile(directory, filename);
|
||||||
|
|
||||||
|
Uri uri = AttachmentProvider.getAttachmentUri(account, part.getAttachmentId());
|
||||||
|
InputStream in = context.getContentResolver().openInputStream(uri);
|
||||||
try {
|
try {
|
||||||
context.startActivity(intent);
|
OutputStream out = new FileOutputStream(file);
|
||||||
} catch (ActivityNotFoundException e) {
|
try {
|
||||||
Log.e(K9.LOG_TAG, "Could not display attachment of type " + contentType, e);
|
IOUtils.copy(in, out);
|
||||||
|
out.flush();
|
||||||
|
} finally {
|
||||||
|
out.close();
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
in.close();
|
||||||
|
}
|
||||||
|
|
||||||
String message = context.getString(R.string.message_view_no_viewer, contentType);
|
return file;
|
||||||
displayMessageToUser(message);
|
}
|
||||||
|
|
||||||
|
public void showFile() {
|
||||||
|
new ViewAttachmentAsyncTask().executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Intent getBestViewIntentAndSaveFileIfNecessary() {
|
||||||
|
IntentAndResolvedActivitiesCount resultForContentUri = getBestViewIntentForContentUri();
|
||||||
|
if (resultForContentUri.getActivitiesCount() > 0) {
|
||||||
|
return resultForContentUri.getIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
IntentAndResolvedActivitiesCount resultForFileUri = getBestViewIntentForFileUri();
|
||||||
|
if (resultForFileUri.getActivitiesCount() > 0) {
|
||||||
|
try {
|
||||||
|
File file = writeAttachmentToStorage(new File(K9.getAttachmentDefaultPath()));
|
||||||
|
return createViewIntentForFileUri(resultForFileUri.getMimeType(), Uri.fromFile(file));
|
||||||
|
} catch (IOException e) {
|
||||||
|
if (K9.DEBUG) {
|
||||||
|
Log.e(K9.LOG_TAG, "Error while saving attachment to use file:// URI with ACTION_VIEW Intent", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Intent constructViewIntent() {
|
return resultForContentUri.getIntent();
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntentAndResolvedActivitiesCount getBestViewIntentForContentUri() {
|
||||||
Intent intent;
|
Intent intent;
|
||||||
|
int activitiesCount;
|
||||||
|
|
||||||
Uri originalMimeTypeUri = AttachmentProvider.getAttachmentUriForViewing(account, part.getAttachmentId(),
|
Uri originalMimeTypeUri = AttachmentProvider.getAttachmentUriForViewing(account, part.getAttachmentId(),
|
||||||
contentType);
|
contentType);
|
||||||
@ -265,6 +294,7 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
|||||||
String inferredMimeType = MimeUtility.getMimeTypeByExtension(name);
|
String inferredMimeType = MimeUtility.getMimeTypeByExtension(name);
|
||||||
if (inferredMimeType.equals(contentType)) {
|
if (inferredMimeType.equals(contentType)) {
|
||||||
intent = originalMimeTypeIntent;
|
intent = originalMimeTypeIntent;
|
||||||
|
activitiesCount = originalMimeTypeActivitiesCount;
|
||||||
} else {
|
} else {
|
||||||
Uri inferredMimeTypeUri = AttachmentProvider.getAttachmentUriForViewing(account, part.getAttachmentId(),
|
Uri inferredMimeTypeUri = AttachmentProvider.getAttachmentUriForViewing(account, part.getAttachmentId(),
|
||||||
inferredMimeType);
|
inferredMimeType);
|
||||||
@ -273,22 +303,67 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
|||||||
|
|
||||||
if (inferredMimeTypeActivitiesCount > originalMimeTypeActivitiesCount) {
|
if (inferredMimeTypeActivitiesCount > originalMimeTypeActivitiesCount) {
|
||||||
intent = inferredMimeTypeIntent;
|
intent = inferredMimeTypeIntent;
|
||||||
|
activitiesCount = inferredMimeTypeActivitiesCount;
|
||||||
} else {
|
} else {
|
||||||
intent = originalMimeTypeIntent;
|
intent = originalMimeTypeIntent;
|
||||||
|
activitiesCount = originalMimeTypeActivitiesCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return intent;
|
return new IntentAndResolvedActivitiesCount(intent, activitiesCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IntentAndResolvedActivitiesCount getBestViewIntentForFileUri() {
|
||||||
|
Intent intent;
|
||||||
|
int activitiesCount;
|
||||||
|
|
||||||
|
File dummyFile = new File(Utility.sanitizeFilename(name));
|
||||||
|
Uri fileUri = Uri.fromFile(dummyFile);
|
||||||
|
|
||||||
|
Intent originalMimeTypeIntent = createViewIntentForFileUri(contentType, fileUri);
|
||||||
|
int originalMimeTypeActivitiesCount = getResolvedIntentActivitiesCount(originalMimeTypeIntent);
|
||||||
|
|
||||||
|
String inferredMimeType = MimeUtility.getMimeTypeByExtension(name);
|
||||||
|
if (inferredMimeType.equals(contentType)) {
|
||||||
|
intent = originalMimeTypeIntent;
|
||||||
|
activitiesCount = originalMimeTypeActivitiesCount;
|
||||||
|
} else {
|
||||||
|
Intent inferredMimeTypeIntent = createViewIntentForFileUri(inferredMimeType, fileUri);
|
||||||
|
int inferredMimeTypeActivitiesCount = getResolvedIntentActivitiesCount(inferredMimeTypeIntent);
|
||||||
|
|
||||||
|
if (inferredMimeTypeActivitiesCount > originalMimeTypeActivitiesCount) {
|
||||||
|
intent = inferredMimeTypeIntent;
|
||||||
|
activitiesCount = inferredMimeTypeActivitiesCount;
|
||||||
|
} else {
|
||||||
|
intent = originalMimeTypeIntent;
|
||||||
|
activitiesCount = originalMimeTypeActivitiesCount;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new IntentAndResolvedActivitiesCount(intent, activitiesCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Intent createViewIntentForContentUri(String mimeType, Uri uri) {
|
private Intent createViewIntentForContentUri(String mimeType, Uri uri) {
|
||||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
intent.setDataAndType(uri, mimeType);
|
intent.setDataAndType(uri, mimeType);
|
||||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||||
|
addUiIntentFlags(intent);
|
||||||
|
|
||||||
return intent;
|
return intent;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Intent createViewIntentForFileUri(String mimeType, Uri uri) {
|
||||||
|
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||||
|
intent.setDataAndType(uri, mimeType);
|
||||||
|
addUiIntentFlags(intent);
|
||||||
|
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addUiIntentFlags(Intent intent) {
|
||||||
|
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_WHEN_TASK_RESET);
|
||||||
|
}
|
||||||
|
|
||||||
private int getResolvedIntentActivitiesCount(Intent intent) {
|
private int getResolvedIntentActivitiesCount(Intent intent) {
|
||||||
PackageManager packageManager = context.getPackageManager();
|
PackageManager packageManager = context.getPackageManager();
|
||||||
|
|
||||||
@ -328,6 +403,28 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static class IntentAndResolvedActivitiesCount {
|
||||||
|
private Intent intent;
|
||||||
|
private int activitiesCount;
|
||||||
|
|
||||||
|
IntentAndResolvedActivitiesCount(Intent intent, int activitiesCount) {
|
||||||
|
this.intent = intent;
|
||||||
|
this.activitiesCount = activitiesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Intent getIntent() {
|
||||||
|
return intent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getActivitiesCount() {
|
||||||
|
return activitiesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getMimeType() {
|
||||||
|
return intent.getType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private class LoadAndDisplayThumbnailAsyncTask extends AsyncTask<Void, Void, Bitmap> {
|
private class LoadAndDisplayThumbnailAsyncTask extends AsyncTask<Void, Void, Bitmap> {
|
||||||
private final ImageView thumbnail;
|
private final ImageView thumbnail;
|
||||||
|
|
||||||
@ -364,4 +461,34 @@ public class AttachmentView extends FrameLayout implements OnClickListener, OnLo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class ViewAttachmentAsyncTask extends AsyncTask<Void, Void, Intent> {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPreExecute() {
|
||||||
|
viewButton.setEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Intent doInBackground(Void... params) {
|
||||||
|
return getBestViewIntentAndSaveFileIfNecessary();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void onPostExecute(Intent intent) {
|
||||||
|
viewAttachment(intent);
|
||||||
|
viewButton.setEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void viewAttachment(Intent intent) {
|
||||||
|
try {
|
||||||
|
context.startActivity(intent);
|
||||||
|
} catch (ActivityNotFoundException e) {
|
||||||
|
Log.e(K9.LOG_TAG, "Could not display attachment of type " + contentType, e);
|
||||||
|
|
||||||
|
String message = context.getString(R.string.message_view_no_viewer, contentType);
|
||||||
|
displayMessageToUser(message);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user