java .lang.IllegalArgumentException: нет такой службы ComponentInfo {/com.SampleApp.AttendanceApp.ServiceClass} - PullRequest
0 голосов
/ 09 января 2020

Я использую Xamarin Android для создания приложения, которое должно позволять приложению отправлять местоположение водителя каждые 15 минут, чтобы я мог отслеживать его движение. Я использовал JobScheduler, чтобы сделать это. Мой проект сейчас очень прост и содержит только следующие 3 файла:

  1. MainActivity.cs
  2. AttendancePage.cs (страница содержимого, взаимодействие с кнопкой пользовательского интерфейса для запуска службы)
  3. ServiceClass.cs

Методы в Main Activity.cs

    protected override void OnCreate(Bundle savedInstanceState)
    {
        base.OnCreate(savedInstanceState);
        scheduler = (JobScheduler)GetSystemService(JobSchedulerService);
        LoadApplication(new App());   //This line will then jump to AttendancePage.cs
    }

    public void ScheduleJob()
    {
        ComponentName componentName = new ComponentName(this, Java.Lang.Class.FromType(typeof(ServiceClass)));
        JobInfo info = new JobInfo.Builder(123, componentName)
            .SetPersisted(true)
            .SetPeriodic(60000)
            .Build();

        int resultCode = scheduler.Schedule(info);  //The error show when hit this line.

        if (resultCode == JobScheduler.ResultSuccess)
        {
            Log.Info("Message", "Job Schedule!");
        }
        else
        {
            Log.Info("Message", "Job shceduling failed");
        }
    }

    public void CancelJob()
    {
        scheduler.Cancel(123);
    }

AttendancePage.cs

public partial class AttendancePage : ContentPage
{
    MainActivity main = new MainActivity();

    public AttendancePage()
    {
        InitializeComponent();
        Title = "Attendance App";           
    }

    //Button OnClickEvent
    async void ScheduleJob(object s, EventArgs e)
    {           
        main.ScheduleJob();              
    }

    //Button OnClickEvent
    async void CancelJob(object s, EventArgs e)
    {
        main.CancelJob();
    }
}

ServiceClass.cs

[Service(Name = "com.SampleApp.AttendanceApp.ServiceClass", Permission = "android.permission.BIND_JOB_SERVICE")]
public class ServiceClass : JobService
{
    public ServiceClass()
    {

    }

    public override bool OnStartJob(JobParameters jobParamsOnStart)
    {
        doBackgroundWork(jobParamsOnStart);
        return true;
    }

    private void doBackgroundWork(JobParameters jobParam)
    {
        //My code to send driver's location
        TestingPage.GetGPS();

        JobFinished(jobParam, false);
    }

    public override bool OnStopJob(JobParameters jobParamsOnStop)
    {
        return false;
    }
}

Я также добавил метку обслуживания в AndroidManifest. xml.

<service android:name=".ServiceClass"
     android:permission="android.permission.BIND_JOB_SERVICE" 
    android:exported="true" />

У меня нет Идея, почему ошибка все еще там. Ошибка из строки scheduler.Schedule (JobInfo). У кого-нибудь есть другое возможное решение? Я разочарован в решении этого. Будет ли причина в том, что я не могу отладить службу, но могу сразу запустить ее в режиме выпуска? Пожалуйста, помогите.

1 Ответ

0 голосов
/ 10 января 2020

Из общего кода Froms он работает в проекте Xamarin. Android, однако вот проект Xamarin.Forms. Это не может работать.

В AttendancePage.cs вы создаете новый MainActivity для вызова собственного метода ScheduleJob и CancelJob. Это не найдет JobScheduler на нативном, тогда он вернет ноль.

Нет такого сервиса ComponentInfo {/com.SampleApp.AttendanceApp.ServiceClass}

Если вы хотите вызвать собственный метод, вы можете попробовать DependencyService в формах Xamarin.

По крайней мере, необходимо создать Interface в формах для вызова:

public interface IJobSchedulerService 
{
    //Start JobSchedule
    void StartJobSchedule();

    //Cancel JobSchedule
    void CancelJobSchedule();
}

Затем можно вызывать в формах Xamarin следующим образом:

async void ScheduleJob(object s, EventArgs e)
{           
    DependencyService.Get<IJobSchedulerService>().StartJobSchedule();              
}

//Button OnClickEvent
async void CancelJob(object s, EventArgs e)
{
    DependencyService.Get<IJobSchedulerService>().CancelJobSchedule();
}

Теперь вам нужно реализовать IJobSchedulerService в нативном android. Создать JobSchedulerDependcenyService :

public class JobSchedulerDependcenyService : IJobSchedulerService
{
    JobScheduler jobScheduler;

    public JobSchedulerDependcenyService()
    {
        jobScheduler = (JobScheduler)MainActivity.Instance.GetSystemService(Android.Content.Context.JobSchedulerService);
    }

    public void StartJobSchedule()
    {
        ComponentName componentName = new ComponentName(MainActivity.Instance, Java.Lang.Class.FromType(typeof(DownloadJob)));
        JobInfo jobInfo = new JobInfo.Builder(1, componentName)
            .SetOverrideDeadline(0)
            .Build();

        //var jobScheduler = (JobScheduler)GetSystemService(JobSchedulerService);
        var scheduleResult = jobScheduler.Schedule(jobInfo);

        if (JobScheduler.ResultSuccess == scheduleResult)
        {
            var snackBar = Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content), "jobscheduled_success", Snackbar.LengthShort);
            snackBar.Show();
        }
        else
        {
            var snackBar = Snackbar.Make(MainActivity.Instance.FindViewById(Android.Resource.Id.Content), "jobscheduled_failure", Snackbar.LengthShort);
            snackBar.Show();
        }

    }

    public void CancelJobSchedule()
    {
        jobScheduler.CancelAll();
    }
}

Здесь вы найдете MainActivity.Instance внутри него, это экземпляр stati c, определяемый self в MainActivity.

    public static MainActivity Instance { set; get; }
    protected override void OnCreate(Bundle savedInstanceState)
    {
        TabLayoutResource = Resource.Layout.Tabbar;
        ToolbarResource = Resource.Layout.Toolbar;

        base.OnCreate(savedInstanceState);

        Instance = this;

        Xamarin.Essentials.Platform.Init(this, savedInstanceState);
        global::Xamarin.Forms.Forms.Init(this, savedInstanceState);
        LoadApplication(new App());
    }
...