Added option to select default folder

pull/212/head
M66B 2 years ago
parent a2aa2d6a51
commit 5cfbeafa82

@ -392,7 +392,7 @@ public class ActivityEML extends ActivityBase {
create.setType(apart.attachment.getMimeType());
if (!TextUtils.isEmpty(apart.attachment.name))
create.putExtra(Intent.EXTRA_TITLE, apart.attachment.name);
Helper.openAdvanced(create);
Helper.openAdvanced(ActivityEML.this, create);
if (create.resolveActivity(getPackageManager()) == null) // system whitelisted
ToastEx.makeText(ActivityEML.this, R.string.title_no_saf, Toast.LENGTH_LONG).show();
else

@ -309,7 +309,7 @@ public class ActivitySignature extends ActivityBase {
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("text/*");
Helper.openAdvanced(intent);
Helper.openAdvanced(ActivitySignature.this, intent);
startActivityForResult(intent, REQUEST_FILE);
}
@ -414,7 +414,7 @@ public class ActivitySignature extends ActivityBase {
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("image/*");
Helper.openAdvanced(intent);
Helper.openAdvanced(ActivitySignature.this, intent);
startActivityForResult(intent, REQUEST_IMAGE);
}

@ -1170,7 +1170,7 @@ public class AdapterFolder extends RecyclerView.Adapter<AdapterFolder.ViewHolder
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, filename);
Helper.openAdvanced(intent);
Helper.openAdvanced(context, intent);
if (intent.resolveActivity(context.getPackageManager()) == null) { // // system/GET_CONTENT whitelisted
ToastEx.makeText(context, R.string.title_no_saf, Toast.LENGTH_LONG).show();

@ -383,7 +383,7 @@ public class FragmentAnswer extends FragmentBase {
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.setType("image/*");
Helper.openAdvanced(intent);
Helper.openAdvanced(getContext(), intent);
startActivityForResult(intent, REQUEST_IMAGE);
}

@ -533,18 +533,20 @@ public class FragmentBase extends Fragment {
getArguments().putLong("selected_attachment", attachment);
Log.i("Save attachment id=" + attachment);
final Context context = getContext();
Intent create = new Intent(Intent.ACTION_CREATE_DOCUMENT);
create.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
create.setType(intent.getStringExtra("type"));
create.putExtra(Intent.EXTRA_TITLE, intent.getStringExtra("name"));
Helper.openAdvanced(create);
PackageManager pm = getContext().getPackageManager();
Helper.openAdvanced(context, create);
PackageManager pm = context.getPackageManager();
if (create.resolveActivity(pm) == null) { // system whitelisted
Log.w("SAF missing");
ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show();
ToastEx.makeText(context, R.string.title_no_saf, Toast.LENGTH_LONG).show();
} else
startActivityForResult(Helper.getChooser(getContext(), create), REQUEST_ATTACHMENT);
startActivityForResult(Helper.getChooser(context, create), REQUEST_ATTACHMENT);
}
private void onStoreAttachments(Intent intent) {
@ -552,14 +554,16 @@ public class FragmentBase extends Fragment {
getArguments().putLong("selected_message", message);
Log.i("Save attachments message=" + message);
final Context context = getContext();
Intent tree = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
Helper.openAdvanced(tree);
PackageManager pm = getContext().getPackageManager();
Helper.openAdvanced(context, tree);
PackageManager pm = context.getPackageManager();
if (tree.resolveActivity(pm) == null) { // system whitelisted
Log.w("SAF missing");
ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show();
ToastEx.makeText(context, R.string.title_no_saf, Toast.LENGTH_LONG).show();
} else
startActivityForResult(Helper.getChooser(getContext(), tree), REQUEST_ATTACHMENTS);
startActivityForResult(Helper.getChooser(context, tree), REQUEST_ATTACHMENTS);
}
private void onSaveAttachment(Intent data) {

@ -392,7 +392,7 @@ public class FragmentContacts extends FragmentBase {
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, "fairemail.vcf");
Helper.openAdvanced(intent);
Helper.openAdvanced(context, intent);
startActivityForResult(Helper.getChooser(context, intent), REQUEST_EXPORT);
} else {
Intent open = new Intent(Intent.ACTION_GET_CONTENT);

@ -7937,18 +7937,20 @@ public class FragmentMessages extends FragmentBase
String subject = intent.getStringExtra("subject");
String name = (TextUtils.isEmpty(subject) ? "email" : Helper.sanitizeFilename(subject)) + ".eml";
final Context context = getContext();
Intent create = new Intent(Intent.ACTION_CREATE_DOCUMENT);
create.addCategory(Intent.CATEGORY_OPENABLE);
create.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
create.setType("*/*");
create.putExtra(Intent.EXTRA_TITLE, name);
Helper.openAdvanced(create);
PackageManager pm = getContext().getPackageManager();
Helper.openAdvanced(context, create);
PackageManager pm = context.getPackageManager();
if (create.resolveActivity(pm) == null) // system whitelisted
Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG)
.setGestureInsetBottomIgnored(true).show();
else
startActivityForResult(Helper.getChooser(getContext(), create), REQUEST_RAW);
startActivityForResult(Helper.getChooser(context, create), REQUEST_RAW);
}
private void onDecrypt(Intent intent) {

@ -339,12 +339,12 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere
private void onExportSelect() {
startActivityForResult(
Helper.getChooser(getContext(), getIntentExport()), REQUEST_EXPORT_HANDLE);
Helper.getChooser(getContext(), getIntentExport(getContext())), REQUEST_EXPORT_HANDLE);
}
private void onImportSelect() {
startActivityForResult(
Helper.getChooser(getContext(), getIntentImport()), REQUEST_IMPORT_HANDLE);
Helper.getChooser(getContext(), getIntentImport(getContext())), REQUEST_IMPORT_HANDLE);
}
private void handleExport(Intent data) {
@ -1112,6 +1112,9 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere
if ("alert_once".equals(key) && !Helper.isXiaomi())
continue;
if ("default_folder".equals(key))
continue;
if ("background_service".equals(key) &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
continue;
@ -1444,10 +1447,11 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere
}
private void askPassword(final boolean export) {
Intent intent = (export ? getIntentExport() : getIntentImport());
PackageManager pm = getContext().getPackageManager();
final Context context = getContext();
Intent intent = (export ? getIntentExport(context) : getIntentImport(context));
PackageManager pm = context.getPackageManager();
if (intent.resolveActivity(pm) == null) { // // system/GET_CONTENT whitelisted
ToastEx.makeText(getContext(), R.string.title_no_saf, Toast.LENGTH_LONG).show();
ToastEx.makeText(context, R.string.title_no_saf, Toast.LENGTH_LONG).show();
return;
}
@ -1461,18 +1465,18 @@ public class FragmentOptionsBackup extends FragmentBase implements SharedPrefere
}
}
private static Intent getIntentExport() {
private static Intent getIntentExport(Context context) {
Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, "fairemail_" +
new SimpleDateFormat("yyyyMMdd").format(new Date().getTime()) + ".backup");
Helper.openAdvanced(intent);
Helper.openAdvanced(context, intent);
return intent;
}
private static Intent getIntentImport() {
private static Intent getIntentImport(Context context) {
Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

@ -19,11 +19,15 @@ package eu.faircode.email;
Copyright 2018-2023 by Marcel Bokhorst (M66B)
*/
import static android.app.Activity.RESULT_OK;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.Editable;
@ -103,10 +107,14 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
private SwitchCompat swResetSnooze;
private SwitchCompat swAutoBlockSender;
private SwitchCompat swSwipeReply;
private Button btnDefaultFolder;
private TextView tvDefaultFolder;
final static int MAX_SWIPE_SENSITIVITY = 10;
final static int DEFAULT_SWIPE_SENSITIVITY = 7;
final static int REQUEST_DEFAULT_FOLDER = 1;
private final static String[] RESET_OPTIONS = new String[]{
"restore_on_launch", "sync_on_launch", "double_back", "conversation_actions", "conversation_actions_replies", "language_detection",
"photo_picker", "default_snooze",
@ -116,7 +124,7 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
"autoclose", "onclose", "autoclose_unseen", "autoclose_send", "collapse_marked",
"undo_timeout",
"autoread", "flag_snoozed", "autounflag", "auto_important", "reset_importance", "reset_snooze", "auto_block_sender",
"swipe_reply"
"swipe_reply", "default_folder"
};
@Override
@ -174,6 +182,8 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
swResetSnooze = view.findViewById(R.id.swResetSnooze);
swAutoBlockSender = view.findViewById(R.id.swAutoBlockSender);
swSwipeReply = view.findViewById(R.id.swSwipeReply);
btnDefaultFolder = view.findViewById(R.id.btnDefaultFolder);
tvDefaultFolder = view.findViewById(R.id.tvDefaultFolder);
setOptions();
@ -539,6 +549,18 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
}
});
Intent tree = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
Helper.openAdvanced(getContext(), tree);
PackageManager pm = getContext().getPackageManager();
btnDefaultFolder.setEnabled(tree.resolveActivity(pm) != null &&
Build.VERSION.SDK_INT >= Build.VERSION_CODES.O);
btnDefaultFolder.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
startActivityForResult(Helper.getChooser(getContext(), tree), REQUEST_DEFAULT_FOLDER);
}
});
// Initialize
FragmentDialogTheme.setBackground(getContext(), view, false);
@ -553,6 +575,24 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
super.onDestroyView();
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
try {
switch (requestCode) {
case REQUEST_DEFAULT_FOLDER:
if (resultCode == RESULT_OK && data != null)
onDefaultFolder(data.getData());
else
onDefaultFolder(null);
break;
}
} catch (Throwable ex) {
Log.e(ex);
}
}
@Override
public void onSharedPreferenceChanged(SharedPreferences prefs, String key) {
if ("default_snooze".equals(key))
@ -655,6 +695,15 @@ public class FragmentOptionsBehavior extends FragmentBase implements SharedPrefe
swResetSnooze.setChecked(prefs.getBoolean("reset_snooze", true));
swAutoBlockSender.setChecked(prefs.getBoolean("auto_block_sender", true));
swSwipeReply.setChecked(prefs.getBoolean("swipe_reply", false));
tvDefaultFolder.setText(prefs.getString("default_folder", null));
}
private void onDefaultFolder(Uri uri) {
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(getContext());
if (uri == null)
prefs.edit().remove("default_folder").apply();
else
prefs.edit().putString("default_folder", uri.toString()).apply();
}
public static class FragmentDialogSwipes extends FragmentDialogBase {

@ -2502,7 +2502,7 @@ public class FragmentOptionsMisc extends FragmentBase implements SharedPreferenc
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, "classifier.json");
Helper.openAdvanced(intent);
Helper.openAdvanced(context, intent);
startActivityForResult(intent, REQUEST_CLASSIFIER);
}

