30
30
import androidx .navigation .ui .NavigationUI ;
31
31
import androidx .preference .PreferenceManager ;
32
32
33
+ import com .d4rk .androidtutorials .java .BuildConfig ;
33
34
import com .d4rk .androidtutorials .java .R ;
34
35
import com .d4rk .androidtutorials .java .databinding .ActivityMainBinding ;
36
+ import com .d4rk .androidtutorials .java .notifications .managers .AppUpdateNotificationsManager ;
37
+ import com .d4rk .androidtutorials .java .notifications .managers .AppUsageNotificationsManager ;
35
38
import com .d4rk .androidtutorials .java .ui .components .navigation .BottomSheetMenuFragment ;
36
39
import com .d4rk .androidtutorials .java .ui .screens .startup .StartupActivity ;
37
40
import com .d4rk .androidtutorials .java .ui .screens .startup .StartupViewModel ;
38
41
import com .d4rk .androidtutorials .java .ui .screens .support .SupportActivity ;
39
42
import com .d4rk .androidtutorials .java .utils .ConsentUtils ;
40
43
import com .d4rk .androidtutorials .java .utils .EdgeToEdgeDelegate ;
44
+ import com .d4rk .androidtutorials .java .utils .ReviewHelper ;
41
45
import com .google .android .gms .ads .AdRequest ;
42
46
import com .google .android .gms .ads .MobileAds ;
43
47
import com .google .android .material .navigation .NavigationBarView ;
48
52
import com .google .android .play .core .install .InstallStateUpdatedListener ;
49
53
import com .google .android .play .core .install .model .AppUpdateType ;
50
54
import com .google .android .play .core .install .model .InstallStatus ;
55
+ import com .google .android .play .core .install .model .UpdateAvailability ;
51
56
import com .google .android .ump .ConsentInformation ;
52
57
import com .google .android .ump .ConsentRequestParameters ;
53
58
import com .google .android .ump .UserMessagingPlatform ;
@@ -92,6 +97,7 @@ public void onResume(@NonNull LifecycleOwner owner) {
92
97
private NavController navController ;
93
98
private int currentNavIndex ;
94
99
private AppUpdateManager appUpdateManager ;
100
+ private AppUpdateNotificationsManager appUpdateNotificationsManager ;
95
101
private InstallStateUpdatedListener installStateUpdatedListener ;
96
102
private long backPressedTime ;
97
103
@@ -134,6 +140,7 @@ protected void onCreate(Bundle savedInstanceState) {
134
140
}
135
141
136
142
this .appUpdateManager = mainViewModel .getAppUpdateManager ();
143
+ setupUpdateNotifications ();
137
144
138
145
registerInstallStateListener ();
139
146
getLifecycle ().addObserver (lifecycleObserver );
@@ -150,6 +157,8 @@ public void handleOnBackPressed() {
150
157
}
151
158
}
152
159
});
160
+
161
+ checkInAppReview ();
153
162
}
154
163
155
164
private void setupActionBar () {
@@ -238,17 +247,19 @@ private void observeViewModel() {
238
247
.build ();
239
248
240
249
if (useRail ) {
241
- NavigationUI .setupWithNavController (mBinding .navRail , navController );
242
- mBinding .navRail .setOnItemSelectedListener (item -> {
243
- if (item .getItemId () == navController .getCurrentDestination ().getId ()) {
250
+ if (mBinding .navRail != null ) {
251
+ NavigationUI .setupWithNavController (mBinding .navRail , navController );
252
+ mBinding .navRail .setOnItemSelectedListener (item -> {
253
+ if (item .getItemId () == navController .getCurrentDestination ().getId ()) {
254
+ return true ;
255
+ }
256
+ int newIndex = navOrder .get (item .getItemId ());
257
+ NavOptions options = newIndex > currentNavIndex ? forwardOptions : backwardOptions ;
258
+ navController .navigate (item .getItemId (), null , options );
259
+ currentNavIndex = newIndex ;
244
260
return true ;
245
- }
246
- int newIndex = navOrder .get (item .getItemId ());
247
- NavOptions options = newIndex > currentNavIndex ? forwardOptions : backwardOptions ;
248
- navController .navigate (item .getItemId (), null , options );
249
- currentNavIndex = newIndex ;
250
- return true ;
251
- });
261
+ });
262
+ }
252
263
} else {
253
264
NavigationUI .setupWithNavController (navBarView , navController );
254
265
navBarView .setOnItemSelectedListener (item -> {
@@ -299,12 +310,64 @@ public boolean onOptionsItemSelected(android.view.MenuItem item) {
299
310
return super .onOptionsItemSelected (item );
300
311
}
301
312
302
- private void startImmediateUpdate (AppUpdateInfo appUpdateInfo ) {
303
- appUpdateManager .startUpdateFlowForResult (
304
- appUpdateInfo ,
305
- updateActivityResultLauncher ,
306
- AppUpdateOptions .newBuilder (AppUpdateType .IMMEDIATE ).build ()
313
+ @ Override
314
+ protected void onResume () {
315
+ super .onResume ();
316
+ AppUsageNotificationsManager appUsageNotificationsManager = new AppUsageNotificationsManager (this );
317
+ appUsageNotificationsManager .scheduleAppUsageCheck ();
318
+ if (Build .VERSION .SDK_INT >= Build .VERSION_CODES .O ) {
319
+ appUpdateNotificationsManager .checkAndSendUpdateNotification ();
320
+ }
321
+ checkForFlexibleOrImmediateUpdate ();
322
+ }
323
+
324
+ private void checkForFlexibleOrImmediateUpdate () {
325
+ appUpdateManager .getAppUpdateInfo ().addOnSuccessListener (appUpdateInfo -> {
326
+ boolean updateAvailable = appUpdateInfo .updateAvailability () == UpdateAvailability .UPDATE_AVAILABLE ;
327
+ if (updateAvailable ) {
328
+ startImmediateUpdate (appUpdateInfo );
329
+ }
330
+ })
331
+ .addOnFailureListener (e -> {
332
+ if (!BuildConfig .DEBUG ) {
333
+ Snackbar .make (
334
+ findViewById (android .R .id .content ),
335
+ getString (R .string .snack_general_error ),
336
+ Snackbar .LENGTH_LONG
337
+ ).show ();
338
+ }
339
+ });
340
+ }
341
+
342
+ private void checkInAppReview () {
343
+ SharedPreferences prefs = PreferenceManager .getDefaultSharedPreferences (this );
344
+ int sessionCount = prefs .getInt (getString (R .string .key_session_count ), 0 );
345
+ boolean hasPrompted = prefs .getBoolean (getString (R .string .key_has_prompted_review ), false );
346
+
347
+ ReviewHelper .launchInAppReviewIfEligible (
348
+ this ,
349
+ sessionCount ,
350
+ hasPrompted ,
351
+ () -> prefs .edit ().putBoolean (getString (R .string .key_has_prompted_review ), true ).apply ()
307
352
);
353
+
354
+ prefs .edit ().putInt (getString (R .string .key_session_count ), sessionCount + 1 ).apply ();
355
+ }
356
+
357
+ private void startImmediateUpdate (AppUpdateInfo appUpdateInfo ) {
358
+ try {
359
+ appUpdateManager .startUpdateFlowForResult (
360
+ appUpdateInfo ,
361
+ updateActivityResultLauncher ,
362
+ AppUpdateOptions .newBuilder (AppUpdateType .IMMEDIATE ).build ()
363
+ );
364
+ } catch (Exception e ) {
365
+ Log .e ("MainActivity" , "Error starting in-app update" , e );
366
+ }
367
+ }
368
+
369
+ private void setupUpdateNotifications () {
370
+ appUpdateNotificationsManager = new AppUpdateNotificationsManager (this );
308
371
}
309
372
310
373
private void registerInstallStateListener () {
0 commit comments