private void StartMyForegroundService()
        {
            try
            {
                // Code not directly related to publishing the notification has been omitted for clarity.
                // Normally, this method would hold the code to be run when the service is started.
                var notifChannel = createNotificationChannel();

                var notification = new NotificationCompat.Builder(this)
                                   .SetContentTitle("selfCAC")
                                   .SetContentText("selfCAC Filtering Service is Running in the back.")
                                   .SetSmallIcon(Resource.Drawable.ic_notfiy_icon)
                                   .SetContentIntent(BuildIntentToShowMainActivity())
                                   .SetOngoing(true)
                                   .SetChannelId(notifChannel.Id)
                                   .SetPriority((int)NotificationPriority.Min) // Hide in oreo+
                                   .Build();

                // Enlist this instance of the service as a foreground service
                StartForeground(SERVICE_RUNNING_NOTIFICATION_ID, notification);
            }
            catch (Exception ex)
            {
                AndroidLevelLogger.e(TAG, ex.ToString());
            }
        }
        // ==================================================================================================
        // ==================================================================================================

        public static void StartForegroundServiceCompat <T>(Context context, string ACTION, Bundle args = null) where T : Service
        {
            try
            {
                var intent = new Intent(context, typeof(T));
                intent.SetAction(ACTION);
                if (args != null)
                {
                    intent.PutExtras(args);
                }

                if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
                {
                    context.StartForegroundService(intent);
                }
                else
                {
                    context.StartService(intent);
                }
            }
            catch (Exception ex)
            {
                AndroidLevelLogger.e(TAG, ex.ToString());
            }
        }
Example #3
0
 public static void StartScanning(Context ctx)
 {
     try
     {
         // Requirements here: https://developer.android.com/guide/topics/connectivity/wifi-scan
         if (myWifiManager.IsWifiEnabled)
         {
             // register the Broadcast receiver to get the list of Wifi Networks
             ctx.RegisterReceiver(myWifiReceiver, new IntentFilter(WifiManager.ScanResultsAvailableAction));
             if (!myWifiManager?.StartScan() ?? false)
             {
                 ctx.UnregisterReceiver(myWifiReceiver);
                 AndroidBridge.WifiScanningCallback?.Invoke(null, null, new Exception("Starting scan failed quietly"));
             }
         }
         else
         {
             AndroidBridge.WifiScanningCallback?.Invoke(null, null, new Exception("Wifi is not on"));
         }
     }
     catch (Exception ex)
     {
         AndroidLevelLogger.e(TAG, ex.ToString());
         AndroidBridge.WifiScanningCallback?.Invoke(null, null, ex);
     }
 }
Example #4
0
        public override bool OnStopJob(JobParameters @params)
        {
            // Called when a requierment not met any more (ex. idle became not-idle...)

            bool shouldJobContinue = false; // Once requirement met again
            bool invokeErrors      = false;

            int jobID = @params.JobId;

            try
            {
                JobCallbacks callbacks = allJobs[jobID];

                callbacks.onJobRequirementAbort?.Invoke();
                shouldJobContinue = callbacks.shouldRetryAfterAbort?.Invoke() ?? shouldJobContinue;
            }
            catch (Exception ex)
            {
                invokeErrors = true;
                AndroidLevelLogger.e(TAG, ex);
            }

            if (invokeErrors || !shouldJobContinue)
            {
                shouldJobContinue = false;
                if (allJobs.ContainsKey(jobID))
                {
                    allJobs.Remove(jobID);
                }
            }

            return(shouldJobContinue);
        }
 public override void OnCreate()
 {
     // Should be called once in lifetime of this service
     try
     {
         managedStart();
     }
     catch (Exception ex)
     {
         AndroidLevelLogger.e(TAG, ex);
     }
 }
Example #6
0
 public static void cancelAllJobs(Context ctx)
 {
     try
     {
         var manager = (JobSchedulerType)ctx.GetSystemService(Context.JobSchedulerService);
         manager.CancelAll();
     }
     catch (Exception ex)
     {
         AndroidLevelLogger.e(TAG, ex);
     }
 }
