隐藏前台通知

时间:2021-03-09 17:20:04

标签: c# android xamarin xamarin.android

我正在尝试创建一个无声的 Android 前台通知并允许用户手动隐藏前台通知。我创建了一个自定义 BroadcastReceiver 来打开通知设置页面并使用代码 here 设置通知的意图。

然而,这会导致崩溃并出现以下错误:

<块引用>

'startForeground 的错误通知'

MyService.cs:

 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;
        private string NOTIFICATION_CHANNEL_ID = "1003";
        private string NOTIFICATION_CHANNEL_NAME = "MyChannel";

        public override void OnCreate()
        {
            base.OnCreate();

            handler = new Handler();

            // push a notification every 5 seconds
            runnable = new Action(() =>
            {
                if (isStarted)
                {
                    DispatchNotificationThatAlarmIsGenerated();
                    handler.PostDelayed(runnable, DELAY_BETWEEN_LOG_MESSAGES);
                }
            });
        }

        public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
        {
            if (isStarted)
            {
                // service is already started
            }
            else
            {
                CreateNotificationChannel();
                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();
        }

        private void CreateNotificationChannel()
        {
            // notification Channel
            NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, NOTIFICATION_CHANNEL_NAME, NotificationImportance.Low);
            notificationChannel.LockscreenVisibility = NotificationVisibility.Secret;
            notificationChannel.SetSound(null, null);
            notificationChannel.EnableLights(false);
            notificationChannel.EnableVibration(false);

            NotificationManager notificationManager = (NotificationManager)this.GetSystemService(Context.NotificationService);
            notificationManager.CreateNotificationChannel(notificationChannel);
        }

        // start a foreground notification to keep alive 
        private void DispatchNotificationThatServiceIsRunning()
        {
            Intent intent = new Intent(this, typeof(CustomReceiver));
            PendingIntent pendingIntent = PendingIntent.GetBroadcast(
                    this,
                    1,
                    intent,
                    PendingIntentFlags.UpdateCurrent
            );
            NotificationCompat.Builder builder = new NotificationCompat.Builder(this, "default")
               .SetAutoCancel(false)
               .SetSmallIcon(Resource.Drawable.icon)
               .SetContentIntent(pendingIntent)
               .SetContentTitle("Hide Notification")
               .SetContentText("To hide the notification, click and uncheck 'Hidden Notification Service'");
            StartForeground(NOTIFICATION_SERVICE_ID, builder.Build());
        }

        // every 5 seconds push a notificaition
        private void DispatchNotificationThatAlarmIsGenerated()
        {
            Intent intent = new Intent(this, typeof(CustomReceiver));
            PendingIntent pendingIntent = PendingIntent.GetBroadcast(
                    this,
                    1,
                    intent,
                    PendingIntentFlags.UpdateCurrent
            );
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, "default")
               .SetAutoCancel(false)
               .SetSmallIcon(Resource.Drawable.icon)
               .SetContentIntent(pendingIntent)
               .SetVisibility(NotificationCompat.VisibilitySecret)
               .SetContentTitle("Hide Notification")
               .SetContentText("To hide me, click and uncheck 'Hidden Notification Service'");

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

BroadcastReceiver.cs:

 [BroadcastReceiver(Enabled = true)]
    public class CustomReceiver : BroadcastReceiver
    {
        private string NOTIFICATION_CHANNEL_ID = "1003";
        public override void OnReceive(Context context, Intent intent)
        {
            Intent i = new Intent(Android.Provider.Settings.ActionChannelNotificationSettings)
                .PutExtra(Android.Provider.Settings.ExtraAppPackage, context.PackageName)
                .PutExtra(Android.Provider.Settings.ExtraChannelId, NOTIFICATION_CHANNEL_ID)
                .SetFlags(ActivityFlags.NewTask);

            context.StartActivity(i);
        }
    }

如何创建前台静音通知,同时点击通知时也打开通知设置页面?

1 个答案:

答案 0 :(得分:0)

<块引用>

然而,这会导致崩溃并出现以下错误:'Bad notice for startForeground'

您需要在 Mainactivity 中创建 Notification channel,然后调用 CreateNotificationChannel() MainActivity.OnCreate() 方法。

void CreateNotificationChannel()
    {
        if (Build.VERSION.SdkInt < BuildVersionCodes.O)
        {
            // Notification channels are new in API 26 (and not a part of the
            // support library). There is no need to create a notification 
            // channel on older versions of Android.
            return;
        }

        var name = "Local Notifications";
        var description = "The count from MainActivity";
        var channel = new NotificationChannel("location_notification", name, NotificationImportance.Default)
        {
            Description = description
        };

        var notificationManager = (NotificationManager)GetSystemService(NotificationService);
        notificationManager.CreateNotificationChannel(channel);
    }

然后在 MyService 中为 Notification 设置 channelId

Intent intent = new Intent(this, typeof(CustomReceiver));
        PendingIntent pendingIntent = PendingIntent.GetBroadcast(
                this,
                1,
                intent,
                PendingIntentFlags.UpdateCurrent
        );
        var notification = new Notification.Builder(this,default)
            .SetChannelId("location_notification")
            .SetContentTitle(Resources.GetString(Resource.String.app_name))
            .SetContentText(Resources.GetString(Resource.String.notification_text))
            .SetSmallIcon(Resource.Drawable.ic_stat_name)
            .SetContentIntent(pendingIntent)
            .SetOngoing(true)
            .AddAction(BuildRestartTimerAction())
            .AddAction(BuildStopServiceAction())
            .Build();


        // Enlist this instance of the service as a foreground service
        StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notification);
<块引用>

如何创建前台静音通知,同时点击通知时也打开通知设置页面?

创建自定义BroadcastReceiver,打开通知设置页面,设置通知Intent,添加点击事件。

 [BroadcastReceiver(Enabled = true)]
public class CustomReceiver : BroadcastReceiver
{
    public override void OnReceive(Context context, Intent intent)
    {
        Intent i = new Intent(Android.Provider.Settings.ActionApplicationDetailsSettings, Android.Net.Uri.Parse("package:" + Android.App.Application.Context.PackageName))//Settings.ACTION_CHANNEL_NOTIFICATION_SETTINGS          
        .SetFlags(ActivityFlags.NewTask);
        context.StartActivity(i);

    }
}