update to targetSdkVersion=33 again, this time with handling of notification permissions (https://developer.android.com/develop/ui/views/notifications/notification-permission)
For now, this is only implemented for entry activity, unlocked/QuickUnlock notifications not tested/implemented yet.
This commit is contained in:
@@ -48,6 +48,8 @@ using KeePassLib.Serialization;
|
||||
using PluginTOTP;
|
||||
using File = Java.IO.File;
|
||||
using Uri = Android.Net.Uri;
|
||||
using keepass2android.fileselect;
|
||||
using Boolean = Java.Lang.Boolean;
|
||||
|
||||
namespace keepass2android
|
||||
{
|
||||
@@ -554,21 +556,90 @@ namespace keepass2android
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
internal void StartNotificationsService(bool activateKeyboard)
|
||||
{
|
||||
Intent showNotIntent = new Intent(this, typeof (CopyToClipboardService));
|
||||
showNotIntent.SetAction(Intents.ShowNotification);
|
||||
showNotIntent.PutExtra(KeyEntry, new ElementAndDatabaseId(App.Kp2a.CurrentDb, Entry).FullId);
|
||||
AppTask.PopulatePasswordAccessServiceIntent(showNotIntent);
|
||||
showNotIntent.PutExtra(KeyActivateKeyboard, activateKeyboard);
|
||||
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
|
||||
{
|
||||
if (permissions.Length == 1 && permissions.First() == Android.Manifest.Permission.PostNotifications &&
|
||||
grantResults.First() == Permission.Granted)
|
||||
{
|
||||
StartNotificationsServiceAfterPermissionsCheck(requestCode == 1 /*requestCode is used to transfer this flag*/);
|
||||
}
|
||||
|
||||
StartService(showNotIntent);
|
||||
}
|
||||
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
internal void StartNotificationsService(bool activateKeyboard)
|
||||
{
|
||||
if (PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
|
||||
GetString(Resource.String.CopyToClipboardNotification_key),
|
||||
Resources.GetBoolean(Resource.Boolean.CopyToClipboardNotification_default)) == false
|
||||
&& PreferenceManager.GetDefaultSharedPreferences(this).GetBoolean(
|
||||
GetString(Resource.String.UseKp2aKeyboard_key),
|
||||
Resources.GetBoolean(Resource.Boolean.UseKp2aKeyboard_default)) == false)
|
||||
{
|
||||
//notifications are disabled
|
||||
return;
|
||||
}
|
||||
|
||||
if ((int)Build.VERSION.SdkInt < 33 || CheckSelfPermission(Android.Manifest.Permission.PostNotifications) ==
|
||||
Permission.Granted)
|
||||
{
|
||||
StartNotificationsServiceAfterPermissionsCheck(activateKeyboard);
|
||||
return;
|
||||
}
|
||||
|
||||
//user has not yet granted Android 13's POST_NOTIFICATONS permission for the app.
|
||||
|
||||
//check if we should ask them to grant:
|
||||
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"
|
||||
{
|
||||
//user has denied permission before. Do not show the dialog. User must give permission in the Android App settings.
|
||||
return;
|
||||
}
|
||||
|
||||
new AlertDialog.Builder(this)
|
||||
.SetTitle(Resource.String.post_notifications_dialog_title)
|
||||
.SetMessage(Resource.String.post_notifications_dialog_message)
|
||||
.SetNegativeButton(Resource.String.post_notifications_dialog_disable, (sender, args) =>
|
||||
{
|
||||
//disable this dialog for the future by disabling the notification preferences
|
||||
var edit= PreferenceManager.GetDefaultSharedPreferences(this).Edit();
|
||||
edit.PutBoolean(GetString(Resource.String.CopyToClipboardNotification_key), false);
|
||||
edit.PutBoolean(GetString(Resource.String.UseKp2aKeyboard_key), false);
|
||||
edit.Commit();
|
||||
})
|
||||
.SetPositiveButton(Resource.String.post_notifications_dialog_allow, (sender, args) =>
|
||||
{
|
||||
|
||||
//remember that we did ask for permission at least once:
|
||||
var edit = PreferenceManager.GetDefaultSharedPreferences(this).Edit();
|
||||
edit.PutBoolean("RequestedPostNotificationsPermission", true);
|
||||
edit.Commit();
|
||||
|
||||
//request permission. user must grant, we'll show notifications in the OnRequestPermissionResults() callback
|
||||
Android.Support.V4.App.ActivityCompat.RequestPermissions(this, new[] { Android.Manifest.Permission.PostNotifications }, activateKeyboard ? 1 : 0 /*use requestCode to transfer the flag*/);
|
||||
|
||||
|
||||
private String getDateTime(DateTime dt)
|
||||
})
|
||||
.SetNeutralButton(Resource.String.post_notifications_dialog_notnow, (sender, args) => { })
|
||||
.Show();
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void StartNotificationsServiceAfterPermissionsCheck(bool activateKeyboard)
|
||||
{
|
||||
Intent showNotIntent = new Intent(this, typeof(CopyToClipboardService));
|
||||
showNotIntent.SetAction(Intents.ShowNotification);
|
||||
showNotIntent.PutExtra(KeyEntry, new ElementAndDatabaseId(App.Kp2a.CurrentDb, Entry).FullId);
|
||||
AppTask.PopulatePasswordAccessServiceIntent(showNotIntent);
|
||||
showNotIntent.PutExtra(KeyActivateKeyboard, activateKeyboard);
|
||||
|
||||
StartService(showNotIntent);
|
||||
}
|
||||
|
||||
|
||||
private String getDateTime(DateTime dt)
|
||||
{
|
||||
return dt.ToLocalTime().ToString("g", CultureInfo.CurrentUICulture);
|
||||
}
|
||||
|
@@ -43,7 +43,7 @@
|
||||
</queries>
|
||||
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_notify_locked" android:label="KP2A entry search" android:name="keepass2android.keepass2android_debug.permission.KP2aInternalSearch" android:protectionLevel="signature" />
|
||||
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android_debug.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
|
||||
<application
|
||||
@@ -258,6 +258,7 @@ The scheme=file is still there for old OS devices. It's also queried by apps lik
|
||||
<uses-permission android:name="keepass2android.keepass2android_debug.permission.KP2aInternalFileBrowsing" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
<!-- Samsung Pass permission -->
|
||||
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
|
||||
<!-- READ_PHONE_STATE seems to come from some library or so, not clear where. We don't want to have it, remove it: -->
|
||||
|
@@ -42,8 +42,8 @@
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
</intent>
|
||||
</queries>
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||
|
||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
||||
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher" android:label="KP2A entry search" android:name="keepass2android.keepass2android.permission.KP2aInternalSearch" android:protectionLevel="signature" />
|
||||
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
|
||||
|
||||
@@ -270,6 +270,7 @@ The scheme=file is still there for old OS devices. It's also queried by apps lik
|
||||
<uses-permission android:name="keepass2android.keepass2android.permission.KP2aInternalSearch" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
|
||||
|
@@ -40,7 +40,7 @@
|
||||
</intent>
|
||||
</queries>
|
||||
|
||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="31" />
|
||||
<uses-sdk android:minSdkVersion="18" android:targetSdkVersion="33" />
|
||||
<permission android:description="@string/permission_desc2" android:icon="@drawable/ic_launcher_offline" android:label="KP2A entry search" android:name="keepass2android.keepass2android_nonet.permission.KP2aInternalSearch" android:protectionLevel="signature" />
|
||||
<permission android:description="@string/permission_desc3" android:icon="@drawable/ic_launcher_offline" android:label="KP2A choose autofill dataset" android:name="keepass2android.keepass2android_nonet.permission.Kp2aChooseAutofill" android:protectionLevel="signature" />
|
||||
<application
|
||||
@@ -243,6 +243,7 @@ The scheme=file is still there for old OS devices. It's also queried by apps lik
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
<uses-permission android:name="android.permission.USE_FINGERPRINT" />
|
||||
<uses-permission android:name="android.permission.USE_BIOMETRIC" />
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
|
||||
|
||||
<uses-feature android:name="android.hardware.camera" android:required="false" />
|
||||
|
||||
|
@@ -1369,6 +1369,12 @@ Initial public release
|
||||
|
||||
<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_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_allow">Allow notifications</string>
|
||||
<string name="post_notifications_dialog_disable">Disable this feature</string>
|
||||
<string name="post_notifications_dialog_notnow">Not now</string>
|
||||
|
||||
<string name="understand">I understand</string>
|
||||
<string name="dont_show_again">Do not show again</string>
|
||||
|
||||
|
@@ -315,7 +315,7 @@ namespace keepass2android
|
||||
}
|
||||
else
|
||||
{
|
||||
//Anrdoid 8 requires that we call StartForeground() shortly after starting the service with StartForegroundService.
|
||||
//Android 8 requires that we call StartForeground() shortly after starting the service with StartForegroundService.
|
||||
//This is not possible when we're closing the service. In this case we don't use the StopSelf in the OngoingNotificationsService.OnStartCommand() anymore but directly stop the service.
|
||||
|
||||
OngoingNotificationsService.CancelNotifications(ctx); //The docs are not 100% clear if OnDestroy() will be called immediately. So make sure the notifications are up to date.
|
||||
|
Reference in New Issue
Block a user