Example #7
0
 public static void InitWifiScan(Context ctx)
 {
     try
     {
         myWifiManager  = (WifiManager)ctx.GetSystemService(Context.WifiService);
         myWifiReceiver = new WifiReceiver();
     }
     catch (Exception ex)
     {
         AndroidLevelLogger.e(TAG, ex);
     }
 }
        public override void OnDestroy()
        {
            try
            {
                // Remove the notification from the status bar.
                var notificationManager = (NotificationManager)GetSystemService(NotificationService);
                notificationManager.Cancel(SERVICE_RUNNING_NOTIFICATION_ID);

                managedStop();
            }
            catch (Exception ex)
            {
                AndroidLevelLogger.e(TAG, ex.ToString());
            }
        }
Example #9
0
 public static void cancelJobById(Context ctx, int jobID)
 {
     try
     {
         if (allJobs.ContainsKey(jobID))
         {
             JobCallbacks job     = allJobs[jobID];
             var          manager = (JobSchedulerType)ctx.GetSystemService(Context.JobSchedulerService);
             manager.Cancel(job.JobUniqueID);
             allJobs.Remove(jobID);
         }
     }
     catch (Exception ex)
     {
         AndroidLevelLogger.e(TAG, ex);
     }
 }
Example #10
0
            public static void GetLatestWifiScanResults(bool isUpToDate = true)
            {
                if (!myWifiManager.IsWifiEnabled)
                {
                    AndroidBridge.WifiScanningCallback?.Invoke(null, null, new Exception("Wifi is not on"));
                    return;
                }

                try
                {
                    IList <ScanResult> scanwifinetworks = myWifiManager.ScanResults;
                    List <string>      allWifis         = new List <string>();

                    // Ignore if fail, we get many in between scans
                    if (isUpToDate)
                    {
                        if (scanwifinetworks.Count > 0)
                        {
                            long     timeOfScan        = (scanwifinetworks.Max(s => s.Timestamp)) / 1000;
                            long     currentTime       = SystemClock.ElapsedRealtime();
                            TimeSpan timeSinceLastScan = TimeSpan.FromMilliseconds(currentTime - timeOfScan);

                            foreach (ScanResult wifinetwork in scanwifinetworks)
                            {
                                allWifis.Add(wifiDesc(wifinetwork));
                            }

                            AndroidBridge.WifiScanningCallback?.Invoke(allWifis, timeSinceLastScan, null);
                        }
                    }
                }
                catch (Exception ex)
                {
                    AndroidLevelLogger.e(TAG, ex);

                    try
                    {
                        AndroidBridge.WifiScanningCallback?.Invoke(null, null, ex);
                    }
                    catch (Exception ex2)
                    {
                        AndroidLevelLogger.e(TAG, ex2);
                    }
                }
            }
Example #11
0
            public override void OnReceive(Context context, Intent intent)
            {
                // Try to stop scan in a different "try\e"
                try
                {
                    //https://stackoverflow.com/questions/4499915/how-to-stop-wifi-scan-on-android
                    context.UnregisterReceiver(this);

                    //InvokeAbortBroadcast not here:
                    //  https://medium.com/@ssaurel/develop-a-wifi-scanner-android-application-daa3b77feb73
                    //InvokeAbortBroadcast();
                }
                catch (Exception ex)
                {
                    AndroidLevelLogger.e(TAG, ex);
                }

                GetLatestWifiScanResults(intent.GetBooleanExtra(WifiManager.ExtraResultsUpdated, false));
                AndroidLevelLogger.d(TAG, "Wifi scan result sucess");
            }
        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            // Called everytime someone try to start (even if already started) or stop us or custom even we set up.
            try
            {
                if (intent.Action != null)
                {
                    switch (intent.Action)
                    {
                    case ACTION_START_SERVICE:
                        // Will have no affect if already running:
                        //                      (onCreate will not called)
                        StartMyForegroundService();
                        break;

                    case ACTION_RESTART_SERVICE:
                        managedStop();
                        managedStart();
                        break;

                    case ACTION_STOP_SERVICE:
                        managedStop();
                        StopMyForegroundService();
                        break;

                    default:
                        break;
                    }
                }
            }
            catch (Exception ex)
            {
                AndroidLevelLogger.e(TAG, ex.ToString());
            }

            return(StartCommandResult.Sticky);
        }
