Don Box
Don Box

Reputation: 3336

Binding for Evernote's android-job

Has anybody got the binding working for Evernote's android-job https://github.com/evernote/android-job ?

Funnily Xamarin docs mention it in an example:

https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/troubleshooting-bindings/#Problem_Name_Collisions_on_Inner_Classes_Properties

I tried to follow https://developer.xamarin.com/guides/android/advanced_topics/binding-a-java-library/binding-an-aar/ but it doesn't generate the JobManager class

Upvotes: 4

Views: 1103

Answers (1)

Le-roy Staines
Le-roy Staines

Reputation: 2057

Xamarin binding for android-job on GitHub

What is it?

The Xamarin Android-Job binding allows you to utilize Evernote's android-job library for Android, to run jobs in the background efficiently and robustly. The library checks the Android version on the client device to determine the best method for performing scheduled background work. It will use the most appropriate method for the OS such as JobScheduler, GcmNetworkManager, AlarmManager or WorkManager.

How to use it:

Step 1:

Download the Xamarin binding for Evernote's android-job library.

Step 2:

Build the binding project in Release Mode, then grab the android-job.dll file from the bin/release folder. Add this dll to your own project and reference it.

Step 3:

Add the following into your Android Manifest, within the Application node, for the services and receivers to work properly.

<service android:name="com.evernote.android.job.v21.PlatformJobService" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:name="com.evernote.android.job.v14.PlatformAlarmService" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE"/>
<service android:name="com.evernote.android.job.v14.PlatformAlarmServiceExact" android:exported="false"/>
<receiver android:name="com.evernote.android.job.v14.PlatformAlarmReceiver" android:exported="false">
  <intent-filter>
    <!-- Keep the filter for legacy intents -->
    <action android:name="com.evernote.android.job.v14.RUN_JOB"/>
    <action android:name="net.vrallev.android.job.v14.RUN_JOB"/>
  </intent-filter>
</receiver>
<receiver android:name="com.evernote.android.job.JobBootReceiver" android:exported="false">
  <intent-filter>
    <action android:name="android.intent.action.BOOT_COMPLETED"/>
    <action android:name="android.intent.action.QUICKBOOT_POWERON"/>
    <action android:name="com.htc.intent.action.QUICKBOOT_POWERON"/>
    <action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
  </intent-filter>
</receiver>
<service android:name="com.evernote.android.job.gcm.PlatformGcmService" android:enabled="false" android:exported="true" android:permission="com.google.android.gms.permission.BIND_NETWORK_TASK_SERVICE">
  <intent-filter>
    <action android:name="com.google.android.gms.gcm.ACTION_TASK_READY"/>
  </intent-filter>
</service>
<service android:name="com.evernote.android.job.JobRescheduleService" android:exported="false" android:permission="android.permission.BIND_JOB_SERVICE"/>

Also, make sure you have the following permissions:

<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>

Step 4:

Make sure you have the following references within your project (can be installed via Nuget):

  • Xamarin.Android.Support.Compat
  • Xamarin.Android.Support.v4
  • Xamarin.GooglePlayServices.Gcm (Not required, but will work better and support even more devices)

Step 5:

Create a class for your Job that will be scheduled:

Tip: Refer to the android-job GitHub page for examples of configuring different types of jobs i.e. periodic, one-off, etc.

using Com.Evernote.Android.Job;

namespace MyNamespace
{
    public class MyJob : Job
    {

        public const String TAG = "job_myjob_tag";

        protected override Result OnRunJob(Params parameters)
        {
            // run your job here   
            return Result.Success;
        }

        public static void ScheduleJob()
        {
            new JobRequest.Builder(MyJob.TAG)
                .SetRequiresDeviceIdle(false)
                .SetRequiredNetworkType(JobRequest.NetworkType.Connected)
                .SetPeriodic(900000, 300000)
                .SetUpdateCurrent(true)
                .Build()
                .Schedule();
        }

        private void CancelJob(int jobId)
        {
            JobManager.Instance().Cancel(jobId);
        }

    }
}

Step 6:

Create a factory method for your Job/s:

using Com.Evernote.Android.Job;

namespace MyNamespace
{
    public class MyJobCreator : Java.Lang.Object, IJobCreator
    {
        public Job Create(string tag)
        {
            switch (tag)
            {
                case MyJob.TAG:
                    return new MyJob();
                default:
                    return null;
            }
        }

    }
}

Step 7:

Initialise the JobManager singleton, ideally within your GlobalApplication.OnCreate method. If you can't, there's an alternative.

JobManager.Create(this).AddJobCreator(new MyJobCreator());

Step 8:

Schedule your job! You could do this from your starting activity OnCreate method, or wherever you like. For example:

MyNamespace.MyJob.ScheduleJob();

Tips:

  1. The work done within OnRunJob(...) method should be Synchronous, or otherwise not return a Result until all work is finished.
  2. Be careful not to instantiate the same job multiple times. Utilize SetUpdateCurrent on the job builder, or check whether the job already exists by calling JobManager.Instance().GetAllJobRequestsForFlag(MyJob.TAG).

Credit & Reference:

Upvotes: 2

Related Questions