首页 > 解决方案 > 通知不振动或不亮

问题描述

我正在使用 Visual Studio 2019 16.6.0 Preview 2.1,我正在尝试在 Galaxy S10 (Android 10) 上进行振动和照明,我正在测试我的应用程序。我收到通知,但手机不振动,灯也不亮。我也想有一个声音,但我在这里尝试过的没有任何东西符合 Visual Studio,因为我能找到的所有示例/示例都在 java 中。我的代码符合并运行没有错误。

        if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            string NOTIFICATION_CHANNEL_ID = "com.OML.Android";
            string channelName = "Notifications Service";
            NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, Android.App.NotificationImportance.None);
            chan.EnableLights(true);
            chan.EnableVibration(true);
            chan.LightColor = Color.Red;
            //chan.SetSound() <<-- simply can't figure out how to construct a Uri to the default sound
            chan.LockscreenVisibility = Android.App.NotificationVisibility.Private;
            NotificationManager manager = (NotificationManager)GetSystemService(Context.NotificationService);
            manager.CreateNotificationChannel(chan);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
            Notification notification = notificationBuilder.SetOngoing(true)
                    .SetSmallIcon(Resource.Drawable.alert_box)
                    .SetContentTitle("Alert System")
                    .SetPriority(1)
                    .SetAutoCancel(true)
                    .Build();
            StartForeground(2, notification);
        } else
        {
            Notification notify = new Notification();
            notify.Defaults = NotificationDefaults.All;
            StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notify);
        }

那么我错过了什么?

* 更新 *

根据@Cherry Bu - MSFT 的回答,我将代码更改为:

        if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            string NOTIFICATION_CHANNEL_ID = "com.OML.Android";
            string channelName = "Notifications Service";
            NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, Android.App.NotificationImportance.None);
            chan.EnableLights(true);
            chan.EnableVibration(true);
            chan.LightColor = Color.Red;
            chan.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification), new AudioAttributes.Builder().SetUsage(AudioUsageKind.Notification).Build());
            chan.LockscreenVisibility = Android.App.NotificationVisibility.Private;
            NotificationManager manager = (NotificationManager)GetSystemService(Context.NotificationService);
            manager.CreateNotificationChannel(chan);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
            Notification notification = notificationBuilder.SetOngoing(true)
                    .SetSmallIcon(Resource.Drawable.alert_box)
                    .SetContentTitle("Alert System")
                    .SetPriority(1)
                    //.SetVibrate(new long[] { 1000, 1000 })
                    //,SetLights(Color.AliceBlue, 3000, 3000)
                    .SetAutoCancel(true)
                    .Build();
            StartForeground(2, notification);
        } else
        {
            Notification notify = new Notification();
            notify.Defaults = NotificationDefaults.All;
            StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notify);
        }
        SingletonServicemanager.isMyServiceRunning = true;
        return StartCommandResult.Sticky;
    }

我还在清单中添加了以下权限:

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

* 更新 *

看看@Cherry Bu - MSFT 发布的 github 项目,我相信我做的和他完全一样,但我的代码不起作用,所以为了解决这个问题,我发布了前台服务的代码. 首先,我用来启动服务的代码是我的Utils代码的一部分:

    public static void StartForegroundServiceComapt<SignalRSrv>(Context context, Bundle args = null) where SignalRSrv : Service
    {
        var intent = new Intent(context, typeof(SignalRSrv));

        if (args != null)
        {
            intent.PutExtra("TheBundle", args);
        }

        if (Android.OS.Build.VERSION.SdkInt >= Android.OS.BuildVersionCodes.O)
        {
            context.StartForegroundService(intent);
        }
        else
        {
            context.StartService(intent);
        }
    }

从上面的代码可以看出,我正在启动一个 SignalR 服务,该代码是:

public class SignalRSrv : Service
{
    private bool InstanceFieldsInitialized = false;
    private string username = "";
    private string firstname = "";
    private string lastname = "";
    private string company = "";
    private string department = "";
    private string section = "";
    private int notifyid = 0;
    public SignalRSingleton mInstance;

    private void InitializeInstanceFields()
    {
        mBinder = new LocalBinder(this);
    }

    private Handler mHandler; // to display any received messages
    private IBinder mBinder; // Binder given to clients
    private Notification notification = null;