Example #13
0
        public override bool OnStartJob(JobParameters @params)
        {
            bool shouldJobContinue = false;

            int  jobID           = @params.JobId;
            bool hasUserFinished = false;
            bool invokeErrors    = false;

            try
            {
                JobCallbacks  callbacks        = allJobs[jobID];
                Action <bool> jobFinishedProxy =
                    (bool wantsReschedule) => {
                    hasUserFinished = true;
                    JobFinished(@params, wantsReschedule);
                };

                callbacks.onJob?.Invoke(jobFinishedProxy);
                shouldJobContinue = callbacks.shouldContinue?.Invoke() ?? shouldJobContinue;
            }
            catch (Exception ex)
            {
                invokeErrors = true;
                AndroidLevelLogger.e(TAG, ex);
            }

            if (invokeErrors || (hasUserFinished && !shouldJobContinue))
            {
                shouldJobContinue = false;
                if (allJobs.ContainsKey(jobID))
                {
                    allJobs.Remove(jobID);
                }
            }

            return(shouldJobContinue);
        }
 public override IBinder OnBind(Intent intent)
 {
     AndroidLevelLogger.d(TAG, "OnBind");
     return(null);
 }
Example #15
0
        public static bool scheduleJob(Context ctx, JobCallbacks callbacks, TimeSpan?minLatency, TimeSpan?maxLatency, TimeSpan?interval = null,
                                       bool requireIdle            = false, bool requireCharger = false, NetworkType requiredNet = NetworkType.Any,
                                       bool requireAboveLowBattery = false, bool requireAboveLowStorage = false)
        {
            int  jobID   = -1;
            bool success = false;

            jobID = callbacks.JobUniqueID;
            allJobs.Add(jobID, callbacks);

            try
            {
                ComponentName JobServiceComponent = new ComponentName(ctx, Java.Lang.Class.FromType(typeof(PeriodicTask)));

                var jobBuilder = new JobInfo
                                 .Builder(jobID, JobServiceComponent)

                                 .SetRequiresDeviceIdle(requireIdle)
                                 .SetRequiresCharging(requireCharger)
                                 .SetRequiredNetworkType(requiredNet)
                                 .SetRequiresBatteryNotLow(requireAboveLowBattery)
                                 .SetRequiresStorageNotLow(requireAboveLowStorage)
                ;

                long intervalMillisecond = (long)(interval?.TotalMilliseconds ?? 0);
                if (intervalMillisecond > 0L)
                {
                    if (intervalMillisecond < JobInfo.MinPeriodMillis)
                    {
                        throw new Exception("Period interval must be at least: " + JobInfo.MinPeriodMillis);
                    }
                    jobBuilder.SetPeriodic(intervalMillisecond);
                }
                else
                {
                    jobBuilder.SetMinimumLatency((long)(minLatency?.TotalMilliseconds ?? 0L));
                    jobBuilder.SetOverrideDeadline((long)(maxLatency?.TotalMilliseconds ?? 0L));
                }

                JobInfo job = jobBuilder.Build();

                var manager = (JobSchedulerType)ctx.GetSystemService(Context.JobSchedulerService);
                var status  = manager.Schedule(job);

                if (status != JobSchedulerType.ResultSuccess)
                {
                    AndroidLevelLogger.e(TAG, "Job schedule failed for id: " + jobID);
                    success = false;
                }
                else
                {
                    success = true;
                }
            }
            catch (Exception ex)
            {
                AndroidLevelLogger.e(TAG, ex);
            }

            if (!success && allJobs.ContainsKey(jobID))
            {
                allJobs.Remove(jobID);
            }

            return(success);
        }
        public void setupAndroidBridge()
        {
            Context global_ctx = Application.Context;

            AndroidBridge._log_d = new Action <string, string>((tag, msg) =>
            {
                AndroidLevelLogger.d(tag, msg);
            });

            AndroidBridge._log_e = new Action <string, string>((tag, msg) =>
            {
                AndroidLevelLogger.e(tag, msg);
            });

            AndroidBridge._toast = new Action <string>((msg) =>
            {
                try
                {
                    AndroidUtils.ToastIt(global_ctx, msg);
                }
                catch (Exception ex)
                {
                    Log.Error(AndroidBridge.TAG, ex.ToString());
                }
            });

            AndroidBridge._toast_from_back = new Action <string>((msg) =>
            {
                try
                {
                    AndroidUtils.ToastItFromBack(global_ctx, msg);
                }
                catch (Exception ex)
                {
                    Log.Error(AndroidBridge.TAG, ex.ToString());
                }
            });

            AndroidBridge._readAsset = new Func <string, string, string>((tag, asset_name) =>
            {
                string result = "";
                try
                {
                    result = FileHelpers.ReadAssetAsString(global_ctx, tag, asset_name);
                }
                catch (Exception ex)
                {
                    Log.Error(AndroidBridge.TAG, ex.ToString());
                }
                return(result);
            });

            AndroidBridge._get_absolute_path = new Func <string, bool, string>((relative, isPulic) =>
            {
                string result = "";
                try
                {
                    if (isPulic)
                    {
                        result = FileHelpers.getPublicAppFilePath(global_ctx, relative);
                    }
                    else
                    {
                        result = FileHelpers.getInternalAppFilePath(global_ctx, relative);
                    }
                }
                catch (Exception ex)
                {
                    Log.Error(AndroidBridge.TAG, ex.ToString());
                }
                return(result);
            });

            WifiScan.InitWifiScan(global_ctx);



            AndroidBridge._start_wifi_scan = new Action(() =>
            {
                WifiScan.StartScanning(global_ctx);
            });

            AndroidBridge._get_wifi_now = new Action(() =>
            {
                WifiScan.WifiReceiver.GetLatestWifiScanResults();
            });

            AndroidBridge._start_service = new Action(() =>
            {
                MyForegroundService.StartForegroundServiceCompat <MyForegroundService>(global_ctx, MyForegroundService.ACTION_START_SERVICE);
            });

            AndroidBridge._stop_service = new Action(() =>
            {
                MyForegroundService.StartForegroundServiceCompat <MyForegroundService>(global_ctx, MyForegroundService.ACTION_STOP_SERVICE);
            });

            AndroidBridge._is_service_up = new Func <bool>(() =>
            {
                return(MyForegroundService.IsServiceUp());
            });


            AndroidBridge._stop_all_jobs = () =>
            {
                PeriodicTask.cancelAllJobs(global_ctx);
            };

            AndroidBridge._stop_job = (int id) =>
            {
                PeriodicTask.cancelJobById(global_ctx, id);
            };

            AndroidBridge._schedule_job = new Func <
                TimeSpan?, TimeSpan?, TimeSpan?, Action <Action <bool> >, Func <bool>, Action, Func <bool>, int>(
                (latency, maxLatency, interval, _onJob, _shouldContinue, _onJobRequirementAbort, _shouldRetryAfterAbort) =>
            {
                PeriodicTask.JobCallbacks job = new PeriodicTask.JobCallbacks()
                {
                    onJob                 = _onJob,
                    shouldContinue        = _shouldContinue,
                    onJobRequirementAbort = _onJobRequirementAbort,
                    shouldRetryAfterAbort = _shouldRetryAfterAbort
                };
                if (PeriodicTask.scheduleJob(global_ctx, job, latency, maxLatency, interval))
                {
                    return(job.JobUniqueID);
                }
                return(-1);
            }
                );
        }