@ -1,24 +1,31 @@
package com.fox2code.mmm ;
import android.Manifest ;
import android.annotation.SuppressLint ;
import android.content.Intent ;
import android.content.SharedPreferences ;
import android.content.pm.PackageManager ;
import android.content.res.Configuration ;
import android.content.res.Resources ;
import android.graphics.Color ;
import android.graphics.drawable.ColorDrawable ;
import android.net.Uri ;
import android.os.Build ;
import android.os.Bundle ;
import android.provider.Settings ;
import android.util.Log ;
import android.util.TypedValue ;
import android.view.View ;
import android.view.WindowManager ;
import android.view.inputmethod.EditorInfo ;
import android.widget.CheckBox ;
import android.widget.TextView ;
import androidx.annotation.NonNull ;
import androidx.appcompat.app.AlertDialog ;
import androidx.appcompat.widget.SearchView ;
import androidx.cardview.widget.CardView ;
import androidx.core.app.NotificationManagerCompat ;
import androidx.core.content.ContextCompat ;
import androidx.core.graphics.ColorUtils ;
import androidx.preference.PreferenceManager ;
@ -46,9 +53,7 @@ import com.google.android.material.progressindicator.LinearProgressIndicator;
import eightbitlab.com.blurview.BlurView ;
public class MainActivity extends FoxActivity implements SwipeRefreshLayout . OnRefreshListener ,
SearchView . OnQueryTextListener , SearchView . OnCloseListener ,
OverScrollManager . OverScrollHelper {
public class MainActivity extends FoxActivity implements SwipeRefreshLayout . OnRefreshListener , SearchView . OnQueryTextListener , SearchView . OnCloseListener , OverScrollManager . OverScrollHelper {
private static final String TAG = "MainActivity" ;
private static final int PRECISION = 10000 ;
public static boolean noodleDebugState = BuildConfig . DEBUG ;
@ -93,9 +98,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
} , R . string . pref_category_settings ) ;
setContentView ( R . layout . activity_main ) ;
this . setTitle ( R . string . app_name ) ;
this . getWindow ( ) . setFlags (
WindowManager . LayoutParams . FLAG_TRANSLUCENT_NAVIGATION ,
WindowManager . LayoutParams . FLAG_TRANSLUCENT_NAVIGATION ) ;
this . getWindow ( ) . setFlags ( WindowManager . LayoutParams . FLAG_TRANSLUCENT_NAVIGATION , WindowManager . LayoutParams . FLAG_TRANSLUCENT_NAVIGATION ) ;
setActionBarBackground ( null ) ;
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . P ) {
WindowManager . LayoutParams layoutParams = this . getWindow ( ) . getAttributes ( ) ;
@ -108,10 +111,8 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
this . actionBarBackground = new ColorDrawable ( Color . TRANSPARENT ) ;
this . progressIndicator = findViewById ( R . id . progress_bar ) ;
this . swipeRefreshLayout = findViewById ( R . id . swipe_refresh ) ;
this . swipeRefreshLayoutOrigStartOffset =
this . swipeRefreshLayout . getProgressViewStartOffset ( ) ;
this . swipeRefreshLayoutOrigEndOffset =
this . swipeRefreshLayout . getProgressViewEndOffset ( ) ;
this . swipeRefreshLayoutOrigStartOffset = this . swipeRefreshLayout . getProgressViewStartOffset ( ) ;
this . swipeRefreshLayoutOrigEndOffset = this . swipeRefreshLayout . getProgressViewEndOffset ( ) ;
this . swipeRefreshBlocker = Long . MAX_VALUE ;
this . moduleList = findViewById ( R . id . module_list ) ;
this . searchCard = findViewById ( R . id . search_card ) ;
@ -134,8 +135,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
} ) ;
this . searchCard . setRadius ( this . searchCard . getHeight ( ) / 2F ) ;
this . searchView . setMinimumHeight ( FoxDisplay . dpToPixel ( 16 ) ) ;
this . searchView . setImeOptions ( EditorInfo . IME_ACTION_SEARCH |
EditorInfo . IME_FLAG_NO_FULLSCREEN ) ;
this . searchView . setImeOptions ( EditorInfo . IME_ACTION_SEARCH | EditorInfo . IME_FLAG_NO_FULLSCREEN ) ;
this . searchView . setOnQueryTextListener ( this ) ;
this . searchView . setOnCloseListener ( this ) ;
this . searchView . setOnQueryTextFocusChangeListener ( ( v , h ) - > {
@ -155,8 +155,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
@Override
public void onPathReceived ( String path ) {
Log . i ( TAG , "Got magisk path: " + path ) ;
if ( InstallerInitializer . peekMagiskVersion ( ) <
Constants . MAGISK_VER_CODE_INSTALL_COMMAND )
if ( InstallerInitializer . peekMagiskVersion ( ) < Constants . MAGISK_VER_CODE_INSTALL_COMMAND )
moduleViewListBuilder . addNotification ( NotificationType . MAGISK_OUTDATED ) ;
if ( ! MainApplication . isShowcaseMode ( ) )
moduleViewListBuilder . addNotification ( NotificationType . INSTALL_FROM_STORAGE ) ;
@ -166,8 +165,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
ensurePermissions ( ) ;
noodleDebug . pop ( ) ;
ModuleManager . getINSTANCE ( ) . scan ( ) ;
ModuleManager . getINSTANCE ( ) . runAfterScan (
moduleViewListBuilder : : appendInstalledModules ) ;
ModuleManager . getINSTANCE ( ) . runAfterScan ( moduleViewListBuilder : : appendInstalledModules ) ;
this . commonNext ( ) ;
}
@ -176,8 +174,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
Log . i ( TAG , "Failed to get magisk path!" ) ;
noodleDebug . setEnabled ( noodleDebugState ) ;
noodleDebug . bind ( ) ;
moduleViewListBuilder . addNotification (
InstallerInitializer . getErrorNotification ( ) ) ;
moduleViewListBuilder . addNotification ( InstallerInitializer . getErrorNotification ( ) ) ;
this . commonNext ( ) ;
}
@ -206,11 +203,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
noodleDebug . replace ( "Check Update Compat" ) ;
AppUpdateManager . getAppUpdateManager ( ) . checkUpdateCompat ( ) ;
noodleDebug . replace ( "Check Update" ) ;
RepoManager . getINSTANCE ( ) . update ( value - > runOnUiThread ( max = = 0 ? ( ) - >
progressIndicator . setProgressCompat (
( int ) ( value * PRECISION ) , true ) : ( ) - >
progressIndicator . setProgressCompat (
( int ) ( value * PRECISION * 0.75F ) , true ) ) ) ;
RepoManager . getINSTANCE ( ) . update ( value - > runOnUiThread ( max = = 0 ? ( ) - > progressIndicator . setProgressCompat ( ( int ) ( value * PRECISION ) , true ) : ( ) - > progressIndicator . setProgressCompat ( ( int ) ( value * PRECISION * 0.75F ) , true ) ) ) ;
NotificationType . NEED_CAPTCHA_ANDROIDACY . autoAdd ( moduleViewListBuilder ) ;
if ( ! NotificationType . NO_INTERNET . shouldRemove ( ) ) {
moduleViewListBuilder . addNotification ( NotificationType . NO_INTERNET ) ;
@ -224,21 +217,17 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
if ( max ! = 0 ) {
int current = 0 ;
noodleDebug . push ( "" ) ;
for ( LocalModuleInfo localModuleInfo :
ModuleManager . getINSTANCE ( ) . getModules ( ) . values ( ) ) {
for ( LocalModuleInfo localModuleInfo : ModuleManager . getINSTANCE ( ) . getModules ( ) . values ( ) ) {
if ( localModuleInfo . updateJson ! = null ) {
noodleDebug . replace ( localModuleInfo . id ) ;
try {
localModuleInfo . checkModuleUpdate ( ) ;
} catch ( Exception e ) {
Log . e ( "MainActivity" , "Failed to fetch update of: "
+ localModuleInfo . id , e ) ;
Log . e ( "MainActivity" , "Failed to fetch update of: " + localModuleInfo . id , e ) ;
}
current + + ;
final int currentTmp = current ;
runOnUiThread ( ( ) - > progressIndicator . setProgressCompat (
( int ) ( ( 1F * currentTmp / max ) * PRECISION * 0.25F
+ ( PRECISION * 0.75F ) ) , true ) ) ;
runOnUiThread ( ( ) - > progressIndicator . setProgressCompat ( ( int ) ( ( 1F * currentTmp / max ) * PRECISION * 0.25F + ( PRECISION * 0.75F ) ) , true ) ) ;
}
}
noodleDebug . pop ( ) ;
@ -252,8 +241,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
updateScreenInsets ( getResources ( ) . getConfiguration ( ) ) ;
} ) ;
noodleDebug . replace ( "Apply" ) ;
RepoManager . getINSTANCE ( ) . runAfterUpdate (
moduleViewListBuilder : : appendRemoteModules ) ;
RepoManager . getINSTANCE ( ) . runAfterUpdate ( moduleViewListBuilder : : appendRemoteModules ) ;
moduleViewListBuilder . applyTo ( moduleList , moduleViewAdapter ) ;
noodleDebug . pop ( ) ;
Log . i ( TAG , "Finished app opening state!" ) ;
@ -266,8 +254,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
private void cardIconifyUpdate ( ) {
boolean iconified = this . searchView . isIconified ( ) ;
int backgroundAttr = iconified ? MainApplication . isMonetEnabled ( ) ?
R . attr . colorSecondaryContainer : // Monet is special...
int backgroundAttr = iconified ? MainApplication . isMonetEnabled ( ) ? R . attr . colorSecondaryContainer : // Monet is special...
R . attr . colorSecondary : R . attr . colorPrimarySurface ;
Resources . Theme theme = this . searchCard . getContext ( ) . getTheme ( ) ;
TypedValue value = new TypedValue ( ) ;
@ -277,48 +264,38 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
}
private void updateScreenInsets ( ) {
this . runOnUiThread ( ( ) - > this . updateScreenInsets (
this . getResources ( ) . getConfiguration ( ) ) ) ;
this . runOnUiThread ( ( ) - > this . updateScreenInsets ( this . getResources ( ) . getConfiguration ( ) ) ) ;
}
private void updateScreenInsets ( Configuration configuration ) {
boolean landscape = configuration . orientation = =
Configuration . ORIENTATION_LANDSCAPE ;
boolean landscape = configuration . orientation = = Configuration . ORIENTATION_LANDSCAPE ;
int bottomInset = ( landscape ? 0 : this . getNavigationBarHeight ( ) ) ;
int statusBarHeight = getStatusBarHeight ( ) ;
int actionBarHeight = getActionBarHeight ( ) ;
int combinedBarsHeight = statusBarHeight + actionBarHeight ;
this . actionBarPadding . setMinHeight ( combinedBarsHeight ) ;
this . swipeRefreshLayout . setProgressViewOffset ( false ,
swipeRefreshLayoutOrigStartOffset + combinedBarsHeight ,
swipeRefreshLayoutOrigEndOffset + combinedBarsHeight ) ;
this . moduleViewListBuilder . setHeaderPx ( Math . max ( statusBarHeight ,
combinedBarsHeight - FoxDisplay . dpToPixel ( 4 ) ) ) ;
this . moduleViewListBuilder . setFooterPx ( FoxDisplay . dpToPixel ( 4 ) +
bottomInset + this . searchCard . getHeight ( ) ) ;
this . swipeRefreshLayout . setProgressViewOffset ( false , swipeRefreshLayoutOrigStartOffset + combinedBarsHeight , swipeRefreshLayoutOrigEndOffset + combinedBarsHeight ) ;
this . moduleViewListBuilder . setHeaderPx ( Math . max ( statusBarHeight , combinedBarsHeight - FoxDisplay . dpToPixel ( 4 ) ) ) ;
this . moduleViewListBuilder . setFooterPx ( FoxDisplay . dpToPixel ( 4 ) + bottomInset + this . searchCard . getHeight ( ) ) ;
this . searchCard . setRadius ( this . searchCard . getHeight ( ) / 2F ) ;
this . moduleViewListBuilder . updateInsets ( ) ;
//this.actionBarBlur.invalidate();
this . overScrollInsetTop = combinedBarsHeight ;
this . overScrollInsetBottom = bottomInset ;
Log . d ( TAG , "( " + bottomInset + ", " +
this . searchCard . getHeight ( ) + ")" ) ;
Log . d ( TAG , "( " + bottomInset + ", " + this . searchCard . getHeight ( ) + ")" ) ;
}
private void updateBlurState ( ) {
boolean isLightMode = this . isLightTheme ( ) ;
int colorBackground ;
try {
colorBackground = this . getColorCompat (
android . R . attr . windowBackground ) ;
colorBackground = this . getColorCompat ( android . R . attr . windowBackground ) ;
} catch ( Resources . NotFoundException e ) {
colorBackground = this . getColorCompat ( isLightMode ?
R . color . white : R . color . black ) ;
colorBackground = this . getColorCompat ( isLightMode ? R . color . white : R . color . black ) ;
}
if ( MainApplication . isBlurEnabled ( ) ) {
this . actionBarBlur . setBlurEnabled ( true ) ;
this . actionBarBackground . setColor ( ColorUtils
. setAlphaComponent ( colorBackground , 0x02 ) ) ;
this . actionBarBackground . setColor ( ColorUtils . setAlphaComponent ( colorBackground , 0x02 ) ) ;
this . actionBarBackground . setColor ( Color . TRANSPARENT ) ;
} else {
this . actionBarBlur . setBlurEnabled ( false ) ;
@ -346,23 +323,20 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
InstallerInitializer . tryGetMagiskPathAsync ( new InstallerInitializer . Callback ( ) {
@Override
public void onPathReceived ( String path ) {
if ( InstallerInitializer . peekMagiskVersion ( ) <
Constants . MAGISK_VER_CODE_INSTALL_COMMAND )
if ( InstallerInitializer . peekMagiskVersion ( ) < Constants . MAGISK_VER_CODE_INSTALL_COMMAND )
moduleViewListBuilder . addNotification ( NotificationType . MAGISK_OUTDATED ) ;
if ( ! MainApplication . isShowcaseMode ( ) )
moduleViewListBuilder . addNotification ( NotificationType . INSTALL_FROM_STORAGE ) ;
noodleDebug . setEnabled ( noodleDebugState ) ;
noodleDebug . bind ( ) ;
ModuleManager . getINSTANCE ( ) . scan ( ) ;
ModuleManager . getINSTANCE ( ) . runAfterScan (
moduleViewListBuilder : : appendInstalledModules ) ;
ModuleManager . getINSTANCE ( ) . runAfterScan ( moduleViewListBuilder : : appendInstalledModules ) ;
this . commonNext ( ) ;
}
@Override
public void onFailure ( int error ) {
moduleViewListBuilder . addNotification (
InstallerInitializer . getErrorNotification ( ) ) ;
moduleViewListBuilder . addNotification ( InstallerInitializer . getErrorNotification ( ) ) ;
noodleDebug . setEnabled ( noodleDebugState ) ;
noodleDebug . bind ( ) ;
this . commonNext ( ) ;
@ -386,17 +360,14 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
progressIndicator . setMax ( PRECISION ) ;
} ) ;
noodleDebug . replace ( "Check Update" ) ;
RepoManager . getINSTANCE ( ) . update ( value - > runOnUiThread ( ( ) - >
progressIndicator . setProgressCompat (
( int ) ( value * PRECISION ) , true ) ) ) ;
RepoManager . getINSTANCE ( ) . update ( value - > runOnUiThread ( ( ) - > progressIndicator . setProgressCompat ( ( int ) ( value * PRECISION ) , true ) ) ) ;
runOnUiThread ( ( ) - > {
progressIndicator . setProgressCompat ( PRECISION , true ) ;
progressIndicator . setVisibility ( View . GONE ) ;
} ) ;
}
noodleDebug . replace ( "Apply" ) ;
RepoManager . getINSTANCE ( ) . runAfterUpdate (
moduleViewListBuilder : : appendRemoteModules ) ;
RepoManager . getINSTANCE ( ) . runAfterUpdate ( moduleViewListBuilder : : appendRemoteModules ) ;
Log . i ( TAG , "Common Before applyTo" ) ;
moduleViewListBuilder . applyTo ( moduleList , moduleViewAdapter ) ;
noodleDebug . pop ( ) ;
@ -414,9 +385,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
@Override
public void onRefresh ( ) {
if ( this . swipeRefreshBlocker > System . currentTimeMillis ( ) | |
this . initMode | | this . progressIndicator = = null | |
this . progressIndicator . getVisibility ( ) = = View . VISIBLE ) {
if ( this . swipeRefreshBlocker > System . currentTimeMillis ( ) | | this . initMode | | this . progressIndicator = = null | | this . progressIndicator . getVisibility ( ) = = View . VISIBLE ) {
this . swipeRefreshLayout . setRefreshing ( false ) ;
return ; // Do not double scan
}
@ -430,11 +399,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
Http . cleanDnsCache ( ) ; // Allow DNS reload from network
noodleDebug . push ( "Check Update" ) ;
final int max = ModuleManager . getINSTANCE ( ) . getUpdatableModuleCount ( ) ;
RepoManager . getINSTANCE ( ) . update ( value - > runOnUiThread ( max = = 0 ? ( ) - >
progressIndicator . setProgressCompat (
( int ) ( value * PRECISION ) , true ) : ( ) - >
progressIndicator . setProgressCompat (
( int ) ( value * PRECISION * 0.75F ) , true ) ) ) ;
RepoManager . getINSTANCE ( ) . update ( value - > runOnUiThread ( max = = 0 ? ( ) - > progressIndicator . setProgressCompat ( ( int ) ( value * PRECISION ) , true ) : ( ) - > progressIndicator . setProgressCompat ( ( int ) ( value * PRECISION * 0.75F ) , true ) ) ) ;
NotificationType . NEED_CAPTCHA_ANDROIDACY . autoAdd ( moduleViewListBuilder ) ;
if ( ! NotificationType . NO_INTERNET . shouldRemove ( ) ) {
moduleViewListBuilder . addNotification ( NotificationType . NO_INTERNET ) ;
@ -448,21 +413,17 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
if ( max ! = 0 ) {
int current = 0 ;
noodleDebug . push ( "" ) ;
for ( LocalModuleInfo localModuleInfo :
ModuleManager . getINSTANCE ( ) . getModules ( ) . values ( ) ) {
for ( LocalModuleInfo localModuleInfo : ModuleManager . getINSTANCE ( ) . getModules ( ) . values ( ) ) {
if ( localModuleInfo . updateJson ! = null ) {
noodleDebug . replace ( localModuleInfo . id ) ;
try {
localModuleInfo . checkModuleUpdate ( ) ;
} catch ( Exception e ) {
Log . e ( "MainActivity" , "Failed to fetch update of: "
+ localModuleInfo . id , e ) ;
Log . e ( "MainActivity" , "Failed to fetch update of: " + localModuleInfo . id , e ) ;
}
current + + ;
final int currentTmp = current ;
runOnUiThread ( ( ) - > progressIndicator . setProgressCompat (
( int ) ( ( 1F * currentTmp / max ) * PRECISION * 0.25F
+ ( PRECISION * 0.75F ) ) , true ) ) ;
runOnUiThread ( ( ) - > progressIndicator . setProgressCompat ( ( int ) ( ( 1F * currentTmp / max ) * PRECISION * 0.25F + ( PRECISION * 0.75F ) ) , true ) ) ;
}
}
noodleDebug . pop ( ) ;
@ -478,8 +439,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
this . moduleViewListBuilder . addNotification ( NotificationType . NO_INTERNET ) ;
}
RepoManager . getINSTANCE ( ) . updateEnabledStates ( ) ;
RepoManager . getINSTANCE ( ) . runAfterUpdate (
moduleViewListBuilder : : appendRemoteModules ) ;
RepoManager . getINSTANCE ( ) . runAfterUpdate ( moduleViewListBuilder : : appendRemoteModules ) ;
this . moduleViewListBuilder . applyTo ( moduleList , moduleViewAdapter ) ;
noodleDebug . pop ( ) ;
noodleDebug . unbind ( ) ;
@ -491,8 +451,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
this . searchView . clearFocus ( ) ;
if ( this . initMode ) return false ;
if ( this . moduleViewListBuilder . setQueryChange ( query ) ) {
new Thread ( ( ) - > this . moduleViewListBuilder . applyTo (
moduleList , moduleViewAdapter ) , "Query update thread" ) . start ( ) ;
new Thread ( ( ) - > this . moduleViewListBuilder . applyTo ( moduleList , moduleViewAdapter ) , "Query update thread" ) . start ( ) ;
}
return true ;
}
@ -501,8 +460,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
public boolean onQueryTextChange ( String query ) {
if ( this . initMode ) return false ;
if ( this . moduleViewListBuilder . setQueryChange ( query ) ) {
new Thread ( ( ) - > this . moduleViewListBuilder . applyTo (
moduleList , moduleViewAdapter ) , "Query update thread" ) . start ( ) ;
new Thread ( ( ) - > this . moduleViewListBuilder . applyTo ( moduleList , moduleViewAdapter ) , "Query update thread" ) . start ( ) ;
}
return false ;
}
@ -511,8 +469,7 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
public boolean onClose ( ) {
if ( this . initMode ) return false ;
if ( this . moduleViewListBuilder . setQueryChange ( null ) ) {
new Thread ( ( ) - > this . moduleViewListBuilder . applyTo (
moduleList , moduleViewAdapter ) , "Query update thread" ) . start ( ) ;
new Thread ( ( ) - > this . moduleViewListBuilder . applyTo ( moduleList , moduleViewAdapter ) , "Query update thread" ) . start ( ) ;
}
return false ;
}
@ -527,27 +484,64 @@ public class MainActivity extends FoxActivity implements SwipeRefreshLayout.OnRe
return this . overScrollInsetBottom ;
}
@SuppressLint ( "RestrictedApi" )
private void ensurePermissions ( ) {
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . TIRAMISU & &
ContextCompat . checkSelfPermission ( this ,
Manifest . permission . POST_NOTIFICATIONS ) ! =
PackageManager . PERMISSION_GRANTED ) {
// Show a dialog explaining why we need this permission, which is to show
// notifications for updates
runOnUiThread ( ( ) - > {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder ( this ) ;
builder . setTitle ( R . string . permission_notification_title ) ;
builder . setMessage ( R . string . permission_notification_message ) ;
builder . setPositiveButton ( R . string . permission_notification_grant , ( dialog , which ) - > this . requestPermissions ( new String [ ] {
Manifest . permission . POST_NOTIFICATIONS } , 0 ) ) ;
builder . setNegativeButton ( R . string . cancel , ( dialog , which ) - > {
// Set pref_background_update_check to false and dismiss dialog
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( this ) ;
prefs . edit ( ) . putBoolean ( "pref_background_update_check" , false ) . apply ( ) ;
dialog . dismiss ( ) ;
// First, check if user has said don't ask again by checking if pref_dont_ask_again_notification_permission is true
if ( ! PreferenceManager . getDefaultSharedPreferences ( this ) . getBoolean ( "pref_dont_ask_again_notification_permission" , false ) ) {
if ( Build . VERSION . SDK_INT > = Build . VERSION_CODES . TIRAMISU & & ContextCompat . checkSelfPermission ( this , Manifest . permission . POST_NOTIFICATIONS ) ! = PackageManager . PERMISSION_GRANTED ) {
// Show a dialog explaining why we need this permission, which is to show
// notifications for updates
runOnUiThread ( ( ) - > {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder ( this ) ;
builder . setTitle ( R . string . permission_notification_title ) ;
builder . setMessage ( R . string . permission_notification_message ) ;
// Don't ask again checkbox
View view = getLayoutInflater ( ) . inflate ( R . layout . dialog_checkbox , null ) ;
CheckBox checkBox = view . findViewById ( R . id . checkbox ) ;
checkBox . setText ( R . string . dont_ask_again ) ;
checkBox . setOnCheckedChangeListener ( ( buttonView , isChecked ) - > PreferenceManager . getDefaultSharedPreferences ( this ) . edit ( ) . putBoolean ( "pref_dont_ask_again_notification_permission" , isChecked ) . apply ( ) ) ;
builder . setView ( view ) ;
builder . setPositiveButton ( R . string . permission_notification_grant , ( dialog , which ) - > {
// Request the permission
this . requestPermissions ( new String [ ] { Manifest . permission . POST_NOTIFICATIONS } , 0 ) ;
} ) ;
builder . setNegativeButton ( R . string . cancel , ( dialog , which ) - > {
// Set pref_background_update_check to false and dismiss dialog
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( this ) ;
prefs . edit ( ) . putBoolean ( "pref_background_update_check" , false ) . apply ( ) ;
dialog . dismiss ( ) ;
} ) ;
builder . show ( ) ;
} ) ;
builder . show ( ) ;
} ) ;
// Next branch is for < android 13 and user has blocked notifications
} else if ( Build . VERSION . SDK_INT < Build . VERSION_CODES . TIRAMISU & & ! NotificationManagerCompat . from ( this ) . areNotificationsEnabled ( ) ) {
runOnUiThread ( ( ) - > {
MaterialAlertDialogBuilder builder = new MaterialAlertDialogBuilder ( this ) ;
builder . setTitle ( R . string . permission_notification_title ) ;
builder . setMessage ( R . string . permission_notification_message ) ;
// Don't ask again checkbox
View view = getLayoutInflater ( ) . inflate ( R . layout . dialog_checkbox , null ) ;
CheckBox checkBox = view . findViewById ( R . id . checkbox ) ;
checkBox . setText ( R . string . dont_ask_again ) ;
checkBox . setOnCheckedChangeListener ( ( buttonView , isChecked ) - > PreferenceManager . getDefaultSharedPreferences ( this ) . edit ( ) . putBoolean ( "pref_dont_ask_again_notification_permission" , isChecked ) . apply ( ) ) ;
builder . setView ( view ) ;
builder . setPositiveButton ( R . string . permission_notification_grant , ( dialog , which ) - > {
// Open notification settings
Intent intent = new Intent ( ) ;
intent . setAction ( Settings . ACTION_APPLICATION_DETAILS_SETTINGS ) ;
Uri uri = Uri . fromParts ( "package" , getPackageName ( ) , null ) ;
intent . setData ( uri ) ;
startActivity ( intent ) ;
} ) ;
builder . setNegativeButton ( R . string . cancel , ( dialog , which ) - > {
// Set pref_background_update_check to false and dismiss dialog
SharedPreferences prefs = PreferenceManager . getDefaultSharedPreferences ( this ) ;
prefs . edit ( ) . putBoolean ( "pref_background_update_check" , false ) . apply ( ) ;
dialog . dismiss ( ) ;
} ) ;
builder . show ( ) ;
} ) ;
}
}
}
}