Compare commits
2 Commits
v1.13
...
1400-keybo
Author | SHA1 | Date | |
---|---|---|---|
![]() |
319d197d79 | ||
![]() |
b459e9f9a5 |
@@ -56,6 +56,8 @@ using Android.Util;
|
|||||||
using AndroidX.Core.Content;
|
using AndroidX.Core.Content;
|
||||||
using Google.Android.Material.Dialog;
|
using Google.Android.Material.Dialog;
|
||||||
using keepass2android;
|
using keepass2android;
|
||||||
|
using AndroidX.Core.App;
|
||||||
|
using Google.Android.Material.Snackbar;
|
||||||
|
|
||||||
namespace keepass2android
|
namespace keepass2android
|
||||||
{
|
{
|
||||||
@@ -571,13 +573,41 @@ namespace keepass2android
|
|||||||
if (permissions.Length == 1 && permissions.First() == Android.Manifest.Permission.PostNotifications &&
|
if (permissions.Length == 1 && permissions.First() == Android.Manifest.Permission.PostNotifications &&
|
||||||
grantResults.First() == Permission.Granted)
|
grantResults.First() == Permission.Granted)
|
||||||
{
|
{
|
||||||
|
if (!CopyToClipboardService.HasEntryNotificationPermissions(this, false))
|
||||||
|
{
|
||||||
|
Intent intent = new Intent();
|
||||||
|
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
|
||||||
|
{
|
||||||
|
intent.SetAction(Android.Provider.Settings.ActionAppNotificationSettings);
|
||||||
|
intent.PutExtra(Android.Provider.Settings.ExtraAppPackage, PackageName);
|
||||||
|
}
|
||||||
|
else if (Build.VERSION.SdkInt >= BuildVersionCodes.Lollipop)
|
||||||
|
{
|
||||||
|
intent.SetAction(Android.Provider.Settings.ActionAppNotificationSettings);
|
||||||
|
intent.PutExtra("app_package", PackageName);
|
||||||
|
intent.PutExtra("app_uid", ApplicationInfo.Uid);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
intent.SetAction(Android.Provider.Settings.ActionApplicationDetailsSettings);
|
||||||
|
intent.AddCategory(Intent.CategoryDefault);
|
||||||
|
intent.SetData(Uri.Parse("package:" + PackageName));
|
||||||
|
}
|
||||||
|
StartActivity(intent);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Kp2aLog.Log($"StartNotificationsServiceAfterPermissionsCheck(activateKeyboard: requestCode == {requestCode}");
|
||||||
StartNotificationsServiceAfterPermissionsCheck(requestCode == 1 /*requestCode is used to transfer this flag*/);
|
StartNotificationsServiceAfterPermissionsCheck(requestCode == 1 /*requestCode is used to transfer this flag*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||||
}
|
}
|
||||||
internal void StartNotificationsService(bool activateKeyboard)
|
internal void StartNotificationsService(bool activateKeyboard)
|
||||||
{
|
{
|
||||||
|
Kp2aLog.Log($"StartNotificationsService. ActivateKeyboard={activateKeyboard}");
|
||||||
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
|
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
|
||||||
GetString(Resource.String.CopyToClipboardNotification_key),
|
GetString(Resource.String.CopyToClipboardNotification_key),
|
||||||
Resources.GetBoolean(Resource.Boolean.CopyToClipboardNotification_default)) == false
|
Resources.GetBoolean(Resource.Boolean.CopyToClipboardNotification_default)) == false
|
||||||
@@ -586,12 +616,16 @@ namespace keepass2android
|
|||||||
Resources.GetBoolean(Resource.Boolean.UseKp2aKeyboard_default)) == false)
|
Resources.GetBoolean(Resource.Boolean.UseKp2aKeyboard_default)) == false)
|
||||||
{
|
{
|
||||||
//notifications are disabled
|
//notifications are disabled
|
||||||
|
Kp2aLog.Log($"StartNotificationsService. Notifications disabled. Returning.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((int)Build.VERSION.SdkInt < 33 || CheckSelfPermission(Android.Manifest.Permission.PostNotifications) ==
|
|
||||||
Permission.Granted)
|
|
||||||
|
if ((int)Build.VERSION.SdkInt < 33 || CopyToClipboardService.HasEntryNotificationPermissions(this, activateKeyboard))
|
||||||
{
|
{
|
||||||
|
Kp2aLog.Log($"StartNotificationsService. Permissions ok. activateKeyboard={activateKeyboard}");
|
||||||
|
|
||||||
StartNotificationsServiceAfterPermissionsCheck(activateKeyboard);
|
StartNotificationsServiceAfterPermissionsCheck(activateKeyboard);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -602,10 +636,34 @@ namespace keepass2android
|
|||||||
if (!ShouldShowRequestPermissionRationale(Android.Manifest.Permission.PostNotifications) //this menthod returns false if we haven't asked yet or if the user has denied permission too often
|
if (!ShouldShowRequestPermissionRationale(Android.Manifest.Permission.PostNotifications) //this menthod returns false if we haven't asked yet or if the user has denied permission too often
|
||||||
&& PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean("RequestedPostNotificationsPermission", false))//use a preference to tell the difference between "haven't asked yet" and "have asked too often"
|
&& PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean("RequestedPostNotificationsPermission", false))//use a preference to tell the difference between "haven't asked yet" and "have asked too often"
|
||||||
{
|
{
|
||||||
|
Kp2aLog.Log($"StartNotificationsService. Permissions not granted. Showing snackbar.");
|
||||||
//user has denied permission before. Do not show the dialog. User must give permission in the Android App settings.
|
//user has denied permission before. Do not show the dialog. User must give permission in the Android App settings.
|
||||||
|
var snackbar = Snackbar
|
||||||
|
.Make(SnackbarAnchorView, Resource.String.post_notifications_snackbar,
|
||||||
|
Snackbar.LengthIndefinite);
|
||||||
|
snackbar.SetTextMaxLines(10);
|
||||||
|
if ((int)Build.VERSION.SdkInt >= 23)
|
||||||
|
{
|
||||||
|
|
||||||
|
snackbar.SetBackgroundTint(App.Context.GetColor(Resource.Color.md_theme_inverseSurface));
|
||||||
|
snackbar.SetTextColor(App.Context.GetColor(Resource.Color.md_theme_inverseOnSurface));
|
||||||
|
}
|
||||||
|
|
||||||
|
snackbar.SetAction(Resource.String.post_notifications_snackbar_config, view => { ShowNotificationPermissionsDialog(activateKeyboard); });
|
||||||
|
|
||||||
|
snackbar.Show();
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShowNotificationPermissionsDialog(activateKeyboard);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ShowNotificationPermissionsDialog(bool activateKeyboard)
|
||||||
|
{
|
||||||
|
Kp2aLog.Log($"ShowNotificationPermissionsDialog");
|
||||||
new MaterialAlertDialogBuilder(this)
|
new MaterialAlertDialogBuilder(this)
|
||||||
.SetTitle(Resource.String.post_notifications_dialog_title)
|
.SetTitle(Resource.String.post_notifications_dialog_title)
|
||||||
.SetMessage(Resource.String.post_notifications_dialog_message)
|
.SetMessage(Resource.String.post_notifications_dialog_message)
|
||||||
@@ -632,8 +690,6 @@ namespace keepass2android
|
|||||||
})
|
})
|
||||||
.SetNeutralButton(Resource.String.post_notifications_dialog_notnow, (sender, args) => { })
|
.SetNeutralButton(Resource.String.post_notifications_dialog_notnow, (sender, args) => { })
|
||||||
.Show();
|
.Show();
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void StartNotificationsServiceAfterPermissionsCheck(bool activateKeyboard)
|
private void StartNotificationsServiceAfterPermissionsCheck(bool activateKeyboard)
|
||||||
|
@@ -337,6 +337,7 @@ namespace keepass2android
|
|||||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||||
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
|
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
|
||||||
{
|
{
|
||||||
|
Kp2aLog.Log("Activating keyboard in EntryEditActivity due to UseKp2aKeyboardInKp2a");
|
||||||
CopyToClipboardService.ActivateKeyboard(this);
|
CopyToClipboardService.ActivateKeyboard(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:versionCode="206"
|
android:versionCode="207"
|
||||||
android:versionName="1.12-r5"
|
android:versionName="1.12-r5-test2848"
|
||||||
package="keepass2android.keepass2android"
|
package="keepass2android.keepass2android"
|
||||||
xmlns:tools="http://schemas.android.com/tools"
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:installLocation="auto">
|
android:installLocation="auto">
|
||||||
|
@@ -1578,6 +1578,7 @@ namespace keepass2android
|
|||||||
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
if (PreferenceManager.GetDefaultSharedPreferences(this)
|
||||||
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
|
.GetBoolean(GetString(Resource.String.UseKp2aKeyboardInKp2a_key), false))
|
||||||
{
|
{
|
||||||
|
Kp2aLog.Log("Activating keyboard in PasswordActivity due to UseKp2aKeyboardInKp2a");
|
||||||
CopyToClipboardService.ActivateKeyboard(this);
|
CopyToClipboardService.ActivateKeyboard(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1224,6 +1224,9 @@
|
|||||||
<string name="enable_fingerprint_hint">Keepass2Android has detected biometric hardware. Do you want to enable Biometric Unlock for this database?</string>
|
<string name="enable_fingerprint_hint">Keepass2Android has detected biometric hardware. Do you want to enable Biometric Unlock for this database?</string>
|
||||||
<string name="post_notifications_dialog_title">Allow notifications</string>
|
<string name="post_notifications_dialog_title">Allow notifications</string>
|
||||||
<string name="post_notifications_dialog_message">Keepass2Android can show notifications with buttons to copy values like passwords and TOTPs to clipboard, or to bring up the built-in keyboard. This is useful to transfer values into other apps without switching to Keepass2Android repeatedly. Do you want to enable such notifications?</string>
|
<string name="post_notifications_dialog_message">Keepass2Android can show notifications with buttons to copy values like passwords and TOTPs to clipboard, or to bring up the built-in keyboard. This is useful to transfer values into other apps without switching to Keepass2Android repeatedly. Do you want to enable such notifications?</string>
|
||||||
|
<string name="post_notifications_snackbar">Cannot make entry available through notification. No permission granted.</string>
|
||||||
|
<string name="post_notifications_snackbar_config">Configure</string>
|
||||||
|
|
||||||
<string name="post_notifications_dialog_allow">Allow notifications</string>
|
<string name="post_notifications_dialog_allow">Allow notifications</string>
|
||||||
<string name="post_notifications_dialog_disable">Disable this feature</string>
|
<string name="post_notifications_dialog_disable">Disable this feature</string>
|
||||||
<string name="post_notifications_dialog_notnow">Not now</string>
|
<string name="post_notifications_dialog_notnow">Not now</string>
|
||||||
|
@@ -328,6 +328,7 @@ namespace keepass2android
|
|||||||
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
if (prefs.GetBoolean("kp2a_switch_rooted", false))
|
||||||
{
|
{
|
||||||
activationCondition = ActivationCondition.Always;
|
activationCondition = ActivationCondition.Always;
|
||||||
|
Kp2aLog.Log("Will activate keyboard because SearchUrlTask opened with ActionSend and kp2a_switch_rooted");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -336,6 +337,7 @@ namespace keepass2android
|
|||||||
if (prefs.GetBoolean(this.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), this.Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
if (prefs.GetBoolean(this.GetString(Resource.String.OpenKp2aKeyboardAutomatically_key), this.Resources.GetBoolean(Resource.Boolean.OpenKp2aKeyboardAutomatically_default)))
|
||||||
{
|
{
|
||||||
activationCondition = ActivationCondition.Always;
|
activationCondition = ActivationCondition.Always;
|
||||||
|
Kp2aLog.Log("Will activate keyboard because SearchUrlTask opened with ActionSend and OpenKp2aKeyboardAutomatically");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -355,6 +355,10 @@ namespace keepass2android
|
|||||||
activity.GetString(Resource.String
|
activity.GetString(Resource.String
|
||||||
.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false);
|
||||||
|
|
||||||
|
Kp2aLog.Log($"AppTask.CompleteOnCreateEntryActivity. ActivateKeyboard={activateKeyboard}, kp2a_switch_rooted={prefs.GetBoolean("kp2a_switch_rooted", false)}, OpenKp2aKeyboardAutomaticallyOnlyAfterSearch={prefs.GetBoolean(
|
||||||
|
activity.GetString(Resource.String
|
||||||
|
.OpenKp2aKeyboardAutomaticallyOnlyAfterSearch_key), false)}");
|
||||||
|
|
||||||
activity.StartNotificationsService(activateKeyboard);
|
activity.StartNotificationsService(activateKeyboard);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -622,6 +626,7 @@ namespace keepass2android
|
|||||||
bool isTotpEntry = totpPluginAdapter != null;
|
bool isTotpEntry = totpPluginAdapter != null;
|
||||||
|
|
||||||
bool activateKeyboard = ActivateKeyboard == ActivationCondition.Always || (ActivateKeyboard == ActivationCondition.WhenTotp && isTotpEntry);
|
bool activateKeyboard = ActivateKeyboard == ActivationCondition.Always || (ActivateKeyboard == ActivationCondition.WhenTotp && isTotpEntry);
|
||||||
|
Kp2aLog.Log($"activateKeyboard == {activateKeyboard}. Task.Activate=={ActivateKeyboard}, isTotpEntry={isTotpEntry}");
|
||||||
|
|
||||||
if ((ShowUserNotifications == ActivationCondition.Always)
|
if ((ShowUserNotifications == ActivationCondition.Always)
|
||||||
|| ((ShowUserNotifications == ActivationCondition.WhenTotp) && isTotpEntry)
|
|| ((ShowUserNotifications == ActivationCondition.WhenTotp) && isTotpEntry)
|
||||||
|
@@ -878,6 +878,37 @@ namespace keepass2android
|
|||||||
{
|
{
|
||||||
get { return PackageName + "/keepass2android.softkeyboard.KP2AKeyboard"; }
|
get { return PackageName + "/keepass2android.softkeyboard.KP2AKeyboard"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool IsChannelPermissionGranted(Context context, string channelId)
|
||||||
|
{
|
||||||
|
if (Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(channelId))
|
||||||
|
{
|
||||||
|
NotificationManager? manager =
|
||||||
|
(NotificationManager?)context.GetSystemService(Context.NotificationService)!;
|
||||||
|
NotificationChannel? channel = manager?.GetNotificationChannel(channelId);
|
||||||
|
return channel?.Importance != Android.App.NotificationImportance.None;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool HasEntryNotificationPermissions(Context context, bool activateKeyboard)
|
||||||
|
{
|
||||||
|
if (!NotificationManagerCompat.From(context).AreNotificationsEnabled())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return IsChannelPermissionGranted(context, App.NotificationChannelIdEntry);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BroadcastReceiver(Permission = "keepass2android." + AppNames.PackagePart + ".permission.CopyToClipboard")]
|
[BroadcastReceiver(Permission = "keepass2android." + AppNames.PackagePart + ".permission.CopyToClipboard")]
|
||||||
|
Reference in New Issue
Block a user