diff --git a/Badge.userprefs b/Badge.userprefs new file mode 100644 index 0000000..a62ab3c --- /dev/null +++ b/Badge.userprefs @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/Badge/Badge.Plugin.Abstractions/IBadge.cs b/Badge/Badge.Plugin.Abstractions/IBadge.cs old mode 100644 new mode 100755 index 833e8e3..206a076 --- a/Badge/Badge.Plugin.Abstractions/IBadge.cs +++ b/Badge/Badge.Plugin.Abstractions/IBadge.cs @@ -14,7 +14,6 @@ public interface IBadge /// Sets the badge. /// /// The badge number. - /// The title. Used only by Android - void SetBadge(int badgeNumber, string title = null); + void SetBadge(int badgeNumber); } } diff --git a/Badge/Badge.Plugin.Android/Badge.Plugin.Android.csproj b/Badge/Badge.Plugin.Android/Badge.Plugin.Android.csproj index 631dd4e..1abb100 100644 --- a/Badge/Badge.Plugin.Android/Badge.Plugin.Android.csproj +++ b/Badge/Badge.Plugin.Android/Badge.Plugin.Android.csproj @@ -3,8 +3,6 @@ Debug AnyCPU - 8.0.30703 - 2.0 {56A56F17-7DE1-4CA1-9617-BF32E971AC84} {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} Library @@ -16,6 +14,7 @@ Off True True + v5.0 true @@ -50,13 +49,30 @@ + + + + + + + + + + + + + + + + + - {6edb0588-ffc5-4ef5-8a99-9e241d0f878d} + {6EDB0588-FFC5-4EF5-8A99-9E241D0F878D} Badge.Plugin.Abstractions @@ -68,4 +84,7 @@ --> + + + \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/BadgeImplementation.cs b/Badge/Badge.Plugin.Android/BadgeImplementation.cs old mode 100644 new mode 100755 index 0c5c7c0..a48623f --- a/Badge/Badge.Plugin.Android/BadgeImplementation.cs +++ b/Badge/Badge.Plugin.Android/BadgeImplementation.cs @@ -1,8 +1,35 @@ -using Android; + +using System; using Android.App; -using Android.Content; using Badge.Plugin.Abstractions; +/* + + + + + + + + + + + + + + + + + + + + + + + + +*/ + namespace Badge.Plugin { /// @@ -10,19 +37,13 @@ namespace Badge.Plugin /// public class BadgeImplementation : IBadge { - private const int BadgeNotificationId = int.MinValue; - /// /// Sets the badge. /// /// The badge number. - /// The title. Used only by Android - public void SetBadge(int badgeNumber, string title = null) + public void SetBadge(int badgeNumber) { - var notificationManager = getNotificationManager(); - var notification = createNativeNotification(badgeNumber, title ?? string.Format("{0} new messages", badgeNumber)); - - notificationManager.Notify(BadgeNotificationId, notification); + Badges.SetBadge(Application.Context, badgeNumber); } /// @@ -30,26 +51,7 @@ public void SetBadge(int badgeNumber, string title = null) /// public void ClearBadge() { - var notificationManager = getNotificationManager(); - notificationManager.Cancel(BadgeNotificationId); - } - - private NotificationManager getNotificationManager() - { - var notificationManager = Application.Context.GetSystemService(Context.NotificationService) as NotificationManager; - return notificationManager; - } - - private Notification createNativeNotification(int badgeNumber, string title) - { - var builder = new Notification.Builder(Application.Context) - .SetContentTitle(title) - .SetTicker(title) - .SetNumber(badgeNumber) - .SetSmallIcon(Resource.Drawable.IcDialogEmail); - - var nativeNotification = builder.Build(); - return nativeNotification; + Badges.RemoveBadge(Application.Context); } } } \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/BadgeProviderFactory.cs b/Badge/Badge.Plugin.Android/BadgeProviderFactory.cs new file mode 100755 index 0000000..8b628d9 --- /dev/null +++ b/Badge/Badge.Plugin.Android/BadgeProviderFactory.cs @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Android.Content; +using System.Collections.Generic; +using System; + +namespace Badge.Plugin +{ + /** + * Factory created to provide BadgeProvider implementations depending what launcher is being executed + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + public class BadgeProviderFactory { + + readonly Context context; + Dictionary providers; + + /// + /// Badge provider factory constructor + /// + public BadgeProviderFactory(Context context) { + this.context = context; + providers = new Dictionary(); + + /* from https://github.com/arturogutierrez/Badges */ + providers.Add("com.sec.android.app.launcher", new SamsungBadgeProvider(context)); + providers.Add("com.sec.android.app.twlauncher", new SamsungBadgeProvider(context)); + providers.Add("com.lge.launcher", new LGBadgeProvider(context)); + providers.Add("com.lge.launcher2", new LGBadgeProvider(context)); + providers.Add("com.sonyericsson.home", new SonyBadgeProvider(context)); + providers.Add("com.htc.launcher", new HtcBadgeProvider(context)); + + /* from https://github.com/leolin310148/ShortcutBadger */ + providers.Add("org.adw.launcher", new AdwBadgeProvider(context)); + providers.Add("org.adwfreak.launcher", new AdwBadgeProvider(context)); + providers.Add("com.anddoes.launcher", new ApexBadgeProvider(context)); + providers.Add("com.asus.launcher", new AsusBadgeProvider(context)); + providers.Add("com.teslacoilsw.launcher", new NovaBadgeProvider(context)); + providers.Add("com.majeur.launcher", new SolidBadgeProvider(context)); + providers.Add("com.miui.home", new XiaomiBadgeProvider(context)); + providers.Add("com.miui.miuilite", new XiaomiBadgeProvider(context)); + providers.Add("com.miui.miuihome", new XiaomiBadgeProvider(context)); + providers.Add("com.miui.miuihome2", new XiaomiBadgeProvider(context)); + providers.Add("com.miui.mihome", new XiaomiBadgeProvider(context)); + providers.Add("com.miui.mihome2", new XiaomiBadgeProvider(context)); + } + + /// + /// Get badge provider + /// + public BadgeProvider GetBadgeProvider() { + string currentPackage = GetHomePackage(); + + return providers.ContainsKey (currentPackage) ? providers [currentPackage] : new DefaultBadgeProvider (context); //new NullBadgeProvider (); + } + + private string GetHomePackage() { + var identify = new HomePackageIdentify(); + return identify.GetHomePackage(context); + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Badges.cs b/Badge/Badge.Plugin.Android/Badges.cs new file mode 100755 index 0000000..914e880 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Badges.cs @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Android.Content; +using Java.Lang; + +namespace Badge.Plugin +{ + + /** + * Helper to set badge count on current application icon on any supported launchers. + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + public static class Badges { + + /** + * Set badge count on app icon + * + * @param context context activity + * @param count should be >= 0, passing count as 0 the badge will be removed. + * @throws BadgesNotSupportedException when the current launcher is not supported by Badges + */ + public static void SetBadge(Context context, int count) { + + if (context == null) { + throw new BadgesNotSupportedException(); + } + + var badgeFactory = new BadgeProviderFactory(context); + var badgeProvider = badgeFactory.GetBadgeProvider(); + + try { + badgeProvider.SetBadge(count); + } catch (UnsupportedOperationException e) { + throw new BadgesNotSupportedException(); + } + } + + /** + * Remove current badge count + * + * @param context context activity + * @throws BadgesNotSupportedException when the current launcher is not supported by Badges + */ + + public static void RemoveBadge(Context context) { + Badges.SetBadge(context, 0); + } + } +} diff --git a/Badge/Badge.Plugin.Android/BadgesNotSupportedException.cs b/Badge/Badge.Plugin.Android/BadgesNotSupportedException.cs new file mode 100755 index 0000000..ac7b97e --- /dev/null +++ b/Badge/Badge.Plugin.Android/BadgesNotSupportedException.cs @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using System; + +namespace Badge.Plugin +{ + + /** + * Exception to tell the current launcher is not supported by Badges library. + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + public class BadgesNotSupportedException : Exception { + + /// + /// Current home launcher is not supported by Badges library + /// + public BadgesNotSupportedException() + : base("Current home launcher is not supported by Badges library") + { + } + + /// + /// The home launcher package is not supported by Badges library + /// + public BadgesNotSupportedException(String homePackage) + : base(string.Format("The home launcher with package {0} is not supported by Badges library", homePackage)) + { + } + } + +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/HomePackageIdentify.cs b/Badge/Badge.Plugin.Android/HomePackageIdentify.cs new file mode 100755 index 0000000..d94574f --- /dev/null +++ b/Badge/Badge.Plugin.Android/HomePackageIdentify.cs @@ -0,0 +1,33 @@ + +using Android.Content; +using Android.Content.PM; + +namespace Badge.Plugin +{ + /** + * Helper to identify the package of current home launcher running + * + * Created by Arturo Gutiérrez on 19/12/14. + * + * ported to C# by Alex Rainman + */ + public class HomePackageIdentify { + + /// + /// Get home package + /// + public string GetHomePackage(Context context) { + + var intent = new Intent(Intent.ActionMain); + intent.AddCategory(Intent.CategoryHome); + + ResolveInfo resolveInfo = context.PackageManager.ResolveActivity(intent, PackageInfoFlags.MatchDefaultOnly); + + if (resolveInfo != null && resolveInfo.ActivityInfo != null && resolveInfo.ActivityInfo.PackageName != null) { + return resolveInfo.ActivityInfo.PackageName; + } + + return context.PackageName; + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/AdwBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/AdwBadgeProvider.cs new file mode 100644 index 0000000..beac194 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/AdwBadgeProvider.cs @@ -0,0 +1,29 @@ + +using Android.Content; + +namespace Badge.Plugin +{ + /** + * @author Gernot Pansy + * + * ported to C# by Alex Rainman + */ + class AdwBadgeProvider : BadgeProvider { + + public AdwBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("org.adw.launcher.counter.SEND"); + intent.PutExtra("PNAME", GetPackageName()); + intent.PutExtra("COUNT", count); + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/ApexBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/ApexBadgeProvider.cs new file mode 100644 index 0000000..0958998 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/ApexBadgeProvider.cs @@ -0,0 +1,31 @@ + +using Android.Content; + +namespace Badge.Plugin +{ + /** + * @author Gernot Pansy + * + * ported to C# by Alex Rainman + */ + class ApexBadgeProvider : BadgeProvider { + + public ApexBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("com.anddoes.launcher.COUNTER_CHANGED"); + intent.PutExtra("package", GetPackageName()); + intent.PutExtra("count", count); + intent.PutExtra("class", GetMainActivityClassName()); + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} + diff --git a/Badge/Badge.Plugin.Android/Providers/AsusBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/AsusBadgeProvider.cs new file mode 100644 index 0000000..4c5b3d7 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/AsusBadgeProvider.cs @@ -0,0 +1,31 @@ +using Android.Content; + +namespace Badge.Plugin +{ + /** + * @author leolin + * + * ported to C# by Alex Rainman + */ + class AsusBadgeProvider : BadgeProvider { + + public AsusBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); + intent.PutExtra("badge_count", count); + intent.PutExtra("badge_count_package_name", GetPackageName()); + intent.PutExtra("badge_count_class_name", GetMainActivityClassName()); + intent.PutExtra("badge_vip_count", 0); + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} + diff --git a/Badge/Badge.Plugin.Android/Providers/BadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/BadgeProvider.cs new file mode 100755 index 0000000..9d9c1fb --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/BadgeProvider.cs @@ -0,0 +1,70 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Android.Content; + +namespace Badge.Plugin +{ + /** + * Abstract class created to be implemented by different classes to provide badge change support on + * different launchers. + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + + public class BadgeProvider { + + /// + /// Badge provider context + /// + protected Context mContext; + + /// + /// Badge provider constructor + /// + public BadgeProvider(Context context) { + mContext = context; + } + + /// + /// Virtual set badge + /// + public virtual void SetBadge(int count){ + } + + /// + /// Virtual remove badge + /// + public virtual void RemoveBadge(){ + } + + /// + /// Get package name + /// + protected string GetPackageName() { + return mContext.PackageName; + } + + /// + /// Get main activity class name + /// + protected string GetMainActivityClassName() { + return mContext.PackageManager.GetLaunchIntentForPackage(GetPackageName()).Component.ClassName; + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/DefaultBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/DefaultBadgeProvider.cs new file mode 100644 index 0000000..e3821e2 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/DefaultBadgeProvider.cs @@ -0,0 +1,31 @@ +using System; +using Android.Content; + +namespace Badge.Plugin +{ + /** + * @author leolin + * + * ported to C# by Alex Rainman + */ + class DefaultBadgeProvider : BadgeProvider { + + public DefaultBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); + intent.PutExtra("badge_count", count); + intent.PutExtra("badge_count_package_name", GetPackageName()); + intent.PutExtra("badge_count_class_name", GetMainActivityClassName()); + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} + diff --git a/Badge/Badge.Plugin.Android/Providers/HtcBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/HtcBadgeProvider.cs new file mode 100755 index 0000000..6e7f792 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/HtcBadgeProvider.cs @@ -0,0 +1,55 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +//import android.content.ComponentName; +//import android.content.Context; +//import android.content.Intent; +using Android.Content; + +namespace Badge.Plugin +{ + /** + * BadgeProvider implementation to support badges on HTC devices. + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + class HtcBadgeProvider : BadgeProvider { + + public HtcBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT"); + intent.PutExtra("packagename", GetPackageName()); + intent.PutExtra("count", count); + mContext.SendBroadcast (intent); + + var setNotificationIntent = new Intent("com.htc.launcher.action.SET_NOTIFICATION"); + var componentName = new ComponentName(GetPackageName(), GetMainActivityClassName()); + setNotificationIntent.PutExtra("com.htc.launcher.extra.COMPONENT", componentName.FlattenToShortString()); + setNotificationIntent.PutExtra("com.htc.launcher.extra.COUNT", count); + mContext.SendBroadcast(setNotificationIntent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/LGBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/LGBadgeProvider.cs new file mode 100755 index 0000000..769fc7d --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/LGBadgeProvider.cs @@ -0,0 +1,47 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using Android.Content; + +namespace Badge.Plugin +{ + /** + * BadgeProvider implementation to support badges on LG devices. + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + class LGBadgeProvider : BadgeProvider { + + public LGBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); + intent.PutExtra("badge_count_package_name", GetPackageName()); + intent.PutExtra("badge_count_class_name", GetMainActivityClassName()); + intent.PutExtra("badge_count", count); + + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} diff --git a/Badge/Badge.Plugin.Android/Providers/NovaBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/NovaBadgeProvider.cs new file mode 100644 index 0000000..9c1ef8a --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/NovaBadgeProvider.cs @@ -0,0 +1,41 @@ +using System; +using Android.Content; + +namespace Badge.Plugin +{ + /** + * Shortcut Badger support for Nova Launcher. + * TeslaUnread must be installed. + * User: Gernot Pansy + * Date: 2014/11/03 + * Time: 7:15 + * + * ported to C# by Alex Rainman + */ + class NovaBadgeProvider : BadgeProvider { + + public NovaBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + try { + var contentValues = new ContentValues(); + contentValues.Put("tag", GetPackageName() + "/" + GetMainActivityClassName()); + contentValues.Put("count", count); + mContext.ContentResolver.Insert(Android.Net.Uri.Parse("content://com.teslacoilsw.notifier/unread_count"), contentValues); + } catch (Java.Lang.IllegalArgumentException ex) { + /* Fine, TeslaUnread is not installed. */ + } catch (Exception ex) { + /* Some other error, possibly because the format of the ContentValues are incorrect. */ + throw new BadgesNotSupportedException(ex.Message); + } + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} + diff --git a/Badge/Badge.Plugin.Android/Providers/NullBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/NullBadgeProvider.cs new file mode 100755 index 0000000..a047b1c --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/NullBadgeProvider.cs @@ -0,0 +1,41 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Java.Lang; + +namespace Badge.Plugin +{ + /** + * NullObject implementation for BadgeProvider (not used, replaced by DefaultBadgeProvider). + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + class NullBadgeProvider : BadgeProvider { + + public NullBadgeProvider() : base(null) { + } + + public override void SetBadge(int count){ + throw new UnsupportedOperationException(); + } + + public override void RemoveBadge() { + throw new UnsupportedOperationException(); + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/SamsungBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/SamsungBadgeProvider.cs new file mode 100755 index 0000000..85e924d --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/SamsungBadgeProvider.cs @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +using Android.Content; +using System; + +namespace Badge.Plugin +{ + /** + * BadgeProvider implementation to support badges on Samsung devices (WITH FIXES). + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# and fixed by Alex Rainman + */ + class SamsungBadgeProvider : BadgeProvider { + + static Android.Net.Uri CONTENT_URI = Android.Net.Uri.Parse("content://com.sec.badge/apps"); + //const string COLUMN_ID = "_id"; + //const string COLUMN_PACKAGE = "package"; + //const string COLUMN_CLASS = "class"; + //const string COLUMN_BADGE_COUNT = "badgecount"; + + public SamsungBadgeProvider(Context context) : base(context){ + } + + public override void SetBadge(int count) { + try { + + /*ContentResolver contentResolver = mContext.ContentResolver; + var cursor = contentResolver.Query(CONTENT_URI, new string[]{ COLUMN_ID }, COLUMN_PACKAGE + "=?", new string[]{ GetPackageName() }, null); + + if (cursor == null || !cursor.MoveToFirst()) { + var contentValues = new ContentValues(); + contentValues.Put(COLUMN_PACKAGE, GetPackageName()); + contentValues.Put(COLUMN_CLASS, GetMainActivityClassName()); + contentValues.Put(COLUMN_BADGE_COUNT, count); + contentResolver.Insert(CONTENT_URI, contentValues); + } else { + int idColumnIndex = cursor.GetColumnIndex(COLUMN_ID); + + var contentValues = new ContentValues(); + contentValues.Put(COLUMN_BADGE_COUNT, count); + contentResolver.Update(CONTENT_URI, contentValues, COLUMN_ID + "=?", new string[]{ cursor.GetInt(idColumnIndex).ToString() }); + }*/ + + var cv = new ContentValues(); + cv.Put("package", GetPackageName()); + cv.Put("class", GetMainActivityClassName()); + cv.Put("badgecount", count); // integer count you want to display + + ContentResolver contentResolver = mContext.ContentResolver; + + int updated = contentResolver.Update(CONTENT_URI, cv, "package=?", new string[] { GetPackageName() }); + + if (updated == 0) + contentResolver.Insert(CONTENT_URI, cv); + + } catch (Exception e) { + // Some Samsung devices are throwing SecurityException or RuntimeException when + // trying to set the badge saying the app needs permission which are already added, + // this try/catch protect us from these "crappy phones" :) + throw new Java.Lang.UnsupportedOperationException(); + } + } + + public override void RemoveBadge() { + SetBadge(0); + } + + /*const string CONTENT_URI = "content://com.sec.badge/apps?notify=true"; + static string[] CONTENT_PROJECTION = new string[]{ "_id","class" }; + + public SamsungBadgeProvider(Context context) : base(context){ + } + + public override void SetBadge(int count) { + Android.Net.Uri mUri = Android.Net.Uri.Parse(CONTENT_URI); + ContentResolver contentResolver = mContext.ContentResolver; + try { + var cursor = contentResolver.Query(mUri, CONTENT_PROJECTION, "package=?", new string[]{ GetPackageName() }, null); + if (cursor != null) { + string entryActivityName = GetMainActivityClassName(); + bool entryActivityExist = false; + while (cursor.MoveToNext()) { + int id = cursor.GetInt(0); + ContentValues contentValues = GetContentValues(count, false); + contentResolver.Update(mUri, contentValues, "_id=?", new String[]{ id.ToString() }); + entryActivityExist |= entryActivityName.Equals (cursor.GetString (cursor.GetColumnIndex ("class"))); + } + + if (!entryActivityExist) { + ContentValues contentValues = GetContentValues(count, true); + contentResolver.Insert(mUri, contentValues); + } + } + } catch (Exception e) { + // Some Samsung devices are throwing SecurityException or RuntimeException when + // trying to set the badge saying the app needs permission which are already added, + // this try/catch protect us from these "crappy phones" :) + throw new Java.Lang.UnsupportedOperationException(); + } + } + + public override void RemoveBadge() { + SetBadge(0); + } + + ContentValues GetContentValues(int count, bool isInsert) { + var contentValues = new ContentValues(); + if (isInsert) { + contentValues.Put("package", GetPackageName()); + contentValues.Put("class", GetMainActivityClassName()); + } + + contentValues.Put("badgecount", count); + + return contentValues; + }*/ + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/SolidBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/SolidBadgeProvider.cs new file mode 100644 index 0000000..8ae7f5e --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/SolidBadgeProvider.cs @@ -0,0 +1,31 @@ + +using Android.Content; + +namespace Badge.Plugin +{ + /** + * @author MajeurAndroid + * + * ported to C# by Alex Rainman + */ + class SolidBadgeProvider : BadgeProvider { + + public SolidBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent("com.majeur.launcher.intent.action.UPDATE_BADGE"); + intent.PutExtra("com.majeur.launcher.intent.extra.BADGE_PACKAGE", GetPackageName()); + intent.PutExtra("com.majeur.launcher.intent.extra.BADGE_COUNT", count); + intent.PutExtra("com.majeur.launcher.intent.extra.BADGE_CLASS", GetMainActivityClassName()); + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} + diff --git a/Badge/Badge.Plugin.Android/Providers/SonyBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/SonyBadgeProvider.cs new file mode 100755 index 0000000..c88d637 --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/SonyBadgeProvider.cs @@ -0,0 +1,50 @@ +/* + * Copyright (C) 2014 Arturo Gutiérrez Díaz-Guerra. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +using Android.Content; + +namespace Badge.Plugin +{ + /** + * BadgeProvider implementation to support badges on Sony devices. + * + * @author Arturo Gutiérrez Díaz-Guerra + * + * ported to C# by Alex Rainman + */ + class SonyBadgeProvider : BadgeProvider { + + public SonyBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + var intent = new Intent(); + + intent.SetAction("com.sonyericsson.home.action.UPDATE_BADGE"); + intent.PutExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", GetPackageName()); + intent.PutExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", GetMainActivityClassName()); + intent.PutExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", count > 0); + intent.PutExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", count.ToString()); + + mContext.SendBroadcast(intent); + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} \ No newline at end of file diff --git a/Badge/Badge.Plugin.Android/Providers/XiaomiBadgeProvider.cs b/Badge/Badge.Plugin.Android/Providers/XiaomiBadgeProvider.cs new file mode 100644 index 0000000..3fcc87e --- /dev/null +++ b/Badge/Badge.Plugin.Android/Providers/XiaomiBadgeProvider.cs @@ -0,0 +1,40 @@ + +using Android.Content; +using Java.Lang; +using Java.Lang.Reflect; + +namespace Badge.Plugin +{ + /** + * @author leolin + * + * ported to C# by Alex Rainman + */ + class XiaomiBadgeProvider : BadgeProvider { + + public XiaomiBadgeProvider(Context context) + : base(context) + { + } + + public override void SetBadge(int count) { + try { + Class miuiNotificationClass = Class.ForName("android.app.MiuiNotification"); + Object miuiNotification = miuiNotificationClass.NewInstance(); + Field field = miuiNotification.Class.GetDeclaredField("messageCount"); + field.Accessible = true; + field.Set(miuiNotification, count == 0 ? "" : count.ToString()); + } catch (System.Exception e) { + var localIntent = new Intent("android.intent.action.APPLICATION_MESSAGE_UPDATE"); + localIntent.PutExtra("android.intent.extra.update_application_component_name", GetPackageName() + "/" + GetMainActivityClassName()); + localIntent.PutExtra("android.intent.extra.update_application_message_text", count == 0 ? "" : count.ToString()); + mContext.SendBroadcast(localIntent); + } + } + + public override void RemoveBadge() { + SetBadge(0); + } + } +} + diff --git a/Badge/Badge.Plugin.iOS/BadgeImplementation.cs b/Badge/Badge.Plugin.iOS/BadgeImplementation.cs old mode 100644 new mode 100755 index 38e7501..757879c --- a/Badge/Badge.Plugin.iOS/BadgeImplementation.cs +++ b/Badge/Badge.Plugin.iOS/BadgeImplementation.cs @@ -24,8 +24,7 @@ public void ClearBadge() /// Sets the badge. /// /// The badge number. - /// The title. Used only by Android - public void SetBadge(int badgeNumber, string title = null) + public void SetBadge(int badgeNumber) { UIApplication.SharedApplication.ApplicationIconBadgeNumber = badgeNumber; } diff --git a/README.md b/README.md index 4cc423d..096b5a3 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,32 @@ Simple cross platform plugin to work with application badge * Windows Phone 8.1 RT * Windows Store 8.0+ +**Xamarin.Android Fix** + +Android doesn't supports app icon badge by default but third party manufacturers launchers do. + +Now the plugin support these: + +* Samsung +* HTC +* LG +* Sony +* Xiaomi +* Adw +* Apex +* Asus +* Nova +* Solid +* Default (because some launchers use android.intent.action.BADGE_COUNT_UPDATE to update count) + +Thanks to: + +https://github.com/arturogutierrez/Badges + +and + +https://github.com/leolin310148/ShortcutBadger + ### API Usage Call **CrossBadge.Current** from any project or PCL to gain access to APIs.