Как создать приоритетный сервис с уведомлением на Android ниже Oreo 8.0? - PullRequest
0 голосов
/ 16 января 2020

Я создал службу переднего плана, используя следующий код, который находится в методе переопределения OnStartCommand внутри класса службы с именем DemoIntentService.cs.

base.OnStartCommand(intent,flags,startId);
if (Build.VERSION.SdkInt >= BuildVersionCodes.O)
{
 Intent notificationIntent = new Intent(this, Java.Lang.Class.FromType(typeof(DemoIntentService)));
            PendingIntent pendingIntent = PendingIntent.GetActivity(this, 0, notificationIntent, 0);

            Notification.Builder notificationBuilder = new Notification.Builder(this, "Example_Service_Channel")
            .SetSmallIcon(Resource.Drawable.AlertLightFrame)
            .SetContentTitle(Resources.GetString(Resource.String.DialogAlertTitle))
            .SetContentText(Resources.GetString(Resource.String.SelectTextMode))
            .SetContentIntent(pendingIntent);

            Notification notificationAfterBuild = notificationBuilder.Build();

            StartForeground(123, notificationAfterBuild);

            InitializeAlarmManager();
            setAlarm();
}
return StartCommandResult.RedeliverIntent;

Очевидно, что приведенный выше код предназначен только для Android Oreo 8.0 и выше, сервис работает нормально, и уведомление не будет очищено, даже если я закрою приложение вручную. (Это хорошо, это то, что я хочу!). Тем не менее, когда я использую приведенный выше код для тестирования на Android Nougat 7.1.1, он не будет работать.

Во-первых, я исследовал в Интернете, они сказали, что нет необходимости создавать канал уведомлений для Android ниже 8.0, поэтому я удаляю "Example_Service_Channel", который является ID канала. Приложение было успешно развернуто, но уведомление исчезло, когда я убил его. Во-вторых, когда я удалил идентификатор канала, Xamarin выдал мне предупреждение «Notification.Builder.Builder (Context) устарел: устарел», и строка стала желтой. Я игнорирую ошибку и развертываю приложение. Служба работала так, как это видно в работающей службе внутри параметров разработчика. Но когда я убил приложение, сервис и уведомление ушли вместе. Есть ли другой способ создать службу уведомлений переднего плана, которая никогда не закончится для Android ниже 8.0? Спасибо за любые комментарии и идеи.

Ответы [ 2 ]

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

Я пишу простой пример, и он работает на Android 7.1. я просто удаляю канал уведомлений из Android 8.0

1.Создать службу MyService.cs :

[Service(Enabled = true)]
public class MyService : Service
{
    private Handler handler;
    private Action runnable;
    private bool isStarted;
    private int DELAY_BETWEEN_LOG_MESSAGES = 5000;
    private int NOTIFICATION_SERVICE_ID = 1001;
    private int NOTIFICATION_AlARM_ID = 1002;
    public override void OnCreate()
    {
        base.OnCreate();

        handler = new Handler();

        //here is what you want to do always, i just want to push a notification every 5 seconds here
        runnable = new Action(() =>
        {
           if (isStarted)
            {
                DispatchNotificationThatAlarmIsGenerated("I'm running");
                handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
            }
        });
    }

    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {
        if (isStarted)
        {
            // service is already started
        }
        else
        {
            DispatchNotificationThatServiceIsRunning();

            handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
            isStarted = true;
        }
        return StartCommandResult.Sticky;
    }

    public override void OnTaskRemoved(Intent rootIntent)
    {
        //base.OnTaskRemoved(rootIntent);
    }

    public override IBinder OnBind(Intent intent)
    {
        // Return null because this is a pure started service. A hybrid service would return a binder that would
        // allow access to the GetFormattedStamp() method.
        return null;
    }

    public override void OnDestroy()
    {
        // Stop the handler.
        handler.RemoveCallbacks(runnable);

        // Remove the notification from the status bar.
        var notificationManager = (NotificationManager)GetSystemService(NotificationService);
        notificationManager.Cancel(NOTIFICATION_SERVICE_ID);

        isStarted = false;
        base.OnDestroy();
    }



    //start a foreground notification to keep alive 
    private void DispatchNotificationThatServiceIsRunning()
    {
        NotificationCompat.Builder builder = new NotificationCompat.Builder(this)
               .SetDefaults((int)NotificationDefaults.All)
               .SetSmallIcon(Resource.Drawable.Icon)
               .SetVibrate(new long[] { 100, 200, 300, 400, 500, 400, 300, 200, 400 })
               .SetSound(null)
               .SetPriority(NotificationCompat.PriorityDefault)
               .SetAutoCancel(false)
               .SetContentTitle("Mobile")
               .SetContentText("My service started")
               .SetOngoing(true);

        NotificationManagerCompat notificationManager = NotificationManagerCompat.From(this);
        StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
    }

    //every 5 seconds push a notificaition
    private void DispatchNotificationThatAlarmIsGenerated(string message)
    {
        var intent = new Intent(this, typeof(MainActivity));
        intent.AddFlags(ActivityFlags.ClearTop);
        var pendingIntent = PendingIntent.GetActivity(this, 0, intent, PendingIntentFlags.OneShot);

        Notification.Builder notificationBuilder = new Notification.Builder(this)
            .SetSmallIcon(Resource.Drawable.Icon)
            .SetContentTitle("Alarm")
            .SetContentText(message)
            .SetAutoCancel(true)
            .SetContentIntent(pendingIntent);

        var notificationManager = (NotificationManager)GetSystemService(NotificationService);
        notificationManager.Notify(NOTIFICATION_AlARM_ID, notificationBuilder.Build());
    }
}

2.в вашей деятельности:

protected override void OnResume()
  {
      base.OnResume();
      StartMyRequestService();
  }
public void StartMyRequestService()
  {
      var serviceToStart = new Intent(this, typeof(MyService));
      StartService(serviceToStart);
  }
0 голосов
/ 16 января 2020

попробуйте запустить службу с помощью

ContextCompat.startForegroundService(context,intent)

, создайте уведомление, затем вызовите

startForeground(1, notification)

в onCreate () или onStartCommand (), которые работают для вас, но после запуска службы и бег не забудьте попросить разрешения

<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...