Skip to content

Commit

Permalink
Fix notifications on Android 13+ by asking permission
Browse files Browse the repository at this point in the history
  • Loading branch information
erickok committed Jan 24, 2024
1 parent 77d785c commit 2083d98
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 37 deletions.
4 changes: 2 additions & 2 deletions app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@
<!-- To start rss and torrents background check services -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.VIBRATE" />
<!-- To export settings file to external storage -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- To show torrent and app update notifications -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>

<uses-feature
android:name="android.hardware.touchscreen"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,12 @@

import android.Manifest;
import android.annotation.SuppressLint;
import android.annotation.TargetApi;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.net.Uri;
import android.os.Build;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.TypefaceSpan;
Expand Down Expand Up @@ -60,9 +58,7 @@
@EBean
public class NavigationHelper {

private static final int REQUEST_TORRENT_READ_PERMISSION = 0;
private static final int REQUEST_SETTINGS_READ_PERMISSION = 1;
private static final int REQUEST_SETTINGS_WRITE_PERMISSION = 2;
private static final int REQUEST_NOTIFICATIONS_PERMISSION = 0;

private static ImageLoader imageCache;
@RootContext
Expand Down Expand Up @@ -134,51 +130,39 @@ private static String getQueryParameter(Uri uri, String parameter) {
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))
// Permission already granted
return true;
if (!ActivityCompat.shouldShowRequestPermissionRationale(activity, permission)) {
// Never asked again: show a dialog with an explanation
activity.runOnUiThread(() ->
new AlertDialog.Builder(context)
.setMessage(R.string.permission_readtorrent)
.setMessage(explainer)
.setPositiveButton(android.R.string.ok, (dialog, which) ->
ActivityCompat.requestPermissions(activity, new String[]{permission}, requestCode))
.show());
return false;
}
// 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;
}

private boolean hasPermission(String requiredPermission) {
public boolean hasPermission(String requiredPermission) {
return ContextCompat.checkSelfPermission(context, requiredPermission) == PackageManager.PERMISSION_GRANTED;
}

public Boolean handleTorrentReadPermissionResult(int requestCode, int[] grantResults) {
if (requestCode == REQUEST_TORRENT_READ_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) {
public Boolean handleNotificationPermissionResult(int requestCode, int[] grantResults) {
if (requestCode == REQUEST_NOTIFICATIONS_PERMISSION) {
// Return permission granting result
return grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED;
}
return null;
}

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;
return false;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,19 +21,23 @@
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.os.Bundle;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import org.androidannotations.annotations.Bean;
import org.androidannotations.annotations.EActivity;
import org.androidannotations.annotations.OptionsItem;
import org.transdroid.R;
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.ServerCheckerJob;

@EActivity
public class NotificationSettingsActivity extends PreferenceCompatActivity implements OnSharedPreferenceChangeListener {

@Bean
protected NavigationHelper navigationHelper;
@Bean
protected NotificationSettings notificationSettings;

Expand All @@ -45,9 +49,19 @@ protected void onCreate(Bundle savedInstanceState) {

// Load the notification-related preferences from XML and update availability thereof
addPreferencesFromResource(R.xml.pref_notifications);
boolean disabled = !notificationSettings.isEnabledForRss() && !notificationSettings.isEnabledForTorrents();
updatePrefsEnabled(disabled);
updatePrefsEnabled();

}

@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
Expand Down Expand Up @@ -76,11 +90,18 @@ protected void navigateUp() {

@Override
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());
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_sound").setEnabled(!disabled);
findPreference("notifications_vibrate").setEnabled(!disabled);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
import android.os.Bundle;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.preference.Preference.OnPreferenceClickListener;
import androidx.preference.PreferenceManager;
Expand Down Expand Up @@ -64,6 +65,7 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
protected ErrorLogSender errorLogSender;
@Bean
protected SettingsPersistence settingsPersistence;

private OnPreferenceClickListener onImportSettingsClick = preference -> {
showDialog(DIALOG_IMPORTSETTINGS);
return true;
Expand All @@ -73,7 +75,10 @@ public class SystemSettingsActivity extends PreferenceCompatActivity {
return true;
};
private OnPreferenceClickListener onCheckUpdatesClick = preference -> {
AppUpdateJob.schedule(getApplicationContext());
if (!navigationHelper.checkOrRequestNotificationPermission(this)) {
// Already have permission: continue
AppUpdateJob.schedule(getApplicationContext());
}
return true;
};
private OnPreferenceClickListener onClearSearchClick = preference -> {
Expand Down Expand Up @@ -137,6 +142,15 @@ protected void navigateUp() {
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() {
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
Expand Down
4 changes: 1 addition & 3 deletions app/src/main/res/values/strings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -462,9 +462,7 @@
<item>86400</item>
</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_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="permission_notifications">Transdroid requires permission if you want to receive notifications</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>
Expand Down

0 comments on commit 2083d98

Please sign in to comment.