Xamarin 在 Galaxy 8 和 9 上设置徽章编号时获得权限拒绝

Xamarin gets Permission Denial when setting badge number on Galaxy 8 & 9

我有一个应用程序,它在应用程序图标上的小红点中显示通知编号。这适用于除 Samsung Galaxy S9 以外的所有型号。我尝试了很多解决方案,但总是出现错误

Permission Denial: writing com.sec.android.provider.badge.BadgeProvider uri content://com.sec.badge/apps from pid=32464, uid=10233 requires com.sec.android.provider.badge.permission.WRITE, or grantUriPermission()

该项目是Visual Studio 2017年的Xamarin Android项目,以下代码适用于除S9以外的所有机型

在清单中

<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />

C#

        try
        {
            var context = Android.App.Application.Context;

            // This is the content uri for the BadgeProvider
            var uriPath = "content://com.sec.badge/apps"; //"com.sec.android.app.launcher"; 
            Android.Net.Uri uri = Android.Net.Uri.Parse(uriPath); //new Uri("content://com.sec.badge/apps");

            ICursor cursor = context.ContentResolver.Query(uri, new string[] { "_id" }, "package=?", new string[] { context.PackageName }, null);

            if (cursor == null || !cursor.MoveToFirst())
            {
                ContentValues cv = new ContentValues();
                cv.Put("package", context.PackageName);
                cv.Put("class", context.PackageManager.GetLaunchIntentForPackage(context.PackageName).Component.ClassName);
                cv.Put("badgecount", count);
                context.ContentResolver.Insert(uri, cv); //Errors here
            }
            else
            {
                int idColumnIndex = cursor.GetColumnIndex("_id");

                ContentValues cv = new ContentValues();
                cv.Put("badgecount", count);
                context.ContentResolver.Update(uri, cv, "_id=?", new string[] { cursor.GetInt(idColumnIndex).ToString() });
            }

        }
        catch (System.Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message); 
        }

正如我所说,这一切都适用于较早的型号,但适用于较新的型号。是否有需要添加到权限中的内容,或者我是否遗漏了其他内容?

我已经解决了我的问题。您现在需要将 NotificationChannel 与您的 NotificationManager 一起使用。我创建了一个带有一个按钮的小型测试应用程序。在单击按钮时,我调用了下面的代码。我还没有将它移到我的实时应用程序中,但它在这个测试应用程序中运行良好。

首先,添加一个常量用于 NotificationChannel 的 id 参数

public const string CLICKS_CHANNEL = "com.yourcompany.SamsungBadgeTest.clicks";

现在:

  1. 将 NotificationManager 的声明移至 NotificationBuilder 之上
  2. 创建 NotificationChannel
  3. 调用管理器的 CreateNotificationChannel 并将通道作为参数传递
  4. 让你的Notification.Builder
  5. 构建()

        try
        {
            //This is declared at the class level and initially set to 0
            //Incrementing with each button click
            clickCount++;
    
            int defaults = 0;
            defaults |= (int)NotificationDefaults.Sound;
            defaults |= (int)NotificationDefaults.Lights;
            defaults |= (int)NotificationDefaults.Vibrate;
    
            var notificationManager = (NotificationManager)GetSystemService(Context.NotificationService);
    
            var chan = new NotificationChannel(CLICKS_CHANNEL, "Button Click", NotificationImportance.Default)
            {
                LockscreenVisibility = NotificationVisibility.Private
            };
    
            notificationManager.CreateNotificationChannel(chan);
    
            var notificationBuilder = new NotificationCompat.Builder(this, CLICKS_CHANNEL)
                .SetAutoCancel(true)
                .SetContentText("You've received new messages.")
                .SetContentTitle("A New Message")
                .SetNumber(clickCount)
                //You need to add a icon to your project and get it here
                .SetSmallIcon(Resource.Drawable.ic_stat_button_click)
                .SetBadgeIconType(NotificationCompat.BadgeIconSmall)
                .SetDefaults(defaults); //.Build();
    
            notificationManager.Notify(0, notificationBuilder.Build());
        }
        catch(System.Exception ex)
        {
            System.Diagnostics.Debug.WriteLine(ex.Message);
        }
    

不要忘记将此添加到您的清单中

<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />