store recordings and documents in their respective folders

This commit is contained in:
Daniel Gultsch 2022-02-23 09:40:38 +01:00
parent c03a8b784f
commit 0b470534f1
4 changed files with 61 additions and 39 deletions

View file

@ -87,7 +87,7 @@ ext {
} }
android { android {
compileSdkVersion 30 compileSdkVersion 31
defaultConfig { defaultConfig {
minSdkVersion 21 minSdkVersion 21

View file

@ -64,6 +64,7 @@ import eu.siacs.conversations.entities.DownloadableFile;
import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.entities.Message;
import eu.siacs.conversations.services.AttachFileToConversationRunnable; import eu.siacs.conversations.services.AttachFileToConversationRunnable;
import eu.siacs.conversations.services.XmppConnectionService; import eu.siacs.conversations.services.XmppConnectionService;
import eu.siacs.conversations.ui.adapter.MediaAdapter;
import eu.siacs.conversations.ui.util.Attachment; import eu.siacs.conversations.ui.util.Attachment;
import eu.siacs.conversations.utils.Compatibility; import eu.siacs.conversations.utils.Compatibility;
import eu.siacs.conversations.utils.CryptoHelper; import eu.siacs.conversations.utils.CryptoHelper;
@ -888,6 +889,9 @@ public class FileBackend {
} else if (mime.startsWith("video/")) { } else if (mime.startsWith("video/")) {
parentDirectory = parentDirectory =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES); Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES);
} else if (MediaAdapter.DOCUMENT_MIMES.contains(mime)) {
parentDirectory =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS);
} else { } else {
parentDirectory = parentDirectory =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);

View file

@ -1,10 +1,10 @@
package eu.siacs.conversations.ui; package eu.siacs.conversations.ui;
import android.app.Activity; import android.app.Activity;
import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.media.MediaRecorder; import android.media.MediaRecorder;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.os.Bundle; import android.os.Bundle;
import android.os.Environment; import android.os.Environment;
import android.os.FileObserver; import android.os.FileObserver;
@ -18,25 +18,22 @@ import android.widget.Toast;
import androidx.databinding.DataBindingUtil; import androidx.databinding.DataBindingUtil;
import java.io.File; import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat; import java.text.SimpleDateFormat;
import java.util.Date; import java.util.Date;
import java.util.Locale; import java.util.Locale;
import java.util.Objects;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import eu.siacs.conversations.Config; import eu.siacs.conversations.Config;
import eu.siacs.conversations.R; import eu.siacs.conversations.R;
import eu.siacs.conversations.databinding.ActivityRecordingBinding; import eu.siacs.conversations.databinding.ActivityRecordingBinding;
import eu.siacs.conversations.persistance.FileBackend;
import eu.siacs.conversations.ui.util.SettingsUtils; import eu.siacs.conversations.ui.util.SettingsUtils;
import eu.siacs.conversations.utils.ThemeHelper; import eu.siacs.conversations.utils.ThemeHelper;
import eu.siacs.conversations.utils.TimeFrameUtils; import eu.siacs.conversations.utils.TimeFrameUtils;
public class RecordingActivity extends Activity implements View.OnClickListener { public class RecordingActivity extends Activity implements View.OnClickListener {
public static String STORAGE_DIRECTORY_TYPE_NAME = "Recordings";
private ActivityRecordingBinding binding; private ActivityRecordingBinding binding;
private MediaRecorder mRecorder; private MediaRecorder mRecorder;
@ -45,13 +42,14 @@ public class RecordingActivity extends Activity implements View.OnClickListener
private final CountDownLatch outputFileWrittenLatch = new CountDownLatch(1); private final CountDownLatch outputFileWrittenLatch = new CountDownLatch(1);
private final Handler mHandler = new Handler(); private final Handler mHandler = new Handler();
private final Runnable mTickExecutor = new Runnable() { private final Runnable mTickExecutor =
@Override new Runnable() {
public void run() { @Override
tick(); public void run() {
mHandler.postDelayed(mTickExecutor, 100); tick();
} mHandler.postDelayed(mTickExecutor, 100);
}; }
};
private File mOutputFile; private File mOutputFile;
@ -69,7 +67,7 @@ public class RecordingActivity extends Activity implements View.OnClickListener
} }
@Override @Override
protected void onResume(){ protected void onResume() {
super.onResume(); super.onResume();
SettingsUtils.applyScreenshotPreventionSetting(this); SettingsUtils.applyScreenshotPreventionSetting(this);
} }
@ -138,27 +136,44 @@ public class RecordingActivity extends Activity implements View.OnClickListener
} }
} }
if (saveFile) { if (saveFile) {
new Thread(() -> { new Thread(
try { () -> {
if (!outputFileWrittenLatch.await(2, TimeUnit.SECONDS)) { try {
Log.d(Config.LOGTAG, "time out waiting for output file to be written"); if (!outputFileWrittenLatch.await(2, TimeUnit.SECONDS)) {
} Log.d(
} catch (InterruptedException e) { Config.LOGTAG,
Log.d(Config.LOGTAG, "interrupted while waiting for output file to be written", e); "time out waiting for output file to be written");
} }
runOnUiThread(() -> { } catch (InterruptedException e) {
setResult(Activity.RESULT_OK, new Intent().setData(Uri.fromFile(mOutputFile))); Log.d(
finish(); Config.LOGTAG,
}); "interrupted while waiting for output file to be written",
}).start(); e);
}
runOnUiThread(
() -> {
setResult(
Activity.RESULT_OK,
new Intent()
.setData(Uri.fromFile(mOutputFile)));
finish();
});
})
.start();
} }
} }
private File generateOutputFilename() { private File generateOutputFilename() {
final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US); final SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd_HHmmssSSS", Locale.US);
final String filename = "RECORDING_" + dateFormat.format(new Date()) + ".m4a"; final String filename = "RECORDING_" + dateFormat.format(new Date()) + ".m4a";
//TODO once we target 31 use DIRECTORY_RECORDINGS final File parentDirectory;
final File parentDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
parentDirectory =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_RECORDINGS);
} else {
parentDirectory =
Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
}
final File conversationsDirectory = new File(parentDirectory, getString(R.string.app_name)); final File conversationsDirectory = new File(parentDirectory, getString(R.string.app_name));
return new File(conversationsDirectory, filename); return new File(conversationsDirectory, filename);
} }
@ -166,21 +181,24 @@ public class RecordingActivity extends Activity implements View.OnClickListener
private void setupOutputFile() { private void setupOutputFile() {
mOutputFile = generateOutputFilename(); mOutputFile = generateOutputFilename();
final File parentDirectory = mOutputFile.getParentFile(); final File parentDirectory = mOutputFile.getParentFile();
if (parentDirectory.mkdirs()) { if (Objects.requireNonNull(parentDirectory).mkdirs()) {
Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath()); Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath());
} }
setupFileObserver(parentDirectory); setupFileObserver(parentDirectory);
} }
private void setupFileObserver(File directory) { private void setupFileObserver(File directory) {
mFileObserver = new FileObserver(directory.getAbsolutePath()) { mFileObserver =
@Override new FileObserver(directory.getAbsolutePath()) {
public void onEvent(int event, String s) { @Override
if (s != null && s.equals(mOutputFile.getName()) && event == FileObserver.CLOSE_WRITE) { public void onEvent(int event, String s) {
outputFileWrittenLatch.countDown(); if (s != null
} && s.equals(mOutputFile.getName())
} && event == FileObserver.CLOSE_WRITE) {
}; outputFileWrittenLatch.countDown();
}
}
};
mFileObserver.startWatching(); mFileObserver.startWatching();
} }

View file

@ -34,7 +34,7 @@ import eu.siacs.conversations.ui.util.ViewUtil;
public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> { public class MediaAdapter extends RecyclerView.Adapter<MediaAdapter.MediaViewHolder> {
private static final List<String> DOCUMENT_MIMES = Arrays.asList( public static final List<String> DOCUMENT_MIMES = Arrays.asList(
"application/pdf", "application/pdf",
"application/vnd.oasis.opendocument.text", "application/vnd.oasis.opendocument.text",
"application/msword", "application/msword",