Merge pull request #1212 from nextcloud/pdfByIntent

Open files by external Apps
This commit is contained in:
Marcel Hibbe 2021-05-03 21:51:52 +02:00 committed by GitHub
commit 6c7591ebef
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 81 additions and 44 deletions

View File

@ -8,6 +8,7 @@ Types of changes can be: Added/Changed/Deprecated/Removed/Fixed/Security
## [UNRELEASED] ## [UNRELEASED]
### Added ### Added
- open files inside app (jpg, .png, .gif, .mp3, .mp4, .mov, .wav, .txt, .md) - open files inside app (jpg, .png, .gif, .mp3, .mp4, .mov, .wav, .txt, .md)
- other data types are opened with external apps if they are able to handle it
- edit profile information and privacy settings - edit profile information and privacy settings
### Changed ### Changed

View File

@ -29,11 +29,13 @@ import android.content.Intent;
import android.graphics.drawable.Drawable; import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable; import android.graphics.drawable.LayerDrawable;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Handler; import android.os.Handler;
import android.util.Log; import android.util.Log;
import android.view.Gravity; import android.view.Gravity;
import android.view.View; import android.view.View;
import android.widget.PopupMenu; import android.widget.PopupMenu;
import android.widget.Toast;
import com.google.common.util.concurrent.ListenableFuture; import com.google.common.util.concurrent.ListenableFuture;
import com.nextcloud.talk.R; import com.nextcloud.talk.R;
@ -61,6 +63,7 @@ import java.util.concurrent.ExecutionException;
import javax.inject.Inject; import javax.inject.Inject;
import androidx.core.content.ContextCompat; import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.emoji.widget.EmojiTextView; import androidx.emoji.widget.EmojiTextView;
import androidx.work.Data; import androidx.work.Data;
import androidx.work.OneTimeWorkRequest; import androidx.work.OneTimeWorkRequest;
@ -143,7 +146,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
image.setOnClickListener(v -> { image.setOnClickListener(v -> {
String mimetype = message.getSelectedIndividualHashMap().get("mimetype"); String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
if (isSupportedMimetype(mimetype)) { if (isSupportedForInternalViewer(mimetype) || canBeHandledByExternalApp(mimetype, fileName)) {
openOrDownloadFile(message); openOrDownloadFile(message);
} else { } else {
openFileInFilesApp(message, accountString); openFileInFilesApp(message, accountString);
@ -195,7 +198,18 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
} }
} }
public boolean isSupportedMimetype(String mimetype){ private void openOrDownloadFile(ChatMessage message) {
String filename = message.getSelectedIndividualHashMap().get("name");
String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
File file = new File(context.getCacheDir(), filename);
if (file.exists()) {
openFile(filename, mimetype);
} else {
downloadFileToCache(message);
}
}
public boolean isSupportedForInternalViewer(String mimetype){
switch (mimetype) { switch (mimetype) {
case "image/png": case "image/png":
case "image/jpeg": case "image/jpeg":
@ -214,35 +228,6 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
} }
} }
private void openOrDownloadFile(ChatMessage message) {
String filename = message.getSelectedIndividualHashMap().get("name");
String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
File file = new File(context.getCacheDir(), filename);
if (file.exists()) {
openFile(filename, mimetype);
} else {
String size = message.getSelectedIndividualHashMap().get("size");
if (size == null) {
size = "-1";
}
Integer fileSize = Integer.valueOf(size);
String fileId = message.getSelectedIndividualHashMap().get("id");
String path = message.getSelectedIndividualHashMap().get("path");
downloadFileToCache(
message.activeUser.getBaseUrl(),
message.activeUser.getUserId(),
message.activeUser.getAttachmentFolder(),
filename,
path,
mimetype,
fileSize,
fileId
);
}
}
private void openFile(String filename, String mimetype) { private void openFile(String filename, String mimetype) {
switch (mimetype) { switch (mimetype) {
case "audio/mpeg": case "audio/mpeg":
@ -263,10 +248,50 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
openTextView(filename, mimetype); openTextView(filename, mimetype);
break; break;
default: default:
Log.w(TAG, "no method defined for mimetype: " + mimetype); openFileByExternalApp(filename, mimetype);
} }
} }
private void openFileByExternalApp(String fileName, String mimetype) {
String path = context.getCacheDir().getAbsolutePath() + "/" + fileName;
File file = new File(path);
Intent intent;
if (Build.VERSION.SDK_INT < 24) {
intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), mimetype);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
} else {
intent = new Intent();
intent.setAction(Intent.ACTION_VIEW);
Uri pdfURI = FileProvider.getUriForFile(context, context.getPackageName(), file);
intent.setDataAndType(pdfURI, mimetype);
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
try {
if (intent.resolveActivity(context.getPackageManager()) != null) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
} else {
Log.e(TAG, "No Application found to open the file. This should have been handled beforehand!");
}
} catch (Exception e) {
Log.e(TAG, "Error while opening file", e);
}
}
private boolean canBeHandledByExternalApp(String mimetype, String fileName) {
String path = context.getCacheDir().getAbsolutePath() + "/" + fileName;
File file = new File(path);
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setDataAndType(Uri.fromFile(file), mimetype);
// TODO resolveActivity might need more permissions starting with android 11 (api 30)
// https://developer.android.com/about/versions/11/privacy/package-visibility
return intent.resolveActivity(context.getPackageManager()) != null;
}
private void openImageView(String filename, String mimetype) { private void openImageView(String filename, String mimetype) {
Intent fullScreenImageIntent = new Intent(context, FullScreenImageActivity.class); Intent fullScreenImageIntent = new Intent(context, FullScreenImageActivity.class);
fullScreenImageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); fullScreenImageIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
@ -293,7 +318,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
} }
private void onMessageViewLongClick(ChatMessage message, String accountString) { private void onMessageViewLongClick(ChatMessage message, String accountString) {
if (isSupportedMimetype(message.getSelectedIndividualHashMap().get("mimetype"))) { if (isSupportedForInternalViewer(message.getSelectedIndividualHashMap().get("mimetype"))) {
return; return;
} }
@ -309,14 +334,24 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
} }
@SuppressLint("LongLogTag") @SuppressLint("LongLogTag")
private void downloadFileToCache(String baseUrl, private void downloadFileToCache(ChatMessage message) {
String userId,
String attachmentFolder, String baseUrl = message.activeUser.getBaseUrl();
String fileName, String userId = message.activeUser.getUserId();
String path, String attachmentFolder = message.activeUser.getAttachmentFolder();
String mimetype,
Integer size, String fileName = message.getSelectedIndividualHashMap().get("name");
String fileId) { String mimetype = message.getSelectedIndividualHashMap().get("mimetype");
String size = message.getSelectedIndividualHashMap().get("size");
if (size == null) {
size = "-1";
}
Integer fileSize = Integer.valueOf(size);
String fileId = message.getSelectedIndividualHashMap().get("id");
String path = message.getSelectedIndividualHashMap().get("path");
// check if download worker is already running // check if download worker is already running
ListenableFuture<List<WorkInfo>> workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId); ListenableFuture<List<WorkInfo>> workers = WorkManager.getInstance(context).getWorkInfosByTag(fileId);
@ -342,7 +377,7 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
.putString(DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER, attachmentFolder) .putString(DownloadFileToCacheWorker.KEY_ATTACHMENT_FOLDER, attachmentFolder)
.putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileName) .putString(DownloadFileToCacheWorker.KEY_FILE_NAME, fileName)
.putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path) .putString(DownloadFileToCacheWorker.KEY_FILE_PATH, path)
.putInt(DownloadFileToCacheWorker.KEY_FILE_SIZE, size) .putInt(DownloadFileToCacheWorker.KEY_FILE_SIZE, fileSize)
.build(); .build();
downloadWorker = new OneTimeWorkRequest.Builder(DownloadFileToCacheWorker.class) downloadWorker = new OneTimeWorkRequest.Builder(DownloadFileToCacheWorker.class)
@ -372,7 +407,8 @@ public class MagicPreviewMessageViewHolder extends MessageHolders.IncomingImageM
if (image.isShown()) { if (image.isShown()) {
openFile(fileName, mimetype); openFile(fileName, mimetype);
} else { } else {
Log.d(TAG, "image " + fileName + " was downloaded but it's not opened (view is not shown)"); Log.d(TAG, "file " + fileName + " was downloaded but it's not opened because view is not shown on" +
" screen");
} }
messageText.setText(fileName); messageText.setText(fileName);
progressBar.setVisibility(View.GONE); progressBar.setVisibility(View.GONE);

View File

@ -23,6 +23,6 @@
name="files" name="files"
path="/" /> path="/" />
<cache-path <cache-path
name="cachedFiles" name="cache"
path="/" /> path="/" />
</paths> </paths>