    public SignalRSrv()
    {
        if (!InstanceFieldsInitialized)
        {
            InitializeInstanceFields();
            InstanceFieldsInitialized = true;
        }

    }

    public SignalRSingleton GetInstance()
    {
        return mInstance;
    }
    public override void OnCreate()
    {
        base.OnCreate();
        mInstance = SignalRSingleton.getInstance();
        mHandler = new Handler(Looper.MainLooper);
    }

    public override void OnDestroy()
    {
       try
        {
            if (Build.VERSION.SdkInt >= BuildVersionCodes.N)
            {
                StopForeground(StopForegroundFlags.Remove);
            }
            else
            {
                StopForeground(true);
            }

            StopSelf();
        }
        catch (System.Exception e)
        {
            var m = e.Message;
        }
    }


    public override IBinder OnBind(Intent intent)
    {
        return null;
    }

    private void startSignalR(Bundle bundle)
    {

        User MyUser = bundle.GetParcelable("MyUser") as User;
        if (MyUser.Department == null || MyUser.Department == "")
        {
            MyUser.Department = "none";
        }
        if (MyUser.Section == null || MyUser.Section == "")
        {
            MyUser.Section = "none";
        }
        mInstance.setmHubConnection(MyUser.Username, MyUser.Firstname ,MyUser.Lastname,MyUser.Company ,MyUser.Department,MyUser.Section, "FOREGROUND");
        mInstance.setHubProxy();

        try
        {
            // Connect the client to the hup
            mInstance.mHubConnection.Start().Wait(-1);

            mInstance.mHubProxy.On("broadcastMessage", (string platform, string message) =>
            {
                try
                {
                    if (!isApplicationInTheBackground())
                    {
                        showMessage(message);
                    } else
                    {
                        showNotification(message, bundle, notification);
                    }

                }
                catch (System.Exception e)
                {
                   var error = e.Message;
                }
            });
        }
        catch (System.Exception e) when (e is InterruptedException || e is ExecutionException)
        {
            //opps

            //var x = 1;
            return;
        }
    }

