mirror of https://github.com/M66B/FairEmail.git
Added option to suppress notifications in a car
This commit is contained in:
parent
e4fe3bcd75
commit
1837cf9dea
|
@ -92,6 +92,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
|||
private SwitchCompat swNotifyBackgroundOnly;
|
||||
private SwitchCompat swNotifyKnownOnly;
|
||||
private SwitchCompat swNotifySuppressInCall;
|
||||
private SwitchCompat swNotifySuppressInCar;
|
||||
private TextView tvNotifyKnownPro;
|
||||
private SwitchCompat swNotifyRemove;
|
||||
private SwitchCompat swNotifyClear;
|
||||
|
@ -122,7 +123,8 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
|||
"notify_flag", "notify_seen", "notify_hide", "notify_snooze",
|
||||
"light", "sound", "notify_screen_on",
|
||||
"badge", "unseen_ignored",
|
||||
"notify_background_only", "notify_known", "notify_suppress_in_call", "notify_remove", "notify_clear",
|
||||
"notify_background_only", "notify_known", "notify_suppress_in_call", "notify_suppress_in_car",
|
||||
"notify_remove", "notify_clear",
|
||||
"notify_subtext", "notify_preview", "notify_preview_all", "notify_preview_only", "notify_transliterate",
|
||||
"wearable_preview",
|
||||
"notify_messaging",
|
||||
|
@ -173,6 +175,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
|||
swNotifyBackgroundOnly = view.findViewById(R.id.swNotifyBackgroundOnly);
|
||||
swNotifyKnownOnly = view.findViewById(R.id.swNotifyKnownOnly);
|
||||
swNotifySuppressInCall = view.findViewById(R.id.swNotifySuppressInCall);
|
||||
swNotifySuppressInCar = view.findViewById(R.id.swNotifySuppressInCar);
|
||||
tvNotifyKnownPro = view.findViewById(R.id.tvNotifyKnownPro);
|
||||
swNotifyRemove = view.findViewById(R.id.swNotifyRemove);
|
||||
swNotifyClear = view.findViewById(R.id.swNotifyClear);
|
||||
|
@ -478,6 +481,16 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
|||
}
|
||||
});
|
||||
|
||||
swNotifySuppressInCar.setVisibility(
|
||||
Build.VERSION.SDK_INT < Build.VERSION_CODES.M
|
||||
? View.GONE : View.VISIBLE);
|
||||
swNotifySuppressInCar.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||
prefs.edit().putBoolean("notify_suppress_in_car", checked).apply();
|
||||
}
|
||||
});
|
||||
|
||||
swNotifyRemove.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton compoundButton, boolean checked) {
|
||||
|
@ -689,6 +702,7 @@ public class FragmentOptionsNotifications extends FragmentBase implements Shared
|
|||
swNotifyBackgroundOnly.setChecked(prefs.getBoolean("notify_background_only", false));
|
||||
swNotifyKnownOnly.setChecked(prefs.getBoolean("notify_known", false));
|
||||
swNotifySuppressInCall.setChecked(prefs.getBoolean("notify_suppress_in_call", false));
|
||||
swNotifySuppressInCar.setChecked(prefs.getBoolean("notify_suppress_in_car", false));
|
||||
swNotifyRemove.setChecked(prefs.getBoolean("notify_remove", true));
|
||||
swNotifyClear.setChecked(prefs.getBoolean("notify_clear", false));
|
||||
swNotifySubtext.setChecked(prefs.getBoolean("notify_subtext", true));
|
||||
|
|
|
@ -5,6 +5,12 @@ import android.media.AudioAttributes;
|
|||
import android.media.AudioManager;
|
||||
import android.media.MediaPlayer;
|
||||
import android.net.Uri;
|
||||
import android.os.Build;
|
||||
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleObserver;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.OnLifecycleEvent;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
|
@ -79,6 +85,51 @@ public class MediaPlayerHelper {
|
|||
}
|
||||
}
|
||||
|
||||
static void liveInCall(Context context, LifecycleOwner owner, IInCall intf) {
|
||||
AudioManager am = Helper.getSystemService(context, AudioManager.class);
|
||||
if (am == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||
intf.onChanged(false);
|
||||
Log.i("Audio mode legacy");
|
||||
} else {
|
||||
AudioManager.OnModeChangedListener listener = new AudioManager.OnModeChangedListener() {
|
||||
@Override
|
||||
public void onModeChanged(int mode) {
|
||||
ApplicationEx.getMainHandler().post(new RunnableEx("AudioMode") {
|
||||
@Override
|
||||
public void delegate() {
|
||||
intf.onChanged(isInCall(mode));
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
listener.onModeChanged(am.getMode()); // Init
|
||||
|
||||
owner.getLifecycle().addObserver(new LifecycleObserver() {
|
||||
private boolean registered = false;
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
|
||||
public void onStateChanged() {
|
||||
try {
|
||||
if (owner.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
|
||||
if (!registered) {
|
||||
am.addOnModeChangedListener(executor, listener);
|
||||
registered = true;
|
||||
}
|
||||
} else {
|
||||
if (registered) {
|
||||
am.removeOnModeChangedListener(listener);
|
||||
registered = false;
|
||||
}
|
||||
}
|
||||
Log.i("Audio mode registered=" + registered);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
static boolean isInCall(Context context) {
|
||||
AudioManager am = Helper.getSystemService(context, AudioManager.class);
|
||||
if (am == null)
|
||||
|
@ -100,4 +151,8 @@ public class MediaPlayerHelper {
|
|||
mode == AudioManager.MODE_IN_CALL ||
|
||||
mode == AudioManager.MODE_IN_COMMUNICATION);
|
||||
}
|
||||
|
||||
interface IInCall {
|
||||
void onChanged(boolean inCall);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,7 +31,6 @@ import android.content.Context;
|
|||
import android.content.Intent;
|
||||
import android.content.IntentFilter;
|
||||
import android.content.SharedPreferences;
|
||||
import android.media.AudioManager;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.LinkProperties;
|
||||
import android.net.Network;
|
||||
|
@ -46,6 +45,7 @@ import android.text.TextUtils;
|
|||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.RequiresApi;
|
||||
import androidx.car.app.connection.CarConnection;
|
||||
import androidx.core.app.NotificationCompat;
|
||||
import androidx.core.content.ContextCompat;
|
||||
import androidx.lifecycle.Lifecycle;
|
||||
|
@ -116,6 +116,8 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
|
|||
private int lastAccounts = 0;
|
||||
private int lastOperations = 0;
|
||||
private ConnectionHelper.NetworkState lastNetworkState = null;
|
||||
private boolean isInCall = false;
|
||||
private boolean isInCar = false;
|
||||
|
||||
private boolean foreground = false;
|
||||
private final Map<Long, Core.State> coreStates = new Hashtable<>();
|
||||
|
@ -768,58 +770,45 @@ public class ServiceSynchronize extends ServiceBase implements SharedPreferences
|
|||
});
|
||||
|
||||
final TwoStateOwner mowner = new TwoStateOwner(this, "mutableUnseenNotify");
|
||||
mowner.getLifecycle().addObserver(new LifecycleObserver() {
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
|
||||
public void onStateChanged() {
|
||||
Lifecycle.State state = mowner.getLifecycle().getCurrentState();
|
||||
EntityLog.log(ServiceSynchronize.this, EntityLog.Type.Debug, "Owner state=" + state);
|
||||
if (state.equals(Lifecycle.State.DESTROYED))
|
||||
mowner.getLifecycle().removeObserver(this);
|
||||
}
|
||||
});
|
||||
|
||||
AudioManager am = Helper.getSystemService(this, AudioManager.class);
|
||||
if (am == null || Build.VERSION.SDK_INT < Build.VERSION_CODES.S) {
|
||||
mowner.start();
|
||||
Log.i("Audio mode legacy");
|
||||
} else {
|
||||
AudioManager.OnModeChangedListener listener = new AudioManager.OnModeChangedListener() {
|
||||
@Override
|
||||
public void onModeChanged(int mode) {
|
||||
getMainHandler().post(new RunnableEx("AudioMode") {
|
||||
@Override
|
||||
public void delegate() {
|
||||
boolean incall = MediaPlayerHelper.isInCall(mode);
|
||||
boolean suppress = prefs.getBoolean("notify_suppress_in_call", false);
|
||||
boolean start = (!suppress || !incall);
|
||||
Log.i("Audio mode start=" + start +
|
||||
" incall=" + incall +
|
||||
" suppress=" + suppress);
|
||||
if (start)
|
||||
mowner.start();
|
||||
else
|
||||
mowner.stop();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
listener.onModeChanged(am.getMode()); // Init
|
||||
MediaPlayerHelper.liveInCall(this, this, new MediaPlayerHelper.IInCall() {
|
||||
@Override
|
||||
public void onChanged(boolean inCall) {
|
||||
boolean suppress = prefs.getBoolean("notify_suppress_in_call", false);
|
||||
EntityLog.log(ServiceSynchronize.this, EntityLog.Type.Debug,
|
||||
"In call=" + inCall + " suppress=" + suppress);
|
||||
isInCall = (inCall && suppress);
|
||||
if (isInCall || isInCar)
|
||||
mowner.stop();
|
||||
else
|
||||
mowner.start();
|
||||
}
|
||||
});
|
||||
|
||||
getLifecycle().addObserver(new LifecycleObserver() {
|
||||
private boolean registered = false;
|
||||
|
||||
@OnLifecycleEvent(Lifecycle.Event.ON_ANY)
|
||||
public void onStateChanged() {
|
||||
try {
|
||||
if (ServiceSynchronize.this.getLifecycle().getCurrentState().isAtLeast(Lifecycle.State.STARTED)) {
|
||||
if (!registered) {
|
||||
am.addOnModeChangedListener(executor, listener);
|
||||
registered = true;
|
||||
}
|
||||
} else {
|
||||
if (registered) {
|
||||
am.removeOnModeChangedListener(listener);
|
||||
registered = false;
|
||||
}
|
||||
}
|
||||
Log.i("Audio mode registered=" + registered);
|
||||
} catch (Throwable ex) {
|
||||
Log.e(ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
new CarConnection(this).getType().observe(this, new Observer<Integer>() {
|
||||
@Override
|
||||
public void onChanged(Integer connectionState) {
|
||||
boolean projection = (connectionState != null &&
|
||||
connectionState == CarConnection.CONNECTION_TYPE_PROJECTION);
|
||||
boolean suppress = prefs.getBoolean("notify_suppress_in_car", false);
|
||||
EntityLog.log(ServiceSynchronize.this, EntityLog.Type.Debug,
|
||||
"Projection=" + projection + " state=" + connectionState + " suppress=" + suppress);
|
||||
isInCar = (projection && suppress);
|
||||
if (isInCall || isInCar)
|
||||
mowner.stop();
|
||||
else
|
||||
mowner.start();
|
||||
}
|
||||
});
|
||||
|
||||
mutableUnseenNotify.observe(mowner, new Observer<List<TupleMessageEx>>() {
|
||||
private final ExecutorService executor =
|
||||
|
|
|
@ -560,6 +560,17 @@
|
|||
app:layout_constraintTop_toBottomOf="@id/tvNotifyKnownPro"
|
||||
app:switchPadding="12dp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/swNotifySuppressInCar"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="12dp"
|
||||
android:text="@string/title_advanced_notify_suppress_in_car"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/swNotifySuppressInCall"
|
||||
app:switchPadding="12dp" />
|
||||
|
||||
<androidx.appcompat.widget.SwitchCompat
|
||||
android:id="@+id/swNotifyRemove"
|
||||
android:layout_width="0dp"
|
||||
|
@ -569,7 +580,7 @@
|
|||
android:text="@string/title_advanced_notify_remove"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/swNotifySuppressInCall"
|
||||
app:layout_constraintTop_toBottomOf="@id/swNotifySuppressInCar"
|
||||
app:switchPadding="12dp" />
|
||||
|
||||
<TextView
|
||||
|
|
|
@ -622,6 +622,7 @@
|
|||
<string name="title_advanced_notify_background">Show notifications when in the background only</string>
|
||||
<string name="title_advanced_notify_known">Show notifications for contacts only</string>
|
||||
<string name="title_advanced_notify_suppress_in_call">Delay notifications while on a call</string>
|
||||
<string name="title_advanced_notify_suppress_in_car">Delay notifications while Android Auto is connected</string>
|
||||
<string name="title_advanced_notify_summary">Show summary notification only</string>
|
||||
<string name="title_advanced_notify_preview">Show message preview in notifications</string>
|
||||
<string name="title_advanced_notify_preview_all">Preview all text</string>
|
||||
|
|
Loading…
Reference in New Issue