mirror of
https://github.com/M66B/FairEmail.git
synced 2025-03-15 08:29:24 +00:00
Share files with sanitized name and suffix
This commit is contained in:
parent
c4fa598fcf
commit
1902dacb63
7 changed files with 1589 additions and 100 deletions
1546
app/schemas/eu.faircode.email.DB/54.json
Normal file
1546
app/schemas/eu.faircode.email.DB/54.json
Normal file
File diff suppressed because it is too large
Load diff
|
@ -32,10 +32,8 @@ import android.text.TextUtils;
|
|||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.ListView;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
|
@ -49,7 +47,6 @@ import java.util.Comparator;
|
|||
import java.util.List;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.localbroadcastmanager.content.LocalBroadcastManager;
|
||||
|
@ -203,10 +200,8 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
|
|||
}
|
||||
|
||||
private void onShare(EntityAttachment attachment) {
|
||||
// Build file name
|
||||
File file = attachment.getFile(context);
|
||||
|
||||
// https://developer.android.com/reference/android/support/v4/content/FileProvider
|
||||
File file = attachment.getFile(context);
|
||||
final Uri uri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID, file);
|
||||
Log.i("uri=" + uri);
|
||||
|
||||
|
@ -216,60 +211,20 @@ public class AdapterAttachment extends RecyclerView.Adapter<AdapterAttachment.Vi
|
|||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
if (!TextUtils.isEmpty(attachment.name))
|
||||
intent.putExtra(Intent.EXTRA_TITLE, Helper.sanitizeFilename(attachment.name));
|
||||
Log.i("Sharing " + file + " type=" + attachment.type);
|
||||
Log.i("Intent=" + intent);
|
||||
Log.i("Intent=" + intent + " type=" + attachment.type);
|
||||
|
||||
// Get targets
|
||||
PackageManager pm = context.getPackageManager();
|
||||
List<NameResolveInfo> targets = new ArrayList<>();
|
||||
List<ResolveInfo> ris = pm.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
|
||||
for (ResolveInfo ri : ris) {
|
||||
if ("com.adobe.reader".equals(ri.activityInfo.packageName))
|
||||
Toast.makeText(context, R.string.title_no_adobe, Toast.LENGTH_LONG).show();
|
||||
if (ri.activityInfo.packageName.startsWith("com.microsoft.office."))
|
||||
Toast.makeText(context, R.string.title_no_microsoft, Toast.LENGTH_LONG).show();
|
||||
|
||||
Log.i("Target=" + ri);
|
||||
context.grantUriPermission(ri.activityInfo.packageName, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
|
||||
targets.add(new NameResolveInfo(
|
||||
pm.getApplicationIcon(ri.activityInfo.applicationInfo),
|
||||
pm.getApplicationLabel(ri.activityInfo.applicationInfo).toString(),
|
||||
ri));
|
||||
}
|
||||
|
||||
// Check if viewer available
|
||||
if (ris.size() == 0) {
|
||||
if (ris.size() == 0)
|
||||
Toast.makeText(context, context.getString(R.string.title_no_viewer, attachment.type), Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
|
||||
if (false) {
|
||||
View dview = LayoutInflater.from(context).inflate(R.layout.dialog_attachment, null);
|
||||
final AlertDialog dialog = new DialogBuilderLifecycle(context, owner)
|
||||
.setView(dview)
|
||||
.setNegativeButton(android.R.string.cancel, null)
|
||||
.create();
|
||||
|
||||
TextView tvName = dview.findViewById(R.id.tvName);
|
||||
TextView tvType = dview.findViewById(R.id.tvType);
|
||||
ListView lvApp = dview.findViewById(R.id.lvApp);
|
||||
|
||||
tvName.setText(attachment.name);
|
||||
tvType.setText(attachment.type);
|
||||
|
||||
lvApp.setAdapter(new TargetAdapter(context, R.layout.item_target, targets));
|
||||
lvApp.setOnItemClickListener(new AdapterView.OnItemClickListener() {
|
||||
@Override
|
||||
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
|
||||
NameResolveInfo selected = (NameResolveInfo) parent.getItemAtPosition(position);
|
||||
intent.setPackage(selected.info.activityInfo.packageName);
|
||||
context.startActivity(intent);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
||||
dialog.show();
|
||||
} else
|
||||
else
|
||||
context.startActivity(intent);
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ import org.json.JSONArray;
|
|||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -49,7 +50,7 @@ import io.requery.android.database.sqlite.RequerySQLiteOpenHelperFactory;
|
|||
// https://developer.android.com/topic/libraries/architecture/room.html
|
||||
|
||||
@Database(
|
||||
version = 53,
|
||||
version = 54,
|
||||
entities = {
|
||||
EntityIdentity.class,
|
||||
EntityAccount.class,
|
||||
|
@ -567,6 +568,37 @@ public abstract class DB extends RoomDatabase {
|
|||
db.execSQL("ALTER TABLE `operation` ADD COLUMN `account` INTEGER");
|
||||
}
|
||||
})
|
||||
.addMigrations(new Migration(53, 54) {
|
||||
@Override
|
||||
public void migrate(SupportSQLiteDatabase db) {
|
||||
Log.i("DB migration from version " + startVersion + " to " + endVersion);
|
||||
File folder = new File(context.getFilesDir(), "attachments");
|
||||
File[] attachments = folder.listFiles();
|
||||
if (attachments != null)
|
||||
for (File source : attachments) {
|
||||
long id = Long.parseLong(source.getName().split("\\.")[0]);
|
||||
Cursor cursor = null;
|
||||
try {
|
||||
cursor = db.query("SELECT name FROM attachment WHERE id = ?", new Object[]{id});
|
||||
if (cursor != null && cursor.moveToNext()) {
|
||||
String name = cursor.getString(0);
|
||||
if (!TextUtils.isEmpty(name)) {
|
||||
File target = new File(folder, id + "." + Helper.sanitizeFilename(name));
|
||||
if (source.renameTo(target))
|
||||
Log.i("Renamed attachment=" + target.getName());
|
||||
else {
|
||||
Log.i("Unavailable attachment=" + source.getName());
|
||||
db.execSQL("UPDATE attachment SET available = 0 WHERE id = ?", new Object[]{id});
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (Throwable ex) {
|
||||
if (cursor != null)
|
||||
cursor.close();
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
.build();
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ package eu.faircode.email;
|
|||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
@ -79,7 +80,10 @@ public class EntityAttachment {
|
|||
File dir = new File(context.getFilesDir(), "attachments");
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
return new File(dir, Long.toString(id));
|
||||
String filename = Long.toString(id);
|
||||
if (!TextUtils.isEmpty(name))
|
||||
filename += "." + Helper.sanitizeFilename(name);
|
||||
return new File(dir, filename);
|
||||
}
|
||||
|
||||
static void copy(Context context, long oldid, long newid) {
|
||||
|
|
|
@ -92,7 +92,7 @@ public class WorkerCleanup extends Worker {
|
|||
File[] attachments = new File(context.getFilesDir(), "attachments").listFiles();
|
||||
if (attachments != null)
|
||||
for (File file : attachments) {
|
||||
long id = Long.parseLong(file.getName());
|
||||
long id = Long.parseLong(file.getName().split("\\.")[0]);
|
||||
if (db.attachment().countAttachment(id) == 0) {
|
||||
Log.i("Deleting " + file);
|
||||
if (!file.delete())
|
||||
|
|
|
@ -1,46 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:padding="12dp"
|
||||
tools:context=".ActivityView">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvName"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Name"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
||||
android:textColor="?android:attr/textColorPrimary"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvType"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="text/plain"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Small"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvName" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/tvOpenWith"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_open_with"
|
||||
android:textAppearance="@style/TextAppearance.AppCompat.Large"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvType" />
|
||||
|
||||
<ListView
|
||||
android:id="@+id/lvApp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/tvOpenWith" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
|
@ -544,8 +544,6 @@
|
|||
<string name="title_fix">Fix</string>
|
||||
<string name="title_enable">Enable</string>
|
||||
<string name="title_no_ask_again">Do not ask this again</string>
|
||||
<string name="title_no_adobe">Adobe Acrobat reader cannot safely open shared files, see the FAQ for more information</string>
|
||||
<string name="title_no_microsoft">Microsoft apps cannot safely open shared files, see the FAQ for more information</string>
|
||||
<string name="title_no_body">No message text found</string>
|
||||
<string name="title_no_charset">Unsupported encoding: %1$s</string>
|
||||
<string name="title_via">Via: %1$s</string>
|
||||
|
|
Loading…
Add table
Reference in a new issue