    public async void showMessage(string message)
    {


        try
        {

            var result = await UserDialogs.Instance.ConfirmAsync(new ConfirmConfig
            {
                Message = "Alert - " + message,
                OkText = "Ok",

            });
            if (result)
            {
                // do something
                var x = message;
            }
        }
        catch (System.Exception e)
        {
            var s = e.Message;
        }
    }
    public override StartCommandResult OnStartCommand(Intent intent, StartCommandFlags flags, int startId)
    {

        User MyUser = new User("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
        Bundle bundlee = intent.GetBundleExtra("TheBundle");
        MyUser = bundlee.GetParcelable("MyUser") as User;

        username = MyUser.Username;
        firstname = MyUser.Firstname;
        lastname = MyUser.Lastname;
        company = intent.GetStringExtra("theSelectedCompany");
        department = intent.GetStringExtra("theSelectedDepartment");
        section = intent.GetStringExtra("theSelectedSection");

        startSignalR(bundlee);

        if (Android.OS.Build.VERSION.SdkInt >= BuildVersionCodes.O)
        {
            string NOTIFICATION_CHANNEL_ID = "com.OML.Android";
            string channelName = "Notifications Service";
            NotificationChannel chan = new NotificationChannel(NOTIFICATION_CHANNEL_ID, channelName, Android.App.NotificationImportance.None);
            chan.EnableLights(true);
            chan.EnableVibration(true);
            chan.LightColor = Color.Red;
            chan.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification), new AudioAttributes.Builder().SetUsage(AudioUsageKind.Notification).Build());
            chan.LockscreenVisibility = Android.App.NotificationVisibility.Private;
            NotificationManager manager = (NotificationManager)GetSystemService(Context.NotificationService);
            manager.CreateNotificationChannel(chan);
            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID);
            Notification notification = notificationBuilder.SetOngoing(true)
                    .SetSmallIcon(Resource.Drawable.alert_box)
                    .SetContentTitle("Alert System")
                    .SetPriority(1)
                    //.SetVibrate(new long[] { 1000, 1000 })
                    //,SetLights(Color.AliceBlue, 3000, 3000)
                    .SetAutoCancel(true)
                    .Build();
            StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notification);
        } else
        {
            Notification notify = new Notification();
            notify.Defaults = NotificationDefaults.All;
            StartForeground(Constants.SERVICE_RUNNING_NOTIFICATION_ID, notify);
        }
        SingletonServicemanager.isMyServiceRunning = true;
        return StartCommandResult.Sticky;
    }

    private void cancelnotification()
    {
        NotificationManager notificationManager = (NotificationManager)Android.App.Application.Context.GetSystemService(Context.NotificationService);
        notificationManager.Cancel(notifyid);

    }

    public void showNotification( string message, Bundle bundle, Notification notification)
    {
        try
        {
            Intent intent = new Intent();
            User MyUser = new User("", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "");
            MyUser = bundle.GetParcelable("MyUser") as User;
            if (MyUser.Usertype != "")
            {
                if (MyUser.Usertype == "COMPADMIN")
                {
                    intent = new Intent(this, typeof(Drawer)); //Activity you want to open
                } else if (MyUser.Usertype == "DEPTADMIN") {
                    intent = new Intent(this, typeof(Drawer)); //Activity you want to open
                } else
                {
                    intent = new Intent(this, typeof(regUser)); //Activity you want to open
                }
            }
            else
            {
                intent = new Intent(this, typeof(regUser)); //Activity you want to open
            }
            intent.AddFlags(ActivityFlags.ClearTop);
            intent.PutExtra("TheBundle", bundle);
            intent.PutExtra("MessageReceived", message);

            var pendingIntent = PendingIntent.GetActivity(this, RandomGenerator(), intent, PendingIntentFlags.OneShot);

            NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this,"com.OML.Android")
                 .SetSmallIcon(Resource.Drawable.alert_box)
                 .SetContentTitle("Message Received")
                 .SetContentText(message)
                 .SetAutoCancel(true)
                 .SetContentIntent(pendingIntent);

            NotificationManager notificationManager = (NotificationManager)Android.App.Application.Context.GetSystemService(Context.NotificationService);
            notifyid = RandomGenerator();
            notificationManager.Notify(notifyid, notificationBuilder.Build());

        }
        catch (System.Exception e)
        {
            Utils.LogError("An error occured in SignalRSrv.cs ShowNotification, the error is: " + e.Message);
        }
    }
    private int RandomGenerator()
    {
        return new Random().Next(int.MinValue, int.MaxValue);
    }
    private bool isApplicationInTheBackground()
    {
        bool isInBackground;

        RunningAppProcessInfo myProcess = new RunningAppProcessInfo();
        ActivityManager.GetMyMemoryState(myProcess);
        isInBackground = myProcess.Importance != Android.App.Importance.Foreground;

        return isInBackground;
    }
}

public class LocalBinder : Binder
{
    private readonly SignalRSrv outerInstance;

    public LocalBinder(SignalRSrv outerInstance)
    {
        this.outerInstance = outerInstance;
    }

    public virtual SignalRSrv Service
    {
        get
        {
            // Return this instance of SignalRSrv so clients can call public methods
            return outerInstance;
        }
    }
}

我在 SignalRSrv 代码中创建通道,这是错误的吗?

标签: c#androidxamarinxamarin.formsxamarin.android

解决方案


根据您的描述,您想为通知添加声音、灯光和振动,两个权限将允许。

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

请在 Mainfeast 中添加这两个权限。

然后像下面的代码一样设置声音、灯光和振动。

 var name = Resources.GetString(Resource.String.channel_name);
        var description = GetString(Resource.String.channel_description);
        var channel = new NotificationChannel(CHANNEL_ID, name, NotificationImportance.Default)
                      {
                          Description = description
                      };
        channel.EnableVibration(true);
        channel.EnableLights(true);
        channel.LightColor = Color.Red;
        channel.SetSound(RingtoneManager.GetDefaultUri(RingtoneType.Notification),new AudioAttributes.Builder().SetUsage(AudioUsageKind.Notification).Build());
        var notificationManager = (NotificationManager) GetSystemService(NotificationService);
        notificationManager.CreateNotificationChannel(channel);

注意:当您测试振动功能时,请记住先锁定您的设备屏幕,然后当应用收到通知时您会看起来很轻。

如果你想设置自定义声音,我找到一个关于这个的线程,你可以看看:

https://forums.xamarin.com/discussion/148652/how-to-make-a-wav-file-the-default-push-notification-sound-for-the-app

注意:请不要忘记添加读写声音文件的权限。

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

推荐阅读