1212
1313package com .mindful .android ;
1414
15+ import static com .mindful .android .generics .ServiceBinder .ACTION_START_MINDFUL_SERVICE ;
1516import static com .mindful .android .helpers .NewActivitiesLaunchHelper .INTENT_EXTRA_IS_SELF_RESTART ;
16- import static com .mindful .android .services .EmergencyPauseService .ACTION_START_SERVICE_EMERGENCY ;
17- import static com .mindful .android .services .FocusSessionService .ACTION_START_FOCUS_SERVICE ;
1817import static com .mindful .android .services .OverlayDialogService .INTENT_EXTRA_PACKAGE_NAME ;
1918
20- import android .annotation .SuppressLint ;
21- import android .app .AlarmManager ;
22- import android .content .Context ;
2319import android .content .Intent ;
2420import android .content .res .Configuration ;
25- import android .net .Uri ;
26- import android .os .Build ;
2721import android .os .Bundle ;
28- import android .os .PowerManager ;
29- import android .provider .Settings ;
30- import android .widget .Toast ;
3122
23+ import androidx .activity .result .ActivityResultLauncher ;
24+ import androidx .activity .result .contract .ActivityResultContracts ;
3225import androidx .annotation .NonNull ;
3326import androidx .annotation .Nullable ;
3427
@@ -66,17 +59,29 @@ public class MainActivity extends FlutterFragmentActivity implements MethodChann
6659 private SafeServiceConnection <MindfulTrackerService > mTrackerServiceConn ;
6760 private SafeServiceConnection <MindfulVpnService > mVpnServiceConn ;
6861 private SafeServiceConnection <FocusSessionService > mFocusServiceConn ;
62+ private ActivityResultLauncher <Intent > mVpnPermissionLauncher ;
6963
7064 @ Override
7165 protected void onCreate (Bundle savedInstanceState ) {
7266 super .onCreate (savedInstanceState );
7367
68+ // Store uncaught exceptions
69+ Thread .setDefaultUncaughtExceptionHandler ((thread , exception ) -> SharedPrefsHelper .insertCrashLogToPrefs (this , exception ));
70+
7471 // Register notification channels
7572 NotificationHelper .registerNotificationChannels (this );
7673
7774 // Schedule midnight 12 task if already not scheduled
7875 AlarmTasksSchedulingHelper .scheduleMidnightResetTask (this , true );
7976
77+ // register permission launcher for result
78+ mVpnPermissionLauncher = registerForActivityResult (
79+ new ActivityResultContracts .StartActivityForResult (),
80+ result -> {
81+ // Ignored
82+ }
83+ );
84+
8085 // Initialize service connections
8186 mTrackerServiceConn = new SafeServiceConnection <>(MindfulTrackerService .class , this );
8287 mVpnServiceConn = new SafeServiceConnection <>(MindfulVpnService .class , this );
@@ -152,7 +157,15 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
152157 result .success (true );
153158 break ;
154159 }
155-
160+ case "getNativeCrashLogs" : {
161+ result .success (SharedPrefsHelper .getCrashLogsArrayString (this ));
162+ break ;
163+ }
164+ case "clearNativeCrashLogs" : {
165+ SharedPrefsHelper .clearCrashLogs (this );
166+ result .success (true );
167+ break ;
168+ }
156169 // SECTION: Foreground service and Worker methods ---------------------------------------------------------------------------
157170 case "updateAppRestrictions" : {
158171 HashMap <String , AppRestrictions > appRestrictions = SharedPrefsHelper .getSetAppRestrictions (this , Utils .notNullStr (call .arguments ()));
@@ -172,7 +185,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
172185 mVpnServiceConn .getService ().updateBlockedApps (blockedApps );
173186 } else if (!blockedApps .isEmpty () && getAndAskVpnPermission (false )) {
174187 mVpnServiceConn .setOnConnectedCallback (service -> service .updateBlockedApps (blockedApps ));
175- mVpnServiceConn .startAndBind (MindfulVpnService . ACTION_START_SERVICE_VPN );
188+ mVpnServiceConn .startAndBind ();
176189 }
177190 result .success (true );
178191 break ;
@@ -189,6 +202,9 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
189202 AlarmTasksSchedulingHelper .scheduleBedtimeRoutineTasks (this , bedtimeSettings );
190203 } else {
191204 AlarmTasksSchedulingHelper .cancelBedtimeRoutineTasks (this );
205+ if (bedtimeSettings .shouldStartDnd ) {
206+ NotificationHelper .toggleDnd (this , false );
207+ }
192208 }
193209 result .success (true );
194210 break ;
@@ -197,7 +213,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
197213 if (!Utils .isServiceRunning (this , EmergencyPauseService .class .getName ())
198214 && Utils .isServiceRunning (this , MindfulTrackerService .class .getName ())
199215 ) {
200- startService (new Intent (getApplicationContext (), EmergencyPauseService .class ).setAction (ACTION_START_SERVICE_EMERGENCY ));
216+ startService (new Intent (getApplicationContext (), EmergencyPauseService .class ).setAction (ACTION_START_MINDFUL_SERVICE ));
201217 result .success (true );
202218 } else {
203219 result .success (false );
@@ -210,7 +226,7 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
210226 mFocusServiceConn .getService ().updateFocusSession (focusSession );
211227 } else {
212228 mFocusServiceConn .setOnConnectedCallback (service -> service .startFocusSession (focusSession ));
213- mFocusServiceConn .startAndBind (ACTION_START_FOCUS_SERVICE );
229+ mFocusServiceConn .startAndBind ();
214230 }
215231 result .success (true );
216232 break ;
@@ -246,19 +262,19 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
246262 break ;
247263 }
248264 case "getAndAskIgnoreBatteryOptimizationPermission" : {
249- result .success (getAndAskIgnoreBatteryOptimizationPermission (Boolean .TRUE .equals (call .arguments ())));
250- break ;
251- }
252- case "getAndAskVpnPermission" : {
253- result .success (getAndAskVpnPermission (Boolean .TRUE .equals (call .arguments ())));
265+ result .success (PermissionsHelper .getAndAskIgnoreBatteryOptimizationPermission (this , Boolean .TRUE .equals (call .arguments ())));
254266 break ;
255267 }
256268 case "getAndAskDisplayOverlayPermission" : {
257- result .success (getAndAskDisplayOverlayPermission (Boolean .TRUE .equals (call .arguments ())));
269+ result .success (PermissionsHelper . getAndAskDisplayOverlayPermission (this , Boolean .TRUE .equals (call .arguments ())));
258270 break ;
259271 }
260272 case "getAndAskExactAlarmPermission" : {
261- result .success (getAndAskExactAlarmPermission (Boolean .TRUE .equals (call .arguments ())));
273+ result .success (PermissionsHelper .getAndAskExactAlarmPermission (this , Boolean .TRUE .equals (call .arguments ())));
274+ break ;
275+ }
276+ case "getAndAskVpnPermission" : {
277+ result .success (getAndAskVpnPermission (Boolean .TRUE .equals (call .arguments ())));
262278 break ;
263279 }
264280 case "disableDeviceAdmin" : {
@@ -269,12 +285,12 @@ public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result
269285
270286 // SECTION: New Activity Launch methods ------------------------------------------------------
271287 case "openAppWithPackage" : {
272- NewActivitiesLaunchHelper .openAppWithPackage (this , call .arguments ());
288+ NewActivitiesLaunchHelper .openAppWithPackage (this , Utils . notNullStr ( call .arguments () ));
273289 result .success (true );
274290 break ;
275291 }
276292 case "openAppSettingsForPackage" : {
277- NewActivitiesLaunchHelper .openSettingsForPackage (this , call .arguments ());
293+ NewActivitiesLaunchHelper .openSettingsForPackage (this , Utils . notNullStr ( call .arguments () ));
278294 result .success (true );
279295 break ;
280296 }
@@ -328,7 +344,7 @@ private void updateTrackerServiceRestrictions(
328344 || (restrictionGroups != null && !restrictionGroups .isEmpty ())
329345 ) {
330346 mTrackerServiceConn .setOnConnectedCallback (service -> service .updateRestrictionData (appRestrictions , restrictionGroups ));
331- mTrackerServiceConn .startAndBind (MindfulTrackerService . ACTION_START_RESTRICTION_MODE );
347+ mTrackerServiceConn .startAndBind ();
332348 }
333349 }
334350
@@ -340,77 +356,12 @@ private void updateTrackerServiceRestrictions(
340356 */
341357 private boolean getAndAskVpnPermission (boolean askPermissionToo ) {
342358 Intent intent = MindfulVpnService .prepare (this );
343- if (askPermissionToo && intent != null ) {
344- startActivityForResult (intent , 0 );
359+ if (askPermissionToo && intent != null && mVpnPermissionLauncher != null ) {
360+ mVpnPermissionLauncher . launch (intent );
345361 }
346362 return intent == null ;
347363 }
348364
349- /**
350- * Checks if the Display Over Other Apps permission is granted and optionally asks for it if not granted.
351- *
352- * @param askPermissionToo Whether to prompt the user to enable Display Over Other Apps permission if not granted.
353- * @return True if Display Over Other Apps permission is granted, false otherwise.
354- */
355- private boolean getAndAskDisplayOverlayPermission (boolean askPermissionToo ) {
356- if (Settings .canDrawOverlays (this )) return true ;
357-
358- if (askPermissionToo ) {
359- Intent intent = new Intent (Settings .ACTION_MANAGE_OVERLAY_PERMISSION );
360- intent .setData (android .net .Uri .parse ("package:" + getPackageName ()));
361- startActivityForResult (intent , 0 );
362- Toast .makeText (this , "Please allow Mindful to display overlay" , Toast .LENGTH_LONG ).show ();
363- }
364- return false ;
365- }
366-
367- /**
368- * Checks if the Set Exact Alarm permission is granted and optionally asks for it if not granted.
369- *
370- * @param askPermissionToo Whether to prompt the user to enable Set Exact Alarm permission if not granted.
371- * @return True if Set Exact Alarm permission is granted, false otherwise.
372- */
373- public boolean getAndAskExactAlarmPermission (boolean askPermissionToo ) {
374- if (Build .VERSION .SDK_INT < Build .VERSION_CODES .S ) return true ;
375-
376- AlarmManager alarmManager = (AlarmManager ) getSystemService (Context .ALARM_SERVICE );
377- if (alarmManager .canScheduleExactAlarms ()) return true ;
378-
379- if (askPermissionToo ) {
380- Intent intent = new Intent (Settings .ACTION_REQUEST_SCHEDULE_EXACT_ALARM );
381- intent .setData (android .net .Uri .parse ("package:" + getPackageName ()));
382- startActivityForResult (intent , 0 );
383- }
384- return false ;
385- }
386-
387- /**
388- * Checks if the Ignore Battery Optimization permission is granted and optionally asks for it if not granted.
389- *
390- * @param askPermissionToo Whether to prompt the user to enable Ignore Battery Optimization permission if not granted.
391- * @return True if Ignore Battery Optimization permission is granted, false otherwise.
392- */
393- public boolean getAndAskIgnoreBatteryOptimizationPermission (boolean askPermissionToo ) {
394- PowerManager powerManager = (PowerManager ) getSystemService (Context .POWER_SERVICE );
395- if (powerManager .isIgnoringBatteryOptimizations (getPackageName ())) return true ;
396-
397- if (askPermissionToo ) {
398- @ SuppressLint ("BatteryLife" ) Intent intent = new Intent (Settings .ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS );
399- intent .setData (Uri .parse ("package:" + getPackageName ()));
400- startActivityForResult (intent , 0 );
401- }
402- return false ;
403- }
404-
405- @ Override
406- protected void onStop () {
407- super .onStop ();
408- // Notify VPN service that it can restart if needed
409- if (mVpnServiceConn .isConnected ()) {
410- mVpnServiceConn .getService ().onApplicationStop ();
411- }
412- }
413-
414365 @ Override
415366 protected void onDestroy () {
416367 super .onDestroy ();
0 commit comments