Skip to content

Commit

Permalink
Fix #282: Allow the user to turn on notifications from action bar (#284)
Browse files Browse the repository at this point in the history
  • Loading branch information
TWiStErRob committed Jun 29, 2023
1 parent ee864d7 commit 19e7659
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 4 deletions.
1 change: 1 addition & 0 deletions android/backup/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ dependencies {
implementation(libs.androidx.recyclerview)
implementation(libs.androidx.swiperefreshlayout)
implementation "net.twisterrob.lib:twister-lib-android-monolith"
implementation "net.twisterrob.lib:twister-lib-android-permissions"
implementation "net.twisterrob.lib:twister-lib-android-basics"
implementation "net.twisterrob.lib:twister-lib-android-settings"
implementation "net.twisterrob.lib:twister-lib-general"
Expand Down
4 changes: 3 additions & 1 deletion android/backup/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
<manifest
xmlns:android="http://schemas.android.com/apk/res/android">

<!-- Used by BackupService -->
<!-- Used by BackupService through NotificationProgressService.startNotification(). -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<!-- Used by BackupService through NotificationProgressService.finish(). -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />

<!-- net.twisterrob.inventory.android.fragment.BackupControllerFragment.doImport -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" android:maxSdkVersion="28" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
import org.slf4j.*;

import android.content.*;
import android.os.Build;
import android.os.Bundle;

import androidx.annotation.*;
Expand Down Expand Up @@ -63,10 +64,20 @@ private void setAllowNew(boolean allowNew) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_backup);
controller = getFragment(R.id.backup_controller);
if (Build.VERSION_CODES.TIRAMISU <= Build.VERSION.SDK_INT) {
addMenuProvider(new BackupNotificationsMenu(this));
}

displayPopup(findProgress(savedInstanceState, getIntent()));
}

@Override protected void onResume() {
super.onResume();
if (Build.VERSION_CODES.TIRAMISU <= Build.VERSION.SDK_INT) {
invalidateOptionsMenu();
}
}

private @Nullable Progress findProgress(@Nullable Bundle savedInstanceState, @Nullable Intent intent) {
if (savedInstanceState != null) {
return BundleTools.getSerializable(savedInstanceState, BackupService.EXTRA_PROGRESS, Progress.class);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
package net.twisterrob.inventory.android.activity;

import android.Manifest;
import android.annotation.TargetApi;
import android.os.Build;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.view.MenuProvider;

import net.twisterrob.android.permissions.PermissionProtectedAction;
import net.twisterrob.android.permissions.PermissionState;
import net.twisterrob.android.utils.tools.DialogTools;
import net.twisterrob.inventory.android.backup.R;

@TargetApi(Build.VERSION_CODES.TIRAMISU)
public class BackupNotificationsMenu implements MenuProvider {
private final @NonNull PermissionProtectedAction notifications;

BackupNotificationsMenu(final @NonNull AppCompatActivity activity) {
notifications = new PermissionProtectedAction(
activity,
new String[] {Manifest.permission.POST_NOTIFICATIONS},
new PermissionProtectedAction.PermissionEvents() {
@Override public void granted(@NonNull GrantedReason reason) {
activity.supportInvalidateOptionsMenu(); // Hide the button.
}

@Override public void denied(@NonNull DeniedReason reason) {
activity.supportInvalidateOptionsMenu();
// Nothing to do, backup feature's actions work with or without notifications.
}

@Override public void showRationale(final @NonNull RationaleContinuation continuation) {
DialogTools
.confirm(activity, new DialogTools.PopupCallbacks<Boolean>() {
@Override public void finished(Boolean value) {
if (Boolean.TRUE.equals(value)) {
continuation.rationaleAcceptedRetryRequest();
} else {
continuation.rationaleRejectedCancelProcess();
}
}
})
.setTitle(R.string.backup_permission_notification_rationale_title)
.setMessage(R.string.backup_permission_notification_rationale_body)
.show();
}
}
);
}

@Override public void onCreateMenu(@NonNull Menu menu, @NonNull MenuInflater menuInflater) {
menuInflater.inflate(R.menu.backup_notifications, menu);
}

@Override public void onPrepareMenu(@NonNull Menu menu) {
menu.findItem(R.id.backup_notifications)
.setVisible(notifications.currentState() != PermissionState.GRANTED);
}

@Override public boolean onMenuItemSelected(@NonNull MenuItem menuItem) {
if (menuItem.getItemId() == R.id.backup_notifications) {
notifications.executeBehindPermissions();
return true;
}
return false;
}
}
12 changes: 12 additions & 0 deletions android/backup/src/main/res/menu/backup_notifications.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
<menu
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
>

<item
android:id="@+id/backup_notifications"
android:title="@string/backup_permission_notification_enable"
app:showAsAction="ifRoom|withText"
/>

</menu>
4 changes: 4 additions & 0 deletions android/backup/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@
Without this, you can only use export while on the backup screen.
</string>

<string name="backup_permission_notification_enable">Enable notifications</string>
<string name="backup_permission_notification_rationale_title">Backup notifications</string>
<string name="backup_permission_notification_rationale_body">Allow notifications to get notified when a backup operation continues or completes in the background.</string>

<string name="backup__cancel_partial">Cancelling this operation may result in partial data transfer only. Are you sure you want to cancel?</string>

<string name="backup_export_progress_title">Export</string>
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ dependencies {

android {
defaultConfig {
targetSdk = 31
targetSdk = 33
applicationId 'net.twisterrob.inventory'
version {
major = 1
Expand Down
10 changes: 8 additions & 2 deletions android/src/main/java/net/twisterrob/inventory/android/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ private void startServices() {
// run vacuum next, it's quick and most of the time does nothing anyway
startService(new Intent(DatabaseService.ACTION_VACUUM_INCREMENTAL).setPackage(getPackageName()));
// this may take a while, but it's necessary for correct display of search results
updateLanguage(Locale.getDefault());
updateLocaleDependencies(Locale.getDefault());
// last, preload categories, this would happen when editing and suggestions kick in
// so, prevent a delay on first suggestion, load it in the background
startService(new Intent(DatabaseService.ACTION_PRELOAD_CATEGORIES).setPackage(getPackageName()));
Expand All @@ -93,10 +93,14 @@ private void startServices() {

@Override public void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
updateLanguage(AndroidTools.getLocale(newConfig));
updateLocaleDependencies(AndroidTools.getLocale(newConfig));
// FIXME private static final NumberFormat NUMBER = NumberFormat.getIntegerInstance();
}

private void updateLocaleDependencies(@NonNull Locale newLocale) {
updateLanguage(newLocale);
updateNotificationChannels();
}
private void updateLanguage(@NonNull Locale newLocale) {
try {
startService(new Intent(DatabaseService.ACTION_UPDATE_LANGUAGE)
Expand All @@ -116,6 +120,8 @@ private void updateLanguage(@NonNull Locale newLocale) {
// but that's not available until higher support library or AndroidX.
// So for now, just ignore the exception. Next startup will do this properly anyway.
}
}
private void updateNotificationChannels() {
if (VERSION.SDK_INT >= VERSION_CODES.O) {
BackupNotifications.registerNotificationChannels(this);
}
Expand Down

0 comments on commit 19e7659

Please sign in to comment.