Added Attachemtns Uri handling after single aattachment download.
MAILAND-1337
This commit is contained in:
parent
fd40973ac5
commit
fd536f2674
|
@ -400,7 +400,7 @@ public class AddAttachmentsActivity extends BaseStoragePermissionActivity implem
|
|||
public void onDownloadAttachmentEvent(DownloadedAttachmentEvent event) {
|
||||
//once attachment has been downloaded
|
||||
if (event.getStatus().equals(Status.SUCCESS)) {
|
||||
DownloadUtils.viewAttachment(this, event.getFilename());
|
||||
DownloadUtils.viewAttachment(this, event.getFilename(), event.getAttachmentUri());
|
||||
TextExtensions.showToast(this, String.format(getString(R.string.attachment_download_success), event.getFilename()), Toast.LENGTH_SHORT);
|
||||
} else {
|
||||
TextExtensions.showToast(this, String.format(getString(R.string.attachment_download_failed), event.getFilename()), Toast.LENGTH_SHORT);
|
||||
|
|
|
@ -621,7 +621,7 @@ internal class MessageDetailsActivity :
|
|||
attachmentsListAdapter.setIsPgpEncrypted(viewModel.isPgpEncrypted())
|
||||
attachmentsListAdapter.setDownloaded(eventAttachmentId, isDownloaded)
|
||||
if (isDownloaded) {
|
||||
DownloadUtils.viewAttachment(this, event.filename)
|
||||
DownloadUtils.viewAttachment(this, event.filename, event.attachmentUri)
|
||||
} else {
|
||||
showToast(R.string.downloading)
|
||||
}
|
||||
|
|
|
@ -18,32 +18,33 @@
|
|||
*/
|
||||
package ch.protonmail.android.api.models.room.attachmentMetadata
|
||||
|
||||
import androidx.room.*
|
||||
import androidx.room.Dao
|
||||
import androidx.room.Delete
|
||||
import androidx.room.Insert
|
||||
import androidx.room.OnConflictStrategy
|
||||
import androidx.room.Query
|
||||
|
||||
/**
|
||||
* Created by Kamil Rajtar on 14.07.18.
|
||||
*/
|
||||
@Dao
|
||||
abstract class AttachmentMetadataDatabase {
|
||||
interface AttachmentMetadataDatabase {
|
||||
|
||||
@Insert(onConflict=OnConflictStrategy.REPLACE)
|
||||
abstract fun insertAttachmentMetadata(attachmentMetadata:AttachmentMetadata)
|
||||
@Insert(onConflict = OnConflictStrategy.REPLACE)
|
||||
fun insertAttachmentMetadata(attachmentMetadata: AttachmentMetadata)
|
||||
|
||||
@Delete
|
||||
abstract fun deleteAttachmentMetadata(attachmentMetadata:AttachmentMetadata)
|
||||
@Delete
|
||||
fun deleteAttachmentMetadata(attachmentMetadata: AttachmentMetadata)
|
||||
|
||||
@Query("DELETE FROM $TABLE_ATTACHMENT_METADATA")
|
||||
abstract fun clearAttachmentMetadataCache()
|
||||
@Query("DELETE FROM $TABLE_ATTACHMENT_METADATA")
|
||||
fun clearAttachmentMetadataCache()
|
||||
|
||||
@Query("SELECT SUM(${COLUMN_ATTACHMENT_FILE_SIZE}) size FROM $TABLE_ATTACHMENT_METADATA")
|
||||
abstract fun getAllAttachmentsSizeUsed():Long
|
||||
@Query("SELECT SUM($COLUMN_ATTACHMENT_FILE_SIZE) size FROM $TABLE_ATTACHMENT_METADATA")
|
||||
fun getAllAttachmentsSizeUsed(): Long
|
||||
|
||||
@Query("SELECT * FROM $TABLE_ATTACHMENT_METADATA WHERE ${COLUMN_ATTACHMENT_FOLDER_LOCATION}=:messageId")
|
||||
abstract fun getAllAttachmentsForMessage(messageId:String):List<AttachmentMetadata>
|
||||
@Query("SELECT * FROM $TABLE_ATTACHMENT_METADATA WHERE ${COLUMN_ATTACHMENT_FOLDER_LOCATION}=:messageId")
|
||||
fun getAllAttachmentsForMessage(messageId: String): List<AttachmentMetadata>
|
||||
|
||||
@Query("SELECT * FROM $TABLE_ATTACHMENT_METADATA WHERE ${COLUMN_ATTACHMENT_FOLDER_LOCATION}=:messageId AND ${COLUMN_ATTACHMENT_ID}=:attachmentId")
|
||||
abstract fun getAttachmentMetadataForMessageAndAttachmentId(messageId: String, attachmentId: String): AttachmentMetadata?
|
||||
@Query("SELECT * FROM $TABLE_ATTACHMENT_METADATA WHERE ${COLUMN_ATTACHMENT_FOLDER_LOCATION}=:messageId AND ${COLUMN_ATTACHMENT_ID}=:attachmentId")
|
||||
fun getAttachmentMetadataForMessageAndAttachmentId(messageId: String, attachmentId: String): AttachmentMetadata?
|
||||
|
||||
@Query("SELECT * FROM $TABLE_ATTACHMENT_METADATA")
|
||||
abstract fun getAllAttachmentsMetadata():List<AttachmentMetadata>
|
||||
@Query("SELECT * FROM $TABLE_ATTACHMENT_METADATA")
|
||||
fun getAllAttachmentsMetadata(): List<AttachmentMetadata>
|
||||
}
|
||||
|
|
|
@ -154,98 +154,56 @@ class DownloadEmbeddedAttachmentsWorker @WorkerInject constructor(
|
|||
messageId: String
|
||||
): Result {
|
||||
|
||||
|
||||
val filenameInCache = attachment.fileName?.replace(" ", "_")?.replace("/", ":") ?: ATTACHMENT_UNKNOWN_FILE_NAME
|
||||
Timber.v("handleSingleAttachment filename:$filenameInCache DirectoryFile:$attachmentsDirectoryFile")
|
||||
|
||||
AppUtil.postEventOnUi(
|
||||
DownloadedAttachmentEvent(
|
||||
Status.STARTED, filenameInCache, attachment.attachmentId, messageId, false
|
||||
Status.STARTED, filenameInCache, null, attachment.attachmentId, messageId, false
|
||||
)
|
||||
)
|
||||
|
||||
download(attachment, filenameInCache, crypto)
|
||||
// val attachmentFile = File(attachmentsDirectoryFile, filenameInCache)
|
||||
val attachmentUri = downloadAttachment(attachment, filenameInCache, crypto)
|
||||
|
||||
// applicationContext.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS)?.let { externalDirectory ->
|
||||
// val uniqueFilenameInDownloads = downloadHelper.createUniqueFilename(
|
||||
// attachment.fileName ?: ATTACHMENT_UNKNOWN_FILE_NAME,
|
||||
// externalDirectory
|
||||
// )
|
||||
//
|
||||
// try {
|
||||
// val decryptedByteArray = downloadHelper.getAttachmentData(
|
||||
// crypto,
|
||||
// attachment.mimeData,
|
||||
// attachment.attachmentId!!,
|
||||
// attachment.keyPackets,
|
||||
// attachment.fileSize,
|
||||
// uniqueFilenameInDownloads
|
||||
// )
|
||||
// FileOutputStream(attachmentFile).use {
|
||||
// it.write(decryptedByteArray)
|
||||
// }
|
||||
//
|
||||
// val attachmentMetadata = AttachmentMetadata(
|
||||
// attachment.attachmentId!!,
|
||||
// attachment.fileName!!,
|
||||
// attachment.fileSize,
|
||||
// attachment.messageId + "/" + attachment.attachmentId + "/" + filenameInCache,
|
||||
// attachment.messageId, System.currentTimeMillis()
|
||||
// )
|
||||
// attachmentMetadataDatabase.insertAttachmentMetadata(attachmentMetadata)
|
||||
//
|
||||
// attachmentFile.copyTo(
|
||||
// File(
|
||||
// externalDirectory,
|
||||
// uniqueFilenameInDownloads
|
||||
// )
|
||||
// )
|
||||
//
|
||||
// } catch (e: Exception) {
|
||||
// Timber.e(e, "handleSingleAttachment exception")
|
||||
// AppUtil.postEventOnUi(
|
||||
// DownloadedAttachmentEvent(Status.FAILED, filenameInCache, attachment.attachmentId, messageId, false)
|
||||
// )
|
||||
// return Result.failure()
|
||||
// }
|
||||
// AppUtil.postEventOnUi(
|
||||
// DownloadedAttachmentEvent(
|
||||
// Status.SUCCESS, uniqueFilenameInDownloads, attachment.attachmentId, messageId, false
|
||||
// )
|
||||
// )
|
||||
// } ?: run {
|
||||
// Timber.w("Unable to access DIRECTORY_DOWNLOADS to save attachments")
|
||||
// }
|
||||
|
||||
AppUtil.postEventOnUi(
|
||||
DownloadedAttachmentEvent(
|
||||
Status.SUCCESS, filenameInCache, attachment.attachmentId, messageId, false
|
||||
if (attachmentUri != null) {
|
||||
val attachmentMetadata = AttachmentMetadata(
|
||||
attachment.attachmentId!!,
|
||||
attachment.fileName!!,
|
||||
attachment.fileSize,
|
||||
attachment.messageId + "/" + attachment.attachmentId + "/" + filenameInCache,
|
||||
attachment.messageId, System.currentTimeMillis()
|
||||
)
|
||||
)
|
||||
|
||||
attachmentMetadataDatabase.insertAttachmentMetadata(attachmentMetadata)
|
||||
|
||||
AppUtil.postEventOnUi(
|
||||
DownloadedAttachmentEvent(
|
||||
Status.SUCCESS, filenameInCache, attachmentUri, attachment.attachmentId, messageId, false
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Timber.w("handleSingleAttachment failure")
|
||||
AppUtil.postEventOnUi(
|
||||
DownloadedAttachmentEvent(
|
||||
Status.FAILED, filenameInCache, null, attachment.attachmentId, messageId, false
|
||||
)
|
||||
)
|
||||
return Result.failure()
|
||||
}
|
||||
|
||||
AttachmentClearingService.startRegularClearUpService() // TODO don't call it every time we download attachments
|
||||
return Result.success()
|
||||
}
|
||||
|
||||
suspend fun download(attachment: Attachment, filename: String, crypto: AddressCrypto) {
|
||||
private suspend fun downloadAttachment(attachment: Attachment, filename: String, crypto: AddressCrypto): Uri? =
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||
downloadQ(attachment, filename, crypto)
|
||||
downloadAttachmentForAndroidQ(attachment, filename, crypto)
|
||||
} else {
|
||||
downloadLegacy(attachment, filename, crypto)
|
||||
downloadAttachmentBeforeQ(attachment, filename, crypto)
|
||||
}
|
||||
|
||||
val attachmentMetadata = AttachmentMetadata(
|
||||
attachment.attachmentId!!,
|
||||
attachment.fileName!!,
|
||||
attachment.fileSize,
|
||||
attachment.messageId + "/" + attachment.attachmentId + "/" + filename,
|
||||
attachment.messageId, System.currentTimeMillis()
|
||||
)
|
||||
attachmentMetadataDatabase.insertAttachmentMetadata(attachmentMetadata)
|
||||
}
|
||||
|
||||
@TargetApi(Build.VERSION_CODES.Q)
|
||||
private suspend fun downloadQ(
|
||||
private suspend fun downloadAttachmentForAndroidQ(
|
||||
attachment: Attachment,
|
||||
filename: String,
|
||||
crypto: AddressCrypto
|
||||
|
@ -287,7 +245,7 @@ class DownloadEmbeddedAttachmentsWorker @WorkerInject constructor(
|
|||
return@withContext uri
|
||||
}
|
||||
|
||||
private suspend fun downloadLegacy(
|
||||
private suspend fun downloadAttachmentBeforeQ(
|
||||
attachment: Attachment,
|
||||
filename: String,
|
||||
crypto: AddressCrypto
|
||||
|
|
|
@ -411,7 +411,7 @@ public class ProtonMailApplication extends Application implements androidx.work.
|
|||
public void onDownloadAttachmentEvent(DownloadedAttachmentEvent event) {
|
||||
final Status status = event.getStatus();
|
||||
if (status != Status.FAILED) {
|
||||
DownloadUtils.viewAttachment(this, event.getFilename(), !event.isOfflineLoaded());
|
||||
DownloadUtils.viewAttachment(this, event.getFilename(), event.getAttachmentUri(), !event.isOfflineLoaded());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -19,17 +19,31 @@
|
|||
package ch.protonmail.android.events;
|
||||
|
||||
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
public class DownloadedAttachmentEvent {
|
||||
|
||||
private final Status status;
|
||||
private final String filename;
|
||||
private final Uri attachmentUri;
|
||||
private final String attachmentId;
|
||||
private final String messageId;
|
||||
private final boolean offlineLoaded;
|
||||
|
||||
public DownloadedAttachmentEvent(Status status, String filename, String attachmentId, String messageId, boolean offlineLoaded){
|
||||
public DownloadedAttachmentEvent(
|
||||
Status status,
|
||||
@NonNull String filename,
|
||||
@Nullable Uri attachmentUri,
|
||||
String attachmentId,
|
||||
String messageId,
|
||||
boolean offlineLoaded
|
||||
){
|
||||
this.status = status;
|
||||
this.filename = filename;
|
||||
this.attachmentUri = attachmentUri;
|
||||
this.attachmentId = attachmentId;
|
||||
this.messageId = messageId;
|
||||
this.offlineLoaded = offlineLoaded;
|
||||
|
@ -39,10 +53,16 @@ public class DownloadedAttachmentEvent {
|
|||
return status;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
public String getFilename(){
|
||||
return filename;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Uri getAttachmentUri(){
|
||||
return attachmentUri;
|
||||
}
|
||||
|
||||
public String getAttachmentId() {
|
||||
return attachmentId;
|
||||
}
|
||||
|
|
|
@ -1,18 +1,18 @@
|
|||
/*
|
||||
* Copyright (c) 2020 Proton Technologies AG
|
||||
*
|
||||
*
|
||||
* This file is part of ProtonMail.
|
||||
*
|
||||
*
|
||||
* ProtonMail is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
*
|
||||
* ProtonMail is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with ProtonMail. If not, see https://www.gnu.org/licenses/.
|
||||
*/
|
||||
|
@ -25,10 +25,10 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.net.Uri;
|
||||
import android.os.Environment;
|
||||
import android.text.TextUtils;
|
||||
import android.webkit.MimeTypeMap;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.content.FileProvider;
|
||||
|
||||
import java.io.File;
|
||||
|
@ -40,68 +40,61 @@ import timber.log.Timber;
|
|||
|
||||
public class DownloadUtils {
|
||||
|
||||
public static void viewAttachment(Context context, String filename) {
|
||||
String ext = filename.substring(filename.lastIndexOf(".") + 1);
|
||||
filename = filename.replace(filename.substring(filename.lastIndexOf(".") + 1), ext.toLowerCase());
|
||||
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + Constants.DIR_ATTACHMENT_DOWNLOADS, filename);
|
||||
Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", file);
|
||||
String mimeType = "";
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
public static void viewAttachment(Context context, String filename, @Nullable Uri uri) {
|
||||
if (uri != null) {
|
||||
String mimeType = "";
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||
mimeType = resolver.getType(uri);
|
||||
Cursor cursor = resolver.query(uri, null, null, null, null);
|
||||
cursor.close();
|
||||
} else if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(filename);
|
||||
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
|
||||
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||
mimeType = resolver.getType(uri);
|
||||
Cursor cursor = resolver.query(uri, null, null, null, null);
|
||||
cursor.close();
|
||||
} else if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
||||
String extension = MimeTypeMap.getFileExtensionFromUrl(file.getName());
|
||||
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
|
||||
if (mimeType == null) {
|
||||
mimeType = Constants.MIME_TYPE_UNKNOWN_FILE;
|
||||
if (mimeType == null) {
|
||||
mimeType = Constants.MIME_TYPE_UNKNOWN_FILE;
|
||||
}
|
||||
}
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setType(mimeType);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.setDataAndType(uri, mimeType);
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException notFoundException) {
|
||||
Timber.i(notFoundException, "Unable to view attachment");
|
||||
}
|
||||
}
|
||||
|
||||
Intent intent = new Intent(Intent.ACTION_VIEW);
|
||||
intent.setType(mimeType);
|
||||
intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
intent.setDataAndType(uri, mimeType);
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Timber.i(e);
|
||||
}
|
||||
}
|
||||
|
||||
public static void viewAttachment(Context context, String filename, boolean showNotification) {
|
||||
String ext = filename.substring(filename.lastIndexOf(".") + 1);
|
||||
filename = filename.replace(filename.substring(filename.lastIndexOf(".") + 1), ext.toLowerCase());
|
||||
File file = new File(context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS) + Constants.DIR_ATTACHMENT_DOWNLOADS, filename);
|
||||
Uri uri = FileProvider.getUriForFile(context, context.getApplicationContext().getPackageName() + ".provider", file);
|
||||
String mimeType = "";
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
public static void viewAttachment(Context context, String fileName, @Nullable Uri uri, boolean showNotification) {
|
||||
if (uri != null) {
|
||||
String mimeType = "";
|
||||
final ContentResolver resolver = context.getContentResolver();
|
||||
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||
mimeType = resolver.getType(uri);
|
||||
Cursor cursor = resolver.query(uri, null, null, null, null);
|
||||
cursor.close();
|
||||
} else if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
||||
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
if (!TextUtils.isEmpty(extension)) {
|
||||
extension = extension.toLowerCase();
|
||||
}
|
||||
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
|
||||
if (ContentResolver.SCHEME_CONTENT.equals(uri.getScheme())) {
|
||||
mimeType = resolver.getType(uri);
|
||||
Cursor cursor = resolver.query(uri, null, null, null, null);
|
||||
cursor.close();
|
||||
} else if (ContentResolver.SCHEME_FILE.equals(uri.getScheme())) {
|
||||
String fileName = file.getName();
|
||||
String extension = fileName.substring(fileName.lastIndexOf(".") + 1);
|
||||
if (!TextUtils.isEmpty(extension)) {
|
||||
extension = extension.toLowerCase();
|
||||
if (mimeType == null) {
|
||||
mimeType = Constants.MIME_TYPE_UNKNOWN_FILE;
|
||||
}
|
||||
}
|
||||
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension.toLowerCase());
|
||||
|
||||
if (mimeType == null) {
|
||||
mimeType = Constants.MIME_TYPE_UNKNOWN_FILE;
|
||||
}
|
||||
NotificationManager notifyManager = (NotificationManager) context.getSystemService(
|
||||
Context.NOTIFICATION_SERVICE);
|
||||
INotificationServer notificationServer = new NotificationServer(context, notifyManager);
|
||||
notificationServer.notifyAboutAttachment(fileName, uri, mimeType, showNotification);
|
||||
}
|
||||
NotificationManager notifyManager = (NotificationManager) context.getSystemService(
|
||||
Context.NOTIFICATION_SERVICE);
|
||||
INotificationServer notificationServer = new NotificationServer(context, notifyManager);
|
||||
notificationServer.notifyAboutAttachment(filename, uri, mimeType, showNotification);
|
||||
}
|
||||
|
||||
public static void viewCachedAttachmentFile(Context context, String filename, String localLocation) {
|
||||
|
@ -132,8 +125,8 @@ public class DownloadUtils {
|
|||
|
||||
try {
|
||||
context.startActivity(intent);
|
||||
} catch (ActivityNotFoundException e) {
|
||||
Timber.i(e);
|
||||
} catch (ActivityNotFoundException notFoundException) {
|
||||
Timber.i(notFoundException, "Unable to view the file");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue