mirror of
https://github.com/M66B/FairEmail.git
synced 2026-04-27 19:26:26 +02:00
Notify/TTS
This commit is contained in:
@@ -96,6 +96,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
||||
private CheckBox cbNotifyActionSeen;
|
||||
private CheckBox cbNotifyActionHide;
|
||||
private CheckBox cbNotifyActionSnooze;
|
||||
private CheckBox cbNotifyActionTts;
|
||||
private TextView tvNotifyActionsPro;
|
||||
private SwitchCompat swLight;
|
||||
private Button btnSound;
|
||||
@@ -144,7 +145,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
||||
"notify_newest_first", "notify_summary",
|
||||
"notify_trash", "notify_junk", "notify_block_sender", "notify_archive", "notify_move",
|
||||
"notify_reply", "notify_reply_direct",
|
||||
"notify_flag", "notify_seen", "notify_hide", "notify_snooze",
|
||||
"notify_flag", "notify_seen", "notify_hide", "notify_snooze", "notify_tts",
|
||||
"light", "sound", "notify_screen_on",
|
||||
"badge", "unseen_ignored",
|
||||
"notify_grouping", "notify_private", "notify_background_only", "notify_known", "notify_suppress_in_call", "notify_suppress_in_car",
|
||||
@@ -188,6 +189,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
||||
cbNotifyActionSeen = view.findViewById(R.id.cbNotifyActionSeen);
|
||||
cbNotifyActionHide = view.findViewById(R.id.cbNotifyActionHide);
|
||||
cbNotifyActionSnooze = view.findViewById(R.id.cbNotifyActionSnooze);
|
||||
cbNotifyActionTts = view.findViewById(R.id.cbNotifyActionTts);
|
||||
tvNotifyActionsPro = view.findViewById(R.id.tvNotifyActionsPro);
|
||||
swLight = view.findViewById(R.id.swLight);
|
||||
btnSound = view.findViewById(R.id.btnSound);
|
||||
@@ -516,6 +518,13 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
||||
}
|
||||
});
|
||||
|
||||
cbNotifyActionTts.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean checked) {
|
||||
prefs.edit().putBoolean("notify_tts", checked).apply();
|
||||
}
|
||||
});
|
||||
|
||||
Helper.linkPro(tvNotifyActionsPro);
|
||||
Helper.linkPro(tvNotifyKnownPro);
|
||||
|
||||
@@ -894,6 +903,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
||||
cbNotifyActionSeen.setChecked(prefs.getBoolean("notify_seen", true) || !pro);
|
||||
cbNotifyActionHide.setChecked(prefs.getBoolean("notify_hide", false) && pro);
|
||||
cbNotifyActionSnooze.setChecked(prefs.getBoolean("notify_snooze", false) && pro);
|
||||
cbNotifyActionTts.setChecked(prefs.getBoolean("notify_tts", false) && pro);
|
||||
swLight.setChecked(prefs.getBoolean("light", false));
|
||||
swNotifyScreenOn.setChecked(prefs.getBoolean("notify_screen_on", false));
|
||||
|
||||
@@ -941,6 +951,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
||||
cbNotifyActionSeen.setEnabled(pro && !summary);
|
||||
cbNotifyActionHide.setEnabled(pro && !summary);
|
||||
cbNotifyActionSnooze.setEnabled(pro && !summary);
|
||||
cbNotifyActionTts.setEnabled(pro && !summary);
|
||||
swNotifyPreviewAll.setEnabled(!summary && swNotifyPreview.isChecked());
|
||||
swNotifyPreviewOnly.setEnabled(!summary && swNotifyPreview.isChecked());
|
||||
swWearablePreview.setEnabled(!summary && swNotifyPreview.isChecked());
|
||||
|
||||
@@ -720,6 +720,7 @@ class NotificationHelper {
|
||||
boolean notify_seen = (prefs.getBoolean("notify_seen", true) || !pro);
|
||||
boolean notify_hide = (prefs.getBoolean("notify_hide", false) && pro);
|
||||
boolean notify_snooze = (prefs.getBoolean("notify_snooze", false) && pro);
|
||||
boolean notify_tts = (prefs.getBoolean("notify_tts", false) && pro);
|
||||
boolean notify_remove = prefs.getBoolean("notify_remove", true);
|
||||
boolean light = prefs.getBoolean("light", false);
|
||||
String sound = prefs.getString("sound", null);
|
||||
@@ -1334,6 +1335,27 @@ class NotificationHelper {
|
||||
wactions.add(actionSnooze.build());
|
||||
}
|
||||
|
||||
if (message.content && notify_tts) {
|
||||
Intent tts = new Intent(context, ServiceTTS.class);
|
||||
tts.putExtra(ServiceTTS.EXTRA_FLUSH, true);
|
||||
tts.putExtra(ServiceTTS.EXTRA_TEXT, "");
|
||||
tts.putExtra(ServiceTTS.EXTRA_LANGUAGE, message.language);
|
||||
tts.putExtra(ServiceTTS.EXTRA_UTTERANCE_ID, "tts:" + message.id);
|
||||
tts.putExtra(ServiceTTS.EXTRA_GROUP, group);
|
||||
tts.putExtra(ServiceTTS.EXTRA_MESSAGE, message.id);
|
||||
PendingIntent piTts = PendingIntentCompat.getService(
|
||||
context, ServiceTTS.PI_TTS, tts, PendingIntent.FLAG_UPDATE_CURRENT);
|
||||
NotificationCompat.Action.Builder actionTts = new NotificationCompat.Action.Builder(
|
||||
R.drawable.twotone_play_arrow_24,
|
||||
context.getString(R.string.title_rule_tts),
|
||||
piTts)
|
||||
.setShowsUserInterface(false)
|
||||
.setAllowGeneratedReplies(false);
|
||||
mbuilder.addAction(actionTts.build());
|
||||
|
||||
wactions.add(actionTts.build());
|
||||
}
|
||||
|
||||
// https://developer.android.com/training/wearables/notifications
|
||||
// https://developer.android.com/reference/androidx/core/app/NotificationCompat.Action.WearableExtender
|
||||
mbuilder.extend(new NotificationCompat.WearableExtender()
|
||||
|
||||
@@ -20,13 +20,16 @@ package eu.faircode.email;
|
||||
*/
|
||||
|
||||
import android.app.Notification;
|
||||
import android.app.NotificationManager;
|
||||
import android.app.PendingIntent;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.os.IBinder;
|
||||
import android.os.OperationCanceledException;
|
||||
import android.speech.tts.TextToSpeech;
|
||||
import android.speech.tts.UtteranceProgressListener;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
@@ -46,9 +49,13 @@ public class ServiceTTS extends ServiceBase {
|
||||
static final String EXTRA_TEXT = "text";
|
||||
static final String EXTRA_LANGUAGE = "language";
|
||||
static final String EXTRA_UTTERANCE_ID = "utterance";
|
||||
static final String EXTRA_MESSAGE = "message";
|
||||
static final String EXTRA_GROUP = "group";
|
||||
|
||||
static final String ACTION_TTS_COMPLETED = BuildConfig.APPLICATION_ID + ".TTS";
|
||||
|
||||
static final int PI_TTS = 1;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
Log.i("Service TTS create");
|
||||
@@ -145,9 +152,40 @@ public class ServiceTTS extends ServiceBase {
|
||||
final String text = intent.getStringExtra(EXTRA_TEXT);
|
||||
final String language = intent.getStringExtra(EXTRA_LANGUAGE);
|
||||
final String utteranceId = intent.getStringExtra(EXTRA_UTTERANCE_ID);
|
||||
final long group = intent.getLongExtra(EXTRA_GROUP, 0);
|
||||
final long message = intent.getLongExtra(EXTRA_MESSAGE, -1L);
|
||||
|
||||
final Locale locale = (language == null ? Locale.getDefault() : new Locale(language));
|
||||
|
||||
if (message > 0) {
|
||||
String tag = "unseen." + group + "." + message;
|
||||
Log.i("MMM cancel tag=" + tag);
|
||||
NotificationManager nm = Helper.getSystemService(this, NotificationManager.class);
|
||||
nm.cancel(tag, NotificationHelper.NOTIFICATION_TAGGED);
|
||||
|
||||
Helper.getSerialExecutor().submit(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
try {
|
||||
String body = Helper.readText(EntityMessage.getFile(ServiceTTS.this, message));
|
||||
String text = HtmlHelper.getFullText(ServiceTTS.this, body);
|
||||
|
||||
// Avoid: Not enough namespace quota ... for ...
|
||||
text = HtmlHelper.truncate(text, getMaxTextSize() / 3);
|
||||
|
||||
intent.putExtra(EXTRA_TEXT, text);
|
||||
intent.removeExtra(EXTRA_GROUP);
|
||||
intent.removeExtra(EXTRA_MESSAGE);
|
||||
onTts(intent);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
final Runnable speak = new RunnableEx("tts") {
|
||||
@Override
|
||||
public void delegate() {
|
||||
|
||||
Reference in New Issue
Block a user