use new storage location for backup and recordings
This commit is contained in:
parent
60617618b8
commit
8abacd23e8
|
@ -128,16 +128,19 @@ public class ImportBackupService extends Service {
|
||||||
final List<Jid> accounts = mDatabaseBackend.getAccountJids(false);
|
final List<Jid> accounts = mDatabaseBackend.getAccountJids(false);
|
||||||
final ArrayList<BackupFile> backupFiles = new ArrayList<>();
|
final ArrayList<BackupFile> backupFiles = new ArrayList<>();
|
||||||
final Set<String> apps = new HashSet<>(Arrays.asList("Conversations", "Quicksy", getString(R.string.app_name)));
|
final Set<String> apps = new HashSet<>(Arrays.asList("Conversations", "Quicksy", getString(R.string.app_name)));
|
||||||
for (String app : apps) {
|
final List<File> directories = new ArrayList<>();
|
||||||
final File directory = new File(FileBackend.getBackupDirectory(app));
|
for (final String app : apps) {
|
||||||
|
directories.add(FileBackend.getLegacyBackupDirectory(app));
|
||||||
|
}
|
||||||
|
directories.add(FileBackend.getBackupDirectory(this));
|
||||||
|
for (final File directory : directories) {
|
||||||
if (!directory.exists() || !directory.isDirectory()) {
|
if (!directory.exists() || !directory.isDirectory()) {
|
||||||
Log.d(Config.LOGTAG, "directory not found: " + directory.getAbsolutePath());
|
Log.d(Config.LOGTAG, "directory not found: " + directory.getAbsolutePath());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
final File[] files = directory.listFiles();
|
final File[] files = directory.listFiles();
|
||||||
if (files == null) {
|
if (files == null) {
|
||||||
onBackupFilesLoaded.onBackupFilesLoaded(backupFiles);
|
continue;
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
for (final File file : files) {
|
for (final File file : files) {
|
||||||
if (file.isFile() && file.getName().endsWith(".ceb")) {
|
if (file.isFile() && file.getName().endsWith(".ceb")) {
|
||||||
|
|
|
@ -64,7 +64,6 @@ 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.RecordingActivity;
|
|
||||||
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;
|
||||||
|
@ -88,19 +87,6 @@ public class FileBackend {
|
||||||
this.mXmppConnectionService = service;
|
this.mXmppConnectionService = service;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static boolean isInDirectoryThatShouldNotBeScanned(Context context, File file) {
|
|
||||||
return isInDirectoryThatShouldNotBeScanned(context, file.getAbsolutePath());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static boolean isInDirectoryThatShouldNotBeScanned(Context context, String path) {
|
|
||||||
for (String type : new String[] {RecordingActivity.STORAGE_DIRECTORY_TYPE_NAME, "Files"}) {
|
|
||||||
if (path.startsWith(getLegacyStorageLocation(context, type).getAbsolutePath())) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static long getFileSize(Context context, Uri uri) {
|
public static long getFileSize(Context context, Uri uri) {
|
||||||
try {
|
try {
|
||||||
final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
|
final Cursor cursor = context.getContentResolver().query(uri, null, null, null, null);
|
||||||
|
@ -156,34 +142,18 @@ public class FileBackend {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static File getLegacyStorageLocation(Context context, final String type) {
|
public static File getBackupDirectory(final Context context) {
|
||||||
if (Config.ONLY_INTERNAL_STORAGE) {
|
final File conversationsDownloadDirectory =
|
||||||
return new File(context.getFilesDir(), type);
|
new File(
|
||||||
} else {
|
Environment.getExternalStoragePublicDirectory(
|
||||||
final File appDirectory =
|
Environment.DIRECTORY_DOWNLOADS),
|
||||||
new File(
|
context.getString(R.string.app_name));
|
||||||
Environment.getExternalStorageDirectory(),
|
return new File(conversationsDownloadDirectory, "Backup");
|
||||||
context.getString(R.string.app_name));
|
|
||||||
final File appMediaDirectory = new File(appDirectory, "Media");
|
|
||||||
final String locationName =
|
|
||||||
String.format("%s %s", context.getString(R.string.app_name), type);
|
|
||||||
return new File(appMediaDirectory, locationName);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static String getAppMediaDirectory(Context context) {
|
public static File getLegacyBackupDirectory(final String app) {
|
||||||
return Environment.getExternalStorageDirectory().getAbsolutePath()
|
final File appDirectory = new File(Environment.getExternalStorageDirectory(), app);
|
||||||
+ "/"
|
return new File(appDirectory, "Backup");
|
||||||
+ context.getString(R.string.app_name)
|
|
||||||
+ "/Media/";
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getBackupDirectory(Context context) {
|
|
||||||
return getBackupDirectory(context.getString(R.string.app_name));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static String getBackupDirectory(String app) {
|
|
||||||
return Environment.getExternalStorageDirectory().getAbsolutePath() + "/" + app + "/Backup/";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Bitmap rotate(final Bitmap bitmap, final int degree) {
|
private static Bitmap rotate(final Bitmap bitmap, final int degree) {
|
||||||
|
@ -521,38 +491,26 @@ public class FileBackend {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateMediaScanner(File file, final Runnable callback) {
|
public void updateMediaScanner(File file, final Runnable callback) {
|
||||||
if (!isInDirectoryThatShouldNotBeScanned(mXmppConnectionService, file)) {
|
MediaScannerConnection.scanFile(
|
||||||
MediaScannerConnection.scanFile(
|
mXmppConnectionService,
|
||||||
mXmppConnectionService,
|
new String[] {file.getAbsolutePath()},
|
||||||
new String[] {file.getAbsolutePath()},
|
null,
|
||||||
null,
|
new MediaScannerConnection.MediaScannerConnectionClient() {
|
||||||
new MediaScannerConnection.MediaScannerConnectionClient() {
|
@Override
|
||||||
@Override
|
public void onMediaScannerConnected() {}
|
||||||
public void onMediaScannerConnected() {}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onScanCompleted(String path, Uri uri) {
|
public void onScanCompleted(String path, Uri uri) {
|
||||||
if (callback != null && file.getAbsolutePath().equals(path)) {
|
if (callback != null && file.getAbsolutePath().equals(path)) {
|
||||||
|
callback.run();
|
||||||
|
} else {
|
||||||
|
Log.d(Config.LOGTAG, "media scanner scanned wrong file");
|
||||||
|
if (callback != null) {
|
||||||
callback.run();
|
callback.run();
|
||||||
} else {
|
|
||||||
Log.d(Config.LOGTAG, "media scanner scanned wrong file");
|
|
||||||
if (callback != null) {
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
return;
|
});
|
||||||
/*Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
|
|
||||||
intent.setData(Uri.fromFile(file));
|
|
||||||
mXmppConnectionService.sendBroadcast(intent);*/
|
|
||||||
} else if (file.getAbsolutePath()
|
|
||||||
.startsWith(getAppMediaDirectory(mXmppConnectionService))) {
|
|
||||||
createNoMedia(file.getParentFile());
|
|
||||||
}
|
|
||||||
if (callback != null) {
|
|
||||||
callback.run();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean deleteFile(Message message) {
|
public boolean deleteFile(Message message) {
|
||||||
|
@ -629,9 +587,20 @@ public class FileBackend {
|
||||||
return attachments;
|
return attachments;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO remove static method. use direct instance access
|
|
||||||
private File getLegacyStorageLocation(final String type) {
|
private File getLegacyStorageLocation(final String type) {
|
||||||
return getLegacyStorageLocation(mXmppConnectionService, type);
|
if (Config.ONLY_INTERNAL_STORAGE) {
|
||||||
|
return new File(mXmppConnectionService.getFilesDir(), type);
|
||||||
|
} else {
|
||||||
|
final File appDirectory =
|
||||||
|
new File(
|
||||||
|
Environment.getExternalStorageDirectory(),
|
||||||
|
mXmppConnectionService.getString(R.string.app_name));
|
||||||
|
final File appMediaDirectory = new File(appDirectory, "Media");
|
||||||
|
final String locationName =
|
||||||
|
String.format(
|
||||||
|
"%s %s", mXmppConnectionService.getString(R.string.app_name), type);
|
||||||
|
return new File(appMediaDirectory, locationName);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Bitmap resize(final Bitmap originalBitmap, int size) throws IOException {
|
private Bitmap resize(final Bitmap originalBitmap, int size) throws IOException {
|
||||||
|
|
|
@ -291,7 +291,7 @@ public class ExportBackupService extends Service {
|
||||||
secureRandom.nextBytes(salt);
|
secureRandom.nextBytes(salt);
|
||||||
final BackupFileHeader backupFileHeader = new BackupFileHeader(getString(R.string.app_name), account.getJid(), System.currentTimeMillis(), IV, salt);
|
final BackupFileHeader backupFileHeader = new BackupFileHeader(getString(R.string.app_name), account.getJid(), System.currentTimeMillis(), IV, salt);
|
||||||
final Progress progress = new Progress(mBuilder, max, count);
|
final Progress progress = new Progress(mBuilder, max, count);
|
||||||
final File file = new File(FileBackend.getBackupDirectory(this) + account.getJid().asBareJid().toEscapedString() + ".ceb");
|
final File file = new File(FileBackend.getBackupDirectory(this), account.getJid().asBareJid().toEscapedString() + ".ceb");
|
||||||
files.add(file);
|
files.add(file);
|
||||||
final File directory = file.getParentFile();
|
final File directory = file.getParentFile();
|
||||||
if (directory != null && directory.mkdirs()) {
|
if (directory != null && directory.mkdirs()) {
|
||||||
|
@ -335,7 +335,7 @@ public class ExportBackupService extends Service {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void notifySuccess(final List<File> files) {
|
private void notifySuccess(final List<File> files) {
|
||||||
final String path = FileBackend.getBackupDirectory(this);
|
final String path = FileBackend.getBackupDirectory(this).getAbsolutePath();
|
||||||
|
|
||||||
PendingIntent openFolderIntent = null;
|
PendingIntent openFolderIntent = null;
|
||||||
|
|
||||||
|
@ -363,7 +363,7 @@ public class ExportBackupService extends Service {
|
||||||
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext(), "backup");
|
NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(getBaseContext(), "backup");
|
||||||
mBuilder.setContentTitle(getString(R.string.notification_backup_created_title))
|
mBuilder.setContentTitle(getString(R.string.notification_backup_created_title))
|
||||||
.setContentText(getString(R.string.notification_backup_created_subtitle, path))
|
.setContentText(getString(R.string.notification_backup_created_subtitle, path))
|
||||||
.setStyle(new NotificationCompat.BigTextStyle().bigText(getString(R.string.notification_backup_created_subtitle, FileBackend.getBackupDirectory(this))))
|
.setStyle(new NotificationCompat.BigTextStyle().bigText(getString(R.string.notification_backup_created_subtitle, FileBackend.getBackupDirectory(this).getAbsolutePath())))
|
||||||
.setAutoCancel(true)
|
.setAutoCancel(true)
|
||||||
.setContentIntent(openFolderIntent)
|
.setContentIntent(openFolderIntent)
|
||||||
.setSmallIcon(R.drawable.ic_archive_white_24dp);
|
.setSmallIcon(R.drawable.ic_archive_white_24dp);
|
||||||
|
|
|
@ -1183,8 +1183,8 @@ public class ConversationFragment extends XmppFragment implements EditMessage.Ke
|
||||||
cancelTransmission.setVisible(true);
|
cancelTransmission.setVisible(true);
|
||||||
}
|
}
|
||||||
if (m.isFileOrImage() && !deleted && !cancelable) {
|
if (m.isFileOrImage() && !deleted && !cancelable) {
|
||||||
String path = m.getRelativeFilePath();
|
final String path = m.getRelativeFilePath();
|
||||||
if (path == null || !path.startsWith("/") || FileBackend.isInDirectoryThatShouldNotBeScanned(getActivity(), path)) {
|
if (path == null || !path.startsWith("/")) {
|
||||||
deleteFile.setVisible(true);
|
deleteFile.setVisible(true);
|
||||||
deleteFile.setTitle(activity.getString(R.string.delete_x_file, UIHelper.getFileDescriptionString(activity, m)));
|
deleteFile.setTitle(activity.getString(R.string.delete_x_file, UIHelper.getFileDescriptionString(activity, m)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import android.content.Intent;
|
||||||
import android.media.MediaRecorder;
|
import android.media.MediaRecorder;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.os.Environment;
|
||||||
import android.os.FileObserver;
|
import android.os.FileObserver;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.SystemClock;
|
import android.os.SystemClock;
|
||||||
|
@ -153,28 +154,21 @@ public class RecordingActivity extends Activity implements View.OnClickListener
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static File generateOutputFilename(Context context) {
|
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";
|
||||||
return new File(FileBackend.getLegacyStorageLocation(context, STORAGE_DIRECTORY_TYPE_NAME), filename);
|
//TODO once we target 31 use DIRECTORY_RECORDINGS
|
||||||
|
final File parentDirectory = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS);
|
||||||
|
final File conversationsDirectory = new File(parentDirectory, getString(R.string.app_name));
|
||||||
|
return new File(conversationsDirectory, filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setupOutputFile() {
|
private void setupOutputFile() {
|
||||||
mOutputFile = generateOutputFilename(this);
|
mOutputFile = generateOutputFilename();
|
||||||
File parentDirectory = mOutputFile.getParentFile();
|
final File parentDirectory = mOutputFile.getParentFile();
|
||||||
if (parentDirectory.mkdirs()) {
|
if (parentDirectory.mkdirs()) {
|
||||||
Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath());
|
Log.d(Config.LOGTAG, "created " + parentDirectory.getAbsolutePath());
|
||||||
}
|
}
|
||||||
File noMedia = new File(parentDirectory, ".nomedia");
|
|
||||||
if (!noMedia.exists()) {
|
|
||||||
try {
|
|
||||||
if (noMedia.createNewFile()) {
|
|
||||||
Log.d(Config.LOGTAG, "created nomedia file in " + parentDirectory.getAbsolutePath());
|
|
||||||
}
|
|
||||||
} catch (IOException e) {
|
|
||||||
Log.d(Config.LOGTAG, "unable to create nomedia file in " + parentDirectory.getAbsolutePath(), e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
setupFileObserver(parentDirectory);
|
setupFileObserver(parentDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -224,7 +224,7 @@ public class SettingsActivity extends XmppActivity implements
|
||||||
|
|
||||||
final Preference createBackupPreference = mSettingsFragment.findPreference("create_backup");
|
final Preference createBackupPreference = mSettingsFragment.findPreference("create_backup");
|
||||||
if (createBackupPreference != null) {
|
if (createBackupPreference != null) {
|
||||||
createBackupPreference.setSummary(getString(R.string.pref_create_backup_summary, FileBackend.getBackupDirectory(this)));
|
createBackupPreference.setSummary(getString(R.string.pref_create_backup_summary, FileBackend.getBackupDirectory(this).getAbsolutePath()));
|
||||||
createBackupPreference.setOnPreferenceClickListener(preference -> {
|
createBackupPreference.setOnPreferenceClickListener(preference -> {
|
||||||
if (hasStoragePermission(REQUEST_CREATE_BACKUP)) {
|
if (hasStoragePermission(REQUEST_CREATE_BACKUP)) {
|
||||||
createBackup();
|
createBackup();
|
||||||
|
|
Loading…
Reference in a new issue