@ -290,8 +290,9 @@ public class FragmentRules extends FragmentBase {
}
private void onMenuExport() {
if (!ActivityBilling.isPro(getContext())) {
startActivity(new Intent(getContext(), ActivityBilling.class));
final Context context = getContext();
if (!ActivityBilling.isPro(context)) {
startActivity(new Intent(context, ActivityBilling.class));
return;
}
@ -301,7 +302,7 @@ public class FragmentRules extends FragmentBase {
intent.setType("*/*");
intent.putExtra(Intent.EXTRA_TITLE, "fairemail_" +
new SimpleDateFormat("yyyyMMdd").format(new Date().getTime()) + ".rules");
Helper.openAdvanced(intent);
Helper.openAdvanced(context, intent);
startActivityForResult(intent, REQUEST_EXPORT);
}

@ -62,6 +62,7 @@ import android.os.PowerManager;
import android.os.StatFs;
import android.os.storage.StorageManager;
import android.provider.Browser;
import android.provider.DocumentsContract;
import android.provider.Settings;
import android.security.KeyChain;
import android.security.KeyChainAliasCallback;
@ -2591,14 +2592,17 @@ public class Helper {
return size;
}
static void openAdvanced(Intent intent) {
static void openAdvanced(Context context, Intent intent) {
// https://issuetracker.google.com/issues/72053350
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
intent.putExtra("android.content.extra.FANCY", true);
intent.putExtra("android.content.extra.SHOW_FILESIZE", true);
intent.putExtra("android.provider.extra.SHOW_ADVANCED", true);
//File initial = Environment.getExternalStorageDirectory();
//intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Uri.fromFile(initial));
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
String default_folder = prefs.getString("default_folder", null);
if (default_folder != null)
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, Uri.parse(default_folder));
}
static class ByteArrayInOutStream extends ByteArrayOutputStream {

@ -794,8 +794,42 @@
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swAutoBlockSender"
app:switchPadding="12dp" />
<Button
android:id="@+id/btnDefaultFolder"
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="12dp"
android:drawableEnd="@drawable/twotone_folder_24"
android:drawablePadding="6dp"
android:tag="disable"
android:text="@string/title_advanced_default_folder"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/swSwipeReply" />
<TextView
android:id="@+id/tvDefaultFolderHint"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="@string/title_advanced_default_folder_hint"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="italic"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/btnDefaultFolder" />
<TextView
android:id="@+id/tvDefaultFolder"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="Default folder"
android:textAppearance="@style/TextAppearance.AppCompat.Small"
android:textStyle="italic"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@id/tvDefaultFolderHint" />
</androidx.constraintlayout.widget.ConstraintLayout>
</androidx.cardview.widget.CardView>
</androidx.constraintlayout.widget.ConstraintLayout>
</eu.faircode.email.ScrollViewEx>

@ -657,6 +657,7 @@
<string name="title_advanced_auto_block_sender">Automatically block the sender when reporting spam</string>
<string name="title_advanced_swipe_reply">Swipe expanded messages to the right to reply</string>
<string name="title_advanced_default_snooze">Default snooze/delay time</string>
<string name="title_advanced_default_folder">Select default folder</string>
<string name="title_advanced_notifications">Manage notifications</string>
<string name="title_advanced_notifications_default">Default channel</string>
@ -936,6 +937,10 @@
<string name="compressed">The contents of compressed files (%1$s) with more than %2$s files or with files larger than %3$s will not be shown</string>
<string name="title_advanced_parse_classes_hint">This will more accurately display messages, but possibly with a delay</string>
<string name="title_advanced_default_folder_hint">
Android may ask for permission to access the selected folder, even though the app doesn\'t need it.
You can cancel the selection dialog to restore the default folder (usually the \'Download\' folder).
</string>
<string name="title_advanced_restore_on_launch_hint">Restore last app state when restarted via the launcher icon within %1$d minutes</string>
<string name="title_advanced_autoexpand_hint">Automatically open message when there is just one message or just one unread message in a conversation</string>
<string name="title_advanced_expandall_hint">The answer button will not be shown when multiple messages are expanded because it is unclear which message the button applies to</string>

Loading…
Cancel
Save