I have an app that shows the notification number in the little red dot on the app icon. This works fine on all models except the Samsung Galaxy S9. I have tried many solutions but always get the error
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()
The project is a Xamarin Android project in Visual Studio 2017, below is the code that works with all models except S9
In the manifest
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
The 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);
}
Like I said, this all works fine with earlier models but errors with the newer models. Is there something that needs to be added to permissions or am I missing something else?
I have a fix to my problem. You now need to use a NotificationChannel with your NotificationManager. I have created a small test app with one button. In the button click, I call the code below. I haven't moved this to my live apps yet but it is working good in this test app.
First, add a const to use for the id parameter for the NotificationChannel
public const string CLICKS_CHANNEL = "com.yourcompany.SamsungBadgeTest.clicks";
Now:
Build()
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);
}
Don't forget to add this to your Manifest
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />