Request notification permissions when necessary

Co-authored-by: 64391349+tarikbr@users.noreply.github.com
This commit is contained in:
ArtDev
2023-10-18 22:38:26 +03:00
committed by GitHub
8 changed files with 112 additions and 18 deletions

View File

@@ -1,15 +1,20 @@
package net.kdt.pojavlaunch;
import android.Manifest;
import android.app.NotificationManager;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Build;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageButton;
import android.widget.Toast;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AlertDialog;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentContainerView;
@@ -40,6 +45,8 @@ import net.kdt.pojavlaunch.utils.NotificationUtils;
import net.kdt.pojavlaunch.value.launcherprofiles.LauncherProfiles;
import net.kdt.pojavlaunch.value.launcherprofiles.MinecraftProfile;
import java.lang.ref.WeakReference;
public class LauncherActivity extends BaseActivity {
public static final String SETTING_FRAGMENT_TAG = "SETTINGS_FRAGMENT";
@@ -144,13 +151,27 @@ public class LauncherActivity extends BaseActivity {
}
};
private ActivityResultLauncher<String> mRequestNotificationPermissionLauncher;
private WeakReference<Runnable> mRequestNotificationPermissionRunnable;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_pojav_launcher);
IconCacheJanitor.runJanitor();
mRequestNotificationPermissionLauncher = registerForActivityResult(
new ActivityResultContracts.RequestPermission(),
isAllowed -> {
if(!isAllowed) handleNoNotificationPermission();
else {
Runnable runnable = Tools.getWeakReference(mRequestNotificationPermissionRunnable);
if(runnable != null) runnable.run();
}
}
);
getWindow().setBackgroundDrawable(null);
bindViews();
checkNotificationPermission();
mNotificationManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
ProgressKeeper.addTaskCountListener(mDoubleLaunchPreventionListener);
ProgressKeeper.addTaskCountListener((mProgressServiceKeeper = new ProgressServiceKeeper(this)));
@@ -249,6 +270,52 @@ public class LauncherActivity extends BaseActivity {
return null;
}
private void checkNotificationPermission() {
if(LauncherPreferences.PREF_SKIP_NOTIFICATION_PERMISSION_CHECK ||
checkForNotificationPermission()) {
return;
}
if(ActivityCompat.shouldShowRequestPermissionRationale(
this,
Manifest.permission.POST_NOTIFICATIONS)) {
showNotificationPermissionReasoning();
return;
}
askForNotificationPermission(null);
}
private void showNotificationPermissionReasoning() {
new AlertDialog.Builder(this)
.setTitle(R.string.notification_permission_dialog_title)
.setMessage(R.string.notification_permission_dialog_text)
.setPositiveButton(android.R.string.ok, (d, w) -> askForNotificationPermission(null))
.setNegativeButton(android.R.string.cancel, (d, w)-> handleNoNotificationPermission())
.show();
}
private void handleNoNotificationPermission() {
LauncherPreferences.PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = true;
LauncherPreferences.DEFAULT_PREF.edit()
.putBoolean(LauncherPreferences.PREF_KEY_SKIP_NOTIFICATION_CHECK, true)
.apply();
Toast.makeText(this, R.string.notification_permission_toast, Toast.LENGTH_LONG).show();
}
public boolean checkForNotificationPermission() {
return Build.VERSION.SDK_INT < 33 || ContextCompat.checkSelfPermission(
this,
Manifest.permission.POST_NOTIFICATIONS) != PackageManager.PERMISSION_DENIED;
}
public void askForNotificationPermission(Runnable onSuccessRunnable) {
if(Build.VERSION.SDK_INT < 33) return;
if(onSuccessRunnable != null) {
mRequestNotificationPermissionRunnable = new WeakReference<>(onSuccessRunnable);
}
mRequestNotificationPermissionLauncher.launch(Manifest.permission.POST_NOTIFICATIONS);
}
/** Stuff all the view boilerplate here */
private void bindViews(){
mFragmentView = findViewById(R.id.container_fragment);

View File

@@ -75,6 +75,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -1108,6 +1109,11 @@ public final class Tools {
return false;
}
public static <T> T getWeakReference(WeakReference<T> weakReference) {
if(weakReference == null) return null;
return weakReference.get();
}
/** Return the renderers that are compatible with this device */
public static RenderersList getCompatibleRenderers(Context context) {
if(sCompatibleRenderers != null) return sCompatibleRenderers;

View File

@@ -22,12 +22,12 @@ public class ContextExecutor {
}
private static void executeOnUiThread(ContextExecutorTask contextExecutorTask) {
Activity activity = getWeakReference(sActivity);
Activity activity = Tools.getWeakReference(sActivity);
if(activity != null) {
contextExecutorTask.executeWithActivity(activity);
return;
}
Application application = getWeakReference(sApplication);
Application application = Tools.getWeakReference(sApplication);
if(application != null) {
contextExecutorTask.executeWithApplication(application);
}else {
@@ -68,8 +68,5 @@ public class ContextExecutor {
sApplication.clear();
}
private static <T> T getWeakReference(WeakReference<T> weakReference) {
if(weakReference == null) return null;
return weakReference.get();
}
}

View File

@@ -17,6 +17,8 @@ import net.kdt.pojavlaunch.utils.JREUtils;
public class LauncherPreferences {
public static final String PREF_KEY_CURRENT_PROFILE = "currentProfile";
public static final String PREF_KEY_SKIP_NOTIFICATION_CHECK = "skipNotificationPermissionCheck";
public static SharedPreferences DEFAULT_PREF;
public static String PREF_RENDERER = "opengles2";
@@ -64,6 +66,7 @@ public class LauncherPreferences {
public static boolean PREF_VERIFY_MANIFEST = true;
public static String PREF_DOWNLOAD_SOURCE = "default";
public static boolean PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = false;
@@ -109,6 +112,7 @@ public class LauncherPreferences {
PREF_ZINK_PREFER_SYSTEM_DRIVER = DEFAULT_PREF.getBoolean("zinkPreferSystemDriver", false);
PREF_DOWNLOAD_SOURCE = DEFAULT_PREF.getString("downloadSource", "default");
PREF_VERIFY_MANIFEST = DEFAULT_PREF.getBoolean("verifyManifest", true);
PREF_SKIP_NOTIFICATION_PERMISSION_CHECK = DEFAULT_PREF.getBoolean(PREF_KEY_SKIP_NOTIFICATION_CHECK, false);
String argLwjglLibname = "-Dorg.lwjgl.opengl.libname=";
for (String arg : JREUtils.parseJavaArguments(PREF_CUSTOM_JAVA_ARGS)) {

View File

@@ -1,6 +1,7 @@
package net.kdt.pojavlaunch.prefs.screens;
import android.app.Activity;
import android.content.SharedPreferences;
import android.graphics.Color;
import android.os.Bundle;
@@ -11,6 +12,7 @@ import androidx.annotation.Nullable;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import net.kdt.pojavlaunch.LauncherActivity;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.prefs.LauncherPreferences;
@@ -29,6 +31,22 @@ public class LauncherPreferenceFragment extends PreferenceFragmentCompat impleme
@Override
public void onCreatePreferences(Bundle b, String str) {
addPreferencesFromResource(R.xml.pref_main);
setupNotificationRequestPreference();
}
private void setupNotificationRequestPreference() {
Preference mRequestNotificationPermissionPreference = requirePreference("notification_permission_request");
Activity activity = getActivity();
if(activity instanceof LauncherActivity) {
LauncherActivity launcherActivity = (LauncherActivity)activity;
mRequestNotificationPermissionPreference.setVisible(!launcherActivity.checkForNotificationPermission());
mRequestNotificationPermissionPreference.setOnPreferenceClickListener(preference -> {
launcherActivity.askForNotificationPermission(()->mRequestNotificationPermissionPreference.setVisible(false));
return true;
});
}else{
mRequestNotificationPermissionPreference.setVisible(false);
}
}
@Override

View File

@@ -3,14 +3,11 @@ package net.kdt.pojavlaunch.prefs.screens;
import static net.kdt.pojavlaunch.Architecture.is32BitsDevice;
import static net.kdt.pojavlaunch.Tools.getTotalDeviceMemory;
import android.content.Context;
import android.os.Bundle;
import android.widget.TextView;
import androidx.activity.result.ActivityResultLauncher;
import androidx.annotation.NonNull;
import androidx.preference.EditTextPreference;
import androidx.preference.Preference;
import net.kdt.pojavlaunch.R;
import net.kdt.pojavlaunch.Tools;
@@ -21,7 +18,6 @@ import net.kdt.pojavlaunch.prefs.LauncherPreferences;
public class LauncherPreferenceJavaFragment extends LauncherPreferenceFragment {
private MultiRTConfigDialog mDialogScreen;
private Preference mMultiRTPreference;
private final ActivityResultLauncher<Object> mVmInstallLauncher =
registerForActivityResult(new OpenDocumentWithExtension("xz"), (data)->{
if(data != null) Tools.installRuntimeFromUri(getContext(), data);
@@ -52,15 +48,10 @@ public class LauncherPreferenceJavaFragment extends LauncherPreferenceFragment {
editJVMArgs.setOnBindEditTextListener(TextView::setSingleLine);
}
mMultiRTPreference = findPreference("install_jre");
}
@Override
public boolean onPreferenceTreeClick(@NonNull Preference preference) {
if(preference.equals(mMultiRTPreference)) {
requirePreference("install_jre").setOnPreferenceClickListener(preference->{
openMultiRTDialog();
}
return super.onPreferenceTreeClick(preference);
return true;
});
}
private void openMultiRTDialog() {

View File

@@ -359,4 +359,9 @@
<string name="preference_category_main_categories">Categories</string>
<string name="preference_category_miscellaneous">Miscellaneous settings</string>
<string name="preference_category_video">Video settings</string>
<string name="notification_permission_dialog_title">Permission request</string>
<string name="notification_permission_dialog_text">PojavLauncher requires a permission to post notifications to prevent game/modpack downloads from stopping when you leave the app. Without this permission, Android may shut down your downloads when you put PojavLauncher in background mode.</string>
<string name="notification_permission_toast">You can always change your mind later by going into Settings</string>
<string name="preference_ask_for_notification_title">Allow notifications</string>
<string name="preference_ask_for_notification_description">Click to re-request the notification permission, required for game/modpack background downloads to work properly.</string>
</resources>

View File

@@ -60,6 +60,12 @@
android:summary="@string/preference_force_english_description"
/>
<Preference
android:title="@string/preference_ask_for_notification_title"
android:summary="@string/preference_ask_for_notification_description"
android:key="notification_permission_request"
/>