mirror of
https://github.com/M66B/FairEmail.git
synced 2024-12-29 11:15:51 +00:00
Added record audio / take photo
This commit is contained in:
parent
e56629689c
commit
5780253a14
8 changed files with 136 additions and 39 deletions
|
@ -22,6 +22,9 @@
|
|||
<uses-feature
|
||||
android:name="android.software.webview"
|
||||
android:required="false" />
|
||||
<uses-feature
|
||||
android:name="android.hardware.camera"
|
||||
android:required="false" />
|
||||
|
||||
<application
|
||||
android:name=".ApplicationEx"
|
||||
|
|
|
@ -46,7 +46,9 @@ public class ActivityCompose extends ActivityBilling implements FragmentManager.
|
|||
static final int REQUEST_CONTACT_BCC = 3;
|
||||
static final int REQUEST_IMAGE = 4;
|
||||
static final int REQUEST_ATTACHMENT = 5;
|
||||
static final int REQUEST_ENCRYPT = 6;
|
||||
static final int REQUEST_TAKE_PHOTO = 6;
|
||||
static final int REQUEST_RECORD_AUDIO = 7;
|
||||
static final int REQUEST_ENCRYPT = 8;
|
||||
|
||||
static final int PI_REPLY = 1;
|
||||
|
||||
|
|
|
@ -51,6 +51,7 @@ import android.os.Bundle;
|
|||
import android.os.Handler;
|
||||
import android.os.Looper;
|
||||
import android.provider.ContactsContract;
|
||||
import android.provider.MediaStore;
|
||||
import android.provider.OpenableColumns;
|
||||
import android.text.Editable;
|
||||
import android.text.Html;
|
||||
|
@ -94,6 +95,7 @@ import androidx.annotation.Nullable;
|
|||
import androidx.appcompat.app.AlertDialog;
|
||||
import androidx.constraintlayout.widget.ConstraintLayout;
|
||||
import androidx.constraintlayout.widget.Group;
|
||||
import androidx.core.content.FileProvider;
|
||||
import androidx.cursoradapter.widget.SimpleCursorAdapter;
|
||||
import androidx.exifinterface.media.ExifInterface;
|
||||
import androidx.fragment.app.FragmentTransaction;
|
||||
|
@ -185,17 +187,19 @@ public class FragmentCompose extends FragmentBase {
|
|||
|
||||
private boolean pro;
|
||||
|
||||
private long working = -1;
|
||||
private State state = State.NONE;
|
||||
private boolean show_images = false;
|
||||
private boolean autosave = false;
|
||||
private boolean busy = false;
|
||||
|
||||
private boolean prefix_once = false;
|
||||
private boolean monospaced = false;
|
||||
private boolean style = true;
|
||||
private boolean plain_only = false;
|
||||
private boolean encrypt = false;
|
||||
|
||||
private long working = -1;
|
||||
private State state = State.NONE;
|
||||
private boolean show_images = false;
|
||||
private boolean autosave = false;
|
||||
private boolean busy = false;
|
||||
private Uri photoURI = null;
|
||||
|
||||
private OpenPgpServiceConnection pgpService;
|
||||
private long[] pgpKeyIds;
|
||||
private long pgpSignKeyId;
|
||||
|
@ -335,13 +339,23 @@ public class FragmentCompose extends FragmentBase {
|
|||
etBody.setTypeface(monospaced ? Typeface.MONOSPACE : Typeface.DEFAULT);
|
||||
tvReference.setTypeface(monospaced ? Typeface.MONOSPACE : Typeface.DEFAULT);
|
||||
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
Intent take_photo = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
Intent record_audio = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
|
||||
edit_bar.getMenu().findItem(R.id.menu_take_photo).setVisible(take_photo.resolveActivity(pm) != null);
|
||||
edit_bar.getMenu().findItem(R.id.menu_record_audio).setVisible(record_audio.resolveActivity(pm) != null);
|
||||
|
||||
|
||||
edit_bar.setOnNavigationItemSelectedListener(new BottomNavigationView.OnNavigationItemSelectedListener() {
|
||||
@Override
|
||||
public boolean onNavigationItemSelected(@NonNull MenuItem item) {
|
||||
int action = item.getItemId();
|
||||
switch (action) {
|
||||
case R.id.menu_link:
|
||||
onActionLink();
|
||||
case R.id.menu_record_audio:
|
||||
onActionRecordAudio();
|
||||
return true;
|
||||
case R.id.menu_take_photo:
|
||||
onActionTakePhoto();
|
||||
return true;
|
||||
case R.id.menu_image:
|
||||
onActionImage();
|
||||
|
@ -349,6 +363,9 @@ public class FragmentCompose extends FragmentBase {
|
|||
case R.id.menu_attachment:
|
||||
onActionAttachment();
|
||||
return true;
|
||||
case R.id.menu_link:
|
||||
onActionLink();
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -1114,6 +1131,46 @@ public class FragmentCompose extends FragmentBase {
|
|||
});
|
||||
}
|
||||
|
||||
private void onActionRecordAudio() {
|
||||
Intent intent = new Intent(MediaStore.Audio.Media.RECORD_SOUND_ACTION);
|
||||
startActivityForResult(intent, ActivityCompose.REQUEST_RECORD_AUDIO);
|
||||
}
|
||||
|
||||
private void onActionTakePhoto() {
|
||||
File dir = new File(getContext().getFilesDir(), "temporary");
|
||||
if (!dir.exists())
|
||||
dir.mkdir();
|
||||
File file = new File(dir, new Date().getTime() + ".jpg");
|
||||
|
||||
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
|
||||
photoURI = FileProvider.getUriForFile(getContext(), BuildConfig.APPLICATION_ID, file);
|
||||
intent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
|
||||
startActivityForResult(intent, ActivityCompose.REQUEST_TAKE_PHOTO);
|
||||
}
|
||||
|
||||
private void onActionImage() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("image/*");
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
if (intent.resolveActivity(pm) == null)
|
||||
Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG).show();
|
||||
else
|
||||
startActivityForResult(Helper.getChooser(getContext(), intent), ActivityCompose.REQUEST_IMAGE);
|
||||
}
|
||||
|
||||
private void onActionAttachment() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
if (intent.resolveActivity(pm) == null)
|
||||
Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG).show();
|
||||
else
|
||||
startActivityForResult(Helper.getChooser(getContext(), intent), ActivityCompose.REQUEST_ATTACHMENT);
|
||||
}
|
||||
|
||||
private void onActionLink() {
|
||||
Uri uri = null;
|
||||
|
||||
|
@ -1191,29 +1248,6 @@ public class FragmentCompose extends FragmentBase {
|
|||
});
|
||||
}
|
||||
|
||||
private void onActionImage() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("image/*");
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
if (intent.resolveActivity(pm) == null)
|
||||
Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG).show();
|
||||
else
|
||||
startActivityForResult(Helper.getChooser(getContext(), intent), ActivityCompose.REQUEST_IMAGE);
|
||||
}
|
||||
|
||||
private void onActionAttachment() {
|
||||
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
|
||||
intent.addCategory(Intent.CATEGORY_OPENABLE);
|
||||
intent.setType("*/*");
|
||||
intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
|
||||
PackageManager pm = getContext().getPackageManager();
|
||||
if (intent.resolveActivity(pm) == null)
|
||||
Snackbar.make(view, R.string.title_no_saf, Snackbar.LENGTH_LONG).show();
|
||||
else
|
||||
startActivityForResult(Helper.getChooser(getContext(), intent), ActivityCompose.REQUEST_ATTACHMENT);
|
||||
}
|
||||
|
||||
private void onActionDelete() {
|
||||
new DialogBuilderLifecycle(getContext(), getViewLifecycleOwner())
|
||||
.setMessage(R.string.title_ask_discard)
|
||||
|
@ -1505,7 +1539,13 @@ public class FragmentCompose extends FragmentBase {
|
|||
if (uri != null)
|
||||
handleAddAttachment(uri, true);
|
||||
}
|
||||
} else if (requestCode == ActivityCompose.REQUEST_ATTACHMENT) {
|
||||
} else if (requestCode == ActivityCompose.REQUEST_ATTACHMENT ||
|
||||
requestCode == ActivityCompose.REQUEST_RECORD_AUDIO ||
|
||||
requestCode == ActivityCompose.REQUEST_TAKE_PHOTO) {
|
||||
|
||||
if (requestCode == ActivityCompose.REQUEST_TAKE_PHOTO)
|
||||
data = new Intent().setData(photoURI);
|
||||
|
||||
if (data != null) {
|
||||
ClipData clipData = data.getClipData();
|
||||
if (clipData == null) {
|
||||
|
@ -1722,11 +1762,11 @@ public class FragmentCompose extends FragmentBase {
|
|||
|
||||
private static EntityAttachment addAttachment(Context context, long id, Uri uri,
|
||||
boolean image) throws IOException {
|
||||
Log.w("Add attachment uri=" + uri);
|
||||
|
||||
if ("file".equals(uri.getScheme()) &&
|
||||
!Helper.hasPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)) {
|
||||
Log.w("Add attachment uri=" + uri);
|
||||
!Helper.hasPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE))
|
||||
throw new SecurityException();
|
||||
}
|
||||
|
||||
EntityAttachment attachment = new EntityAttachment();
|
||||
|
||||
|
@ -1805,6 +1845,15 @@ public class FragmentCompose extends FragmentBase {
|
|||
}
|
||||
}
|
||||
|
||||
if ("eu.faircode.email".equals(uri.getAuthority())) {
|
||||
// content://eu.faircode.email/temporary/nnn.jpg
|
||||
File tmp = new File(context.getFilesDir(), uri.getPath());
|
||||
Log.i("Deleting " + tmp);
|
||||
if (!tmp.delete())
|
||||
Log.w("Error deleting " + tmp);
|
||||
} else
|
||||
Log.i("Authority=" + uri.getAuthority());
|
||||
|
||||
SharedPreferences prefs = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
boolean autoresize = prefs.getBoolean("autoresize", true);
|
||||
|
||||
|
@ -1821,6 +1870,7 @@ public class FragmentCompose extends FragmentBase {
|
|||
options.outHeight / factor > resize)
|
||||
factor *= 2;
|
||||
|
||||
Log.i("Image type=" + attachment.type + " rotation=" + getImageRotation(file));
|
||||
Matrix rotation = ("image/jpeg".equals(attachment.type) ? getImageRotation(file) : null);
|
||||
|
||||
if (factor > 1 || rotation != null) {
|
||||
|
|
13
app/src/main/res/drawable/baseline_photo_camera_24.xml
Normal file
13
app/src/main/res/drawable/baseline_photo_camera_24.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M12,12m-3.2,0a3.2,3.2 0,1 1,6.4 0a3.2,3.2 0,1 1,-6.4 0"/>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,2L7.17,4L4,4c-1.1,0 -2,0.9 -2,2v12c0,1.1 0.9,2 2,2h16c1.1,0 2,-0.9 2,-2L22,6c0,-1.1 -0.9,-2 -2,-2h-3.17L15,2L9,2zM12,17c-2.76,0 -5,-2.24 -5,-5s2.24,-5 5,-5 5,2.24 5,5 -2.24,5 -5,5z"/>
|
||||
</vector>
|
13
app/src/main/res/drawable/baseline_record_voice_over_24.xml
Normal file
13
app/src/main/res/drawable/baseline_record_voice_over_24.xml
Normal file
|
@ -0,0 +1,13 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0"
|
||||
android:tint="?attr/colorControlNormal">
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,9m-4,0a4,4 0,1 1,8 0a4,4 0,1 1,-8 0"/>
|
||||
<path
|
||||
android:fillColor="@android:color/white"
|
||||
android:pathData="M9,15c-2.67,0 -8,1.34 -8,4v2h16v-2c0,-2.66 -5.33,-4 -8,-4zM16.76,5.36l-1.68,1.69c0.84,1.18 0.84,2.71 0,3.89l1.68,1.69c2.02,-2.02 2.02,-5.07 0,-7.27zM20.07,2l-1.63,1.63c2.77,3.02 2.77,7.56 0,10.74L20.07,16c3.9,-3.89 3.91,-9.95 0,-14z"/>
|
||||
</vector>
|
|
@ -1,9 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item
|
||||
android:id="@+id/menu_link"
|
||||
android:icon="@drawable/baseline_insert_link_24"
|
||||
android:title="@string/title_style_link" />
|
||||
android:id="@+id/menu_record_audio"
|
||||
android:icon="@drawable/baseline_record_voice_over_24"
|
||||
android:title="@string/title_attachment_audio" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_take_photo"
|
||||
android:icon="@drawable/baseline_photo_camera_24"
|
||||
android:title="@string/title_attachment_photo" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_image"
|
||||
|
@ -14,4 +19,9 @@
|
|||
android:id="@+id/menu_attachment"
|
||||
android:icon="@drawable/baseline_attachment_24"
|
||||
android:title="@string/title_add_attachment" />
|
||||
|
||||
<item
|
||||
android:id="@+id/menu_link"
|
||||
android:icon="@drawable/baseline_insert_link_24"
|
||||
android:title="@string/title_style_link" />
|
||||
</menu>
|
||||
|
|
|
@ -461,6 +461,9 @@
|
|||
<string name="title_style_image">Insert image</string>
|
||||
<string name="title_style_toolbar">Style toolbar</string>
|
||||
<string name="title_add_attachment">Add attachment</string>
|
||||
<string name="title_attachment_file">Attach file</string>
|
||||
<string name="title_attachment_photo">Take photo</string>
|
||||
<string name="title_attachment_audio">Record audio</string>
|
||||
<string name="title_show_addresses">Show CC/BCC</string>
|
||||
<string name="title_insert_contact_group">Insert contact group</string>
|
||||
<string name="title_insert_template">Insert template</string>
|
||||
|
|
|
@ -6,4 +6,7 @@
|
|||
<files-path
|
||||
name="raw"
|
||||
path="raw" />
|
||||
<files-path
|
||||
name="temporary"
|
||||
path="temporary" />
|
||||
</paths>
|
||||
|
|
Loading…
Reference in a new issue