Browse Source

Fix notifications on Android 13+ by asking permission

pull/667/head
Eric Kok 10 months ago
parent
commit
2083d98118
  1. 4
      app/src/main/AndroidManifest.xml
  2. 40
      app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java
  3. 27
      app/src/main/java/org/transdroid/core/gui/settings/NotificationSettingsActivity.java
  4. 16
      app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java
  5. 4
      app/src/main/res/values/strings.xml

4
app/src/main/AndroidManifest.xml

@ -35,8 +35,8 @@
<!-- To start rss and torrents background check services --> <!-- To start rss and torrents background check services -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" /> <uses-permission android:name="android.permission.VIBRATE" />
<!-- To export settings file to external storage --> <!-- To show torrent and app update notifications -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
<uses-feature <uses-feature
android:name="android.hardware.touchscreen" android:name="android.hardware.touchscreen"

40
app/src/main/java/org/transdroid/core/gui/navigation/NavigationHelper.java

@ -18,14 +18,12 @@ package org.transdroid.core.gui.navigation;
import android.Manifest; import android.Manifest;
import android.annotation.SuppressLint; import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity; import android.app.Activity;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.pm.PackageManager; import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo; import android.content.pm.ResolveInfo;
import android.net.Uri; import android.net.Uri;
import android.os.Build;
import android.text.Spannable; import android.text.Spannable;
import android.text.SpannableString; import android.text.SpannableString;
import android.text.style.TypefaceSpan; import android.text.style.TypefaceSpan;
@ -60,9 +58,7 @@ import java.util.List;
@EBean @EBean
public class NavigationHelper { public class NavigationHelper {
private static final int REQUEST_TORRENT_READ_PERMISSION = 0; private static final int REQUEST_NOTIFICATIONS_PERMISSION = 0;
private static final int REQUEST_SETTINGS_READ_PERMISSION = 1;
private static final int REQUEST_SETTINGS_WRITE_PERMISSION = 2;
private static ImageLoader imageCache; private static ImageLoader imageCache;
@RootContext @RootContext
@ -134,7 +130,11 @@ public class NavigationHelper {
return null; return null;
} }
private boolean checkPermission(final Activity activity, final String permission, final int requestCode) { public boolean checkOrRequestNotificationPermission(final Activity activity) {
return checkPermission(activity, Manifest.permission.POST_NOTIFICATIONS, REQUEST_NOTIFICATIONS_PERMISSION, R.string.permission_notifications);
}
private boolean checkPermission(final Activity activity, final String permission, final int requestCode, final int explainer) {
if (hasPermission(permission)) if (hasPermission(permission))
// Permission already granted // Permission already granted
return true; return true;
@ -142,43 +142,27 @@ public class NavigationHelper {
// Never asked again: show a dialog with an explanation // Never asked again: show a dialog with an explanation
activity.runOnUiThread(() -> activity.runOnUiThread(() ->
new AlertDialog.Builder(context) new AlertDialog.Builder(context)
.setMessage(R.string.permission_readtorrent) .setMessage(explainer)
.setPositiveButton(android.R.string.ok, (dialog, which) -> .setPositiveButton(android.R.string.ok, (dialog, which) ->
ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode)) ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode))
.show()); .show());
return false; return false;
} }
// Permission not granted (and we asked for it already before) // Permission not granted (and we asked for it already before)
ActivityCompat.requestPermissions(activity, new String[]{permission}, REQUEST_TORRENT_READ_PERMISSION); ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode);
return false; return false;
} }
private boolean hasPermission(String requiredPermission) { public boolean hasPermission(String requiredPermission) {
return ContextCompat.checkSelfPermission(context, requiredPermission) == PackageManager.PERMISSION_GRANTED; return ContextCompat.checkSelfPermission(context, requiredPermission) == PackageManager.PERMISSION_GRANTED;
} }
public Boolean handleTorrentReadPermissionResult(int requestCode, int[] grantResults) { public Boolean handleNotificationPermissionResult(int requestCode, int[] grantResults) {
if (requestCode == REQUEST_TORRENT_READ_PERMISSION) { if (requestCode == REQUEST_NOTIFICATIONS_PERMISSION) {
// Return permission granting result
return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
}
return null;
}
public Boolean handleSettingsReadPermissionResult(int requestCode, int[] grantResults) {
if (requestCode == REQUEST_SETTINGS_READ_PERMISSION) {
// Return permission granting result // Return permission granting result
return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED; return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
} }
return null; return false;
}
public Boolean handleSettingsWritePermissionResult(int requestCode, int[] grantResults) {
if (requestCode == REQUEST_SETTINGS_WRITE_PERMISSION) {
// Return permission granting result
return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
}
return null;
} }
/** /**

27
app/src/main/java/org/transdroid/core/gui/settings/NotificationSettingsActivity.java

@ -21,6 +21,7 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener; import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle; import android.os.Bundle;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable; import androidx.annotation.Nullable;
import org.androidannotations.annotations.Bean; import org.androidannotations.annotations.Bean;
@ -28,12 +29,15 @@ import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.OptionsItem; import org.androidannotations.annotations.OptionsItem;
import org.transdroid.R; import org.transdroid.R;
import org.transdroid.core.app.settings.NotificationSettings; import org.transdroid.core.app.settings.NotificationSettings;
import org.transdroid.core.gui.navigation.NavigationHelper;
import org.transdroid.core.service.RssCheckerJob; import org.transdroid.core.service.RssCheckerJob;
import org.transdroid.core.service.ServerCheckerJob; import org.transdroid.core.service.ServerCheckerJob;
@EActivity @EActivity
public class NotificationSettingsActivity extends PreferenceCompatActivity implements OnSharedPreferenceChangeListener { public class NotificationSettingsActivity extends PreferenceCompatActivity implements OnSharedPreferenceChangeListener {
@Bean
protected NavigationHelper navigationHelper;
@Bean @Bean
protected NotificationSettings notificationSettings; protected NotificationSettings notificationSettings;
@ -45,9 +49,19 @@ public class NotificationSettingsActivity extends PreferenceCompatActivity imple
// Load the notification-related preferences from XML and update availability thereof // Load the notification-related preferences from XML and update availability thereof
addPreferencesFromResource(R.xml.pref_notifications); addPreferencesFromResource(R.xml.pref_notifications);
boolean disabled = !notificationSettings.isEnabledForRss() && !notificationSettings.isEnabledForTorrents(); updatePrefsEnabled();
updatePrefsEnabled(disabled);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (navigationHelper.handleNotificationPermissionResult(requestCode, grantResults)) {
// Now that we have permission, schedule the jobs
ServerCheckerJob.schedule(getApplicationContext());
RssCheckerJob.schedule(getApplicationContext());
updatePrefsEnabled();
}
} }
@Override @Override
@ -76,11 +90,18 @@ public class NotificationSettingsActivity extends PreferenceCompatActivity imple
@Override @Override
public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) { public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String key) {
boolean needsPermission = notificationSettings.isEnabledForRss() || notificationSettings.isEnabledForTorrents();
if (needsPermission && !navigationHelper.checkOrRequestNotificationPermission(this)) {
return;
}
// Already have permission to show notifications, so update the jobs now
ServerCheckerJob.schedule(getApplicationContext()); ServerCheckerJob.schedule(getApplicationContext());
RssCheckerJob.schedule(getApplicationContext()); RssCheckerJob.schedule(getApplicationContext());
updatePrefsEnabled();
} }
private void updatePrefsEnabled(boolean disabled) { private void updatePrefsEnabled() {
boolean disabled = !notificationSettings.isEnabledForRss() && !notificationSettings.isEnabledForTorrents();
findPreference("notifications_interval").setEnabled(!disabled); findPreference("notifications_interval").setEnabled(!disabled);
findPreference("notifications_sound").setEnabled(!disabled); findPreference("notifications_sound").setEnabled(!disabled);
findPreference("notifications_vibrate").setEnabled(!disabled); findPreference("notifications_vibrate").setEnabled(!disabled);

16
app/src/main/java/org/transdroid/core/gui/settings/SystemSettingsActivity.java

@ -24,6 +24,7 @@ import android.content.SharedPreferences;
import android.os.Bundle; import android.os.Bundle;
import android.text.TextUtils; import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog; import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference.OnPreferenceClickListener; import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceManager; import androidx.preference.PreferenceManager;
@ -64,6 +65,7 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
protected ErrorLogSender errorLogSender; protected ErrorLogSender errorLogSender;
@Bean @Bean
protected SettingsPersistence settingsPersistence; protected SettingsPersistence settingsPersistence;
private OnPreferenceClickListener onImportSettingsClick = preference -> { private OnPreferenceClickListener onImportSettingsClick = preference -> {
showDialog(DIALOG_IMPORTSETTINGS); showDialog(DIALOG_IMPORTSETTINGS);
return true; return true;
@ -73,7 +75,10 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
return true; return true;
}; };
private OnPreferenceClickListener onCheckUpdatesClick = preference -> { private OnPreferenceClickListener onCheckUpdatesClick = preference -> {
AppUpdateJob.schedule(getApplicationContext()); if (!navigationHelper.checkOrRequestNotificationPermission(this)) {
// Already have permission: continue
AppUpdateJob.schedule(getApplicationContext());
}
return true; return true;
}; };
private OnPreferenceClickListener onClearSearchClick = preference -> { private OnPreferenceClickListener onClearSearchClick = preference -> {
@ -137,6 +142,15 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
MainSettingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start(); MainSettingsActivity_.intent(this).flags(Intent.FLAG_ACTIVITY_CLEAR_TOP).start();
} }
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (navigationHelper.handleNotificationPermissionResult(requestCode, grantResults)) {
// Now that we have permission, schedule the job
AppUpdateJob.schedule(getApplicationContext());
}
}
private void importSettingsFromFile() { private void importSettingsFromFile() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE); intent.addCategory(Intent.CATEGORY_OPENABLE);

4
app/src/main/res/values/strings.xml

@ -462,9 +462,7 @@
<item>86400</item> <item>86400</item>
</string-array> </string-array>
<string name="permission_readtorrent">Transdroid requires read access to your file storage in order to read local .torrent files</string> <string name="permission_notifications">Transdroid requires permission if you want to receive notifications</string>
<string name="permission_readsettings">Transdroid requires read access to your file storage if you want to read from a local settings file</string>
<string name="permission_writesettings">Transdroid requires write access to your file storage to write the local settings file</string>
<string name="error_httperror">Error during communication; check your connection</string> <string name="error_httperror">Error during communication; check your connection</string>
<string name="error_unsupported">Your torrent client does not support this operation</string> <string name="error_unsupported">Your torrent client does not support this operation</string>

Loading…
Cancel
Save