Android 在应用图标上设置未读消息数量

简介: Android 在应用图标上设置未读消息数量
* 针对国内支持的Launcher分别开发,支持为:
* ** 常见机型及是否支持
* *** 华为 支持
* 小米 支持
* OPPO 可以支持但需要申请
* VIVO 不支持
* SAMSUNG 支持
* MEIZU 不支持
* google 8.0开始支持 显示一个点,长按点弹出数字

image.gif

不造轮子不累赘叙述,直接封装

使用方法:

1.在使用之前首先 初始化 ,三个方法的参数分别是 应用包名/启动页的Activity及Context,四个参数的构造方法第三个是notification

DesktopCornerUtil.init("com.lonbon.nytest", "com.lonbon.view.activity.WelcomeActivity", BaseApplication.context);

image.gif

/**
 * 初始化 init 建议放在Application中执行
 * t is recommended to execute in Application
 *
 * @param packageNameParameter      @desc 应用包名
 * @param mainActivityNameParameter @desc MainActivity
 * @param contextParameter          @desc BaseApplication context
 */
public static void init(String packageNameParameter, String mainActivityNameParameter, Context contextParameter) {
    packageName = packageNameParameter;
    context = contextParameter;
    mainActivityName = mainActivityNameParameter;
}

image.gif

2.设置未读数量

DesktopCornerUtil.setBadgeNumber(1);

image.gif

注意的是:小米系统是自动会有的,且小米和三星系统 必须在后台设置才有效,前台设置无效,比如直接在前台时diamagnetic设置为10,那么不会显示,如果后台时收到通知会自动显示10

3.所有代码 转载请标明出处 欢迎反馈问题

/**
 * @author Huanglinqing
 * @blog: https://blog.csdn.net/huangliniqng
 * @date 2019/6/26
 * @desc 桌面角标显示方案 单例模式
 * <p>
 * 针对国内支持的Launcher分别开发,支持为:
 * ** 常见机型及是否支持
 * *** 华为 支持
 * 小米 支持
 * OPPO 可以支持但需要申请
 * VIVO 不支持
 * SAMSUNG 支持
 * MEIZU 不支持
 * google 8.0开始支持 显示一个点,长按点弹出数字
 * 其他杂牌机不支持
 * <p>
 * ------------------------------------------------------
 * English:
 * <p>
 * * Developed separately for the domestically supported Launcher, the support is:
 *   * ** Common models and support
 *   * *** Huawei Support
 *   * Xiaomi Support
 *   * OPPO can support but need to apply
 *   * VIVO does not support
 *   * SAMSUNG support
 *   * MEIZU does not support
 *   * google 8.0 starts to support display a point, long press the point to pop up the number
 *   * Other brands are not supported
 */
public class DesktopCornerUtil {
    /**
     * 华为手机launcher主题
     * <p>
     * Huawei mobile phone launcher theme
     */
    private static final String HUWEI_LAUNCHERNAME = "com.huawei.android.launcher";
    /**
     * 小米手机launcher主题
     * <p>
     * MIUI phone launcher theme
     */
    private static final String MIUI_LAUNCHERNAME = "com.miui.home";
    /**
     * 摩托罗拉和宏达手机launcher主题
     * <p>
     * Motorola and HTC mobile phone launcher theme
     */
    private static final String MOTOANDHTC_LAUNCHERNAME = " com.android.launcher";
    /**
     * 三星手机launcher主题
     * <p>
     * Samsung mobile phone launcher theme
     */
    private static final String SAMSUNG_LAUNCHERNAME = "com.sec.android.app.launcher";
    /**
     * google 手机launcher主题
     * <p>
     * Google phone launcher theme
     */
    private static final String GOOGLE_LAUNCHERNAME = "com.google.android.apps.nexuslauncher";
    private volatile static DesktopCornerUtil desktopCornerUtil;
    /**
     * vivo手机厂商名字
     * Vivo mobile phone manufacturer name
     */
    private static final String VIVO_MANUFACTURER_NAME = "vivo";
    /**
     * OPPO 手机厂商名字
     * OPPO mobile phone manufacturer name
     */
    private static final String OPPO_MANUFACTURER_NANE = "OPPO";
    /**
     * 应用包名
     * Application package name
     */
    private static String packageName = null;
    /**
     * context 对象 这里建议传递Application的context 避免内存泄漏
     * It is recommended to pass the Application context to avoid memory leaks.
     */
    static Context context = null;
    /**
     * 主Activity的名字 为全路径 比如 com.***..**Activity
     * The name of the main Activity is the full path. For example, com.***..**Activity
     */
    private static String mainActivityName = null;
    /**
     * notification 对象 小米系统会默认设置 如果修改默认逻辑 必须获取notification对象
     * The millet system will default settings. If you modify the default logic,
     * you must get the notification object.
     */
    private static Notification notification = null;
    private DesktopCornerUtil() {
    }
    public static DesktopCornerUtil getInstance() {
        if (desktopCornerUtil == null) {
            synchronized (DesktopCornerUtil.class) {
                if (desktopCornerUtil == null) {
                    desktopCornerUtil = new DesktopCornerUtil();
                }
            }
        }
        return desktopCornerUtil;
    }
    /**
     * 初始化 init 建议放在Application中执行
     * t is recommended to execute in Application
     *
     * @param packageNameParameter      @desc 应用包名
     * @param mainActivityNameParameter @desc MainActivity
     * @param contextParameter          @desc BaseApplication context
     */
    public static void init(String packageNameParameter, String mainActivityNameParameter, Context contextParameter) {
        packageName = packageNameParameter;
        context = contextParameter;
        mainActivityName = mainActivityNameParameter;
    }
    /**
     * @param packageNameParameter  @desc 应用包名
     * @param mainActivityNameParameter @desc MainActivity
     * @param notication        通知
     * @param contextParameter  @desc BaseApplication context
     */
    public static void init(String packageNameParameter, String mainActivityNameParameter, Notification notication, Context contextParameter) {
        packageName = packageNameParameter;
        context = contextParameter;
        mainActivityName = mainActivityNameParameter;
    }
    /**
     * 获取launcher相关信息  根据launcher
     * 分别开发
     * <p>
     * miui: com.miui.home
     * <p>
     * huawei: com.huawei.android.launcher
     * <p>
     * moto and htc: com.android.launcher
     * <p>
     * samsung: com.sec.android.app.launcher
     * <p>
     * goole:com.google.android.apps.nexuslauncher
     * <p>
     * BaseApplication.getContext() is Application context
     *
     * @return
     */
    private static String getLauncherMessage() {
        Intent intent = new Intent(Intent.ACTION_MAIN);
        intent.addCategory(Intent.CATEGORY_HOME);
        if (context == null) {
            return "";
        } else {
            final ResolveInfo res = context
                    .getPackageManager().resolveActivity(intent, 0);
            if (res.activityInfo == null) {
                return "";
            }
            if (context.getString(R.string.android).
                    equals(res.activityInfo.packageName)) {
                return "";
            }
            return res.activityInfo.packageName;
        }
    }
    /**
     * 设置角标数字
     * Set the angle number
     *
     * @param badgeNumber @desc 数量
     */
    public static void setBadgeNumber(int badgeNumber) {
        if (badgeNumber >= 0) {
            switch (getLauncherMessage()) {
                case HUWEI_LAUNCHERNAME:
                    setBadgeNumberHuawei(badgeNumber);
                    break;
                case MIUI_LAUNCHERNAME:
                    setBadgeNumberMiui(badgeNumber);
                    break;
                case MOTOANDHTC_LAUNCHERNAME:
                    setBadgeNumberhtc(badgeNumber);
                    break;
                case SAMSUNG_LAUNCHERNAME:
                    setBadgeNumberSamsung(badgeNumber);
                    break;
                case GOOGLE_LAUNCHERNAME:
                    setBadgeNumberGoogle(badgeNumber);
                    break;
                default:
                    //再根据制造商去判断
                    String manufacturer = Build.MANUFACTURER;
                    switch (manufacturer) {
                        case VIVO_MANUFACTURER_NAME:
                            setBadgeNumberVivo(badgeNumber);
                            break;
                        case OPPO_MANUFACTURER_NANE:
                            setBadgeNumberOppo(badgeNumber);
                            break;
                        default:
                            break;
                    }
                    break;
            }
        } else {
            // TODO: 2019/6/27 donothing
        }
    }
    /**
     * Google手机设置角标 只支持8.0以上
     * Google phone settings corner Only supports 8.0 or above
     *
     * @param badgeNumber @desc 数量
     */
    private static void setBadgeNumberGoogle(int badgeNumber) {
        if (TextUtils.isEmpty(packageName)) {
            return;
        }
        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.O) {
            return;
        }
        Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
        intent.putExtra("badge_count", badgeNumber);
        intent.putExtra("badge_count_package_name", packageName);
        intent.putExtra("badge_count_class_name", mainActivityName);
        context.sendBroadcast(intent);
    }
    /**
     * htc和摩托罗拉设置角标
     * Htc and Motorola set the corners
     *
     * @param badgeNumber @desc 数量
     */
    private static void setBadgeNumberhtc(int badgeNumber) {
        if (TextUtils.isEmpty(packageName)) {
            return;
        }
        Intent intentNotification = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
        intentNotification.putExtra("com.htc.launcher.extra.COMPONENT", packageName);
        intentNotification.putExtra("com.htc.launcher.extra.COUNT", badgeNumber);
        context.sendBroadcast(intentNotification);
        Intent intentShortcut = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
        intentShortcut.putExtra("packagename", packageName);
        intentShortcut.putExtra("count", badgeNumber);
        context.sendBroadcast(intentShortcut);
    }
    /**
     * 小米手机设置角标
     * MIUI mobile phone settings corner
     * 当APP处于前台时,数字会自动清空
     * When the app is in the foreground, the number will be automatically cleared.
     *
     * @param badgeNumber @desc 数量
     */
    private static void setBadgeNumberMiui(int badgeNumber) {
        try {
            if (notification == null) {
                return;
            } else {
                Field field = notification.getClass().getDeclaredField("extraNotification");
                Object extraNotification = field.get(notification);
                Method method = extraNotification.getClass().getDeclaredMethod("setMessageCoun", int.class);
                method.invoke(extraNotification, badgeNumber);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 华为手机设置角标
     * Huawei mobile phone settings corner
     *
     * @param badgeNumber @desc 数量
     */
    private static void setBadgeNumberHuawei(int badgeNumber) {
        if (TextUtils.isEmpty(packageName)) {
            return;
        }
        Bundle extra = new Bundle();
        extra.putString("package", packageName);
        extra.putString("class", mainActivityName);
        extra.putInt("badgenumber", badgeNumber);
        context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"),
                "change_badge", null, extra);
    }
    /**
     * 三星手机 设置角标
     * Samsung mobile phone set corner
     *
     * @param badgeNumber @desc 数量
     */
    private static void setBadgeNumberSamsung(int badgeNumber) {
        if (TextUtils.isEmpty(packageName)) {
            return;
        }
        Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
        intent.putExtra("badge_count", badgeNumber);
        intent.putExtra("badge_count_package_name", packageName);
        intent.putExtra("badge_count_class_name", mainActivityName);
        context.sendBroadcast(intent);
    }
    /**
     * vivo 手机 设置角标
     * Vivo mobile phone set corner
     *
     * @param badgeNumber @desc 数量
     */
    public static void setBadgeNumberVivo(int badgeNumber) {
        try {
            Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
            intent.putExtra("packageName", packageName);
            String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
            intent.putExtra("className", launchClassName);
            intent.putExtra("notificationNum", badgeNumber);
            context.sendBroadcast(intent);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    /**
     * 服务是否启动
     *
     * @param intent @desc 查找的服务
     * @return
     */
    public static boolean broadcastStarts(Intent intent) {
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0);
        return receivers != null && receivers.size() > 0;
    }
    /**
     * Oppo 手机 设置角标
     * OPPO mobile phone set corner
     *
     * @param badgeNumber @desc 数量
     */
    public static void setBadgeNumberOppo(int badgeNumber) {
        try {
            Intent intent = new Intent("com.oppo.unsettledevent");
            intent.putExtra("pakeageName", context.getPackageName());
            intent.putExtra("number", badgeNumber);
            intent.putExtra("upgradeNumber", badgeNumber);
            if (broadcastStarts(intent)) {
                context.sendBroadcast(intent);
            } else {
                try {
                    Bundle extras = new Bundle();
                    extras.putInt("app_badge_count", badgeNumber);
                    context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extras);
                } catch (Throwable th) {
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

image.gif


目录
相关文章
|
9天前
|
IDE Java 开发工具
深入探索安卓应用开发:从环境搭建到第一个"Hello, World!"应用
本文将引导读者完成安卓应用开发的初步入门,包括安装必要的开发工具、配置开发环境、创建第一个简单的安卓项目,以及解释其背后的一些基本概念。通过一步步的指导和解释,本文旨在为安卓开发新手提供一个清晰、易懂的起点,帮助读者顺利地迈出安卓开发的第一步。
183 64
|
8天前
|
存储 Java Android开发
探索安卓应用开发:构建你的第一个"Hello World"应用
【9月更文挑战第24天】在本文中,我们将踏上一段激动人心的旅程,深入安卓应用开发的奥秘。通过一个简单而经典的“Hello World”项目,我们将解锁安卓应用开发的基础概念和步骤。无论你是编程新手还是希望扩展技能的老手,这篇文章都将为你提供一次实操体验。从搭建开发环境到运行你的应用,每一步都清晰易懂,确保你能顺利地迈出安卓开发的第一步。让我们开始吧,探索如何将一行简单的代码转变为一个功能齐全的安卓应用!
|
13天前
|
开发框架 搜索推荐 开发工具
打造个性化安卓应用:从零开始的Flutter之旅
【8月更文挑战第51天】本文是一篇面向初学者的Flutter入门教程,旨在通过简单易懂的语言和实际代码示例,引导读者步入跨平台移动应用开发的世界。文章首先介绍了Flutter的基本概念和优势,然后逐步展示了如何搭建开发环境、创建第一个Flutter应用,并实现了一个简单的待办事项列表。最后,文章探讨了Flutter在实现高性能和美观界面方面的潜力,鼓励读者发挥创意,探索更多可能。
63 15
|
3天前
|
监控 安全 Java
Kotlin 在公司上网监控中的安卓开发应用
在数字化办公环境中,公司对员工上网行为的监控日益重要。Kotlin 作为一种基于 JVM 的编程语言,具备简洁、安全、高效的特性,已成为安卓开发的首选语言之一。通过网络请求拦截,Kotlin 可实现网址监控、访问时间记录等功能,满足公司上网监控需求。其简洁性有助于快速构建强大的监控应用,并便于后续维护与扩展。因此,Kotlin 在安卓上网监控应用开发中展现出广阔前景。
7 1
|
17天前
|
搜索推荐 Java Android开发
打造个性化安卓应用:从设计到发布的全程指南
【9月更文挑战第15天】本篇文章将带领读者踏上一段激动人心的旅程,从构思一个独特的安卓应用想法开始,直至将其变为现实并成功发布。我们将一起探索如何捕捉灵感、设计界面、编写代码以及最终将应用推向市场。无论你是编程新手还是有经验的开发者,这篇文章都将为你提供宝贵的洞见和实用的技巧,让你的应用在竞争激烈的市场中脱颖而出。
53 17
|
13天前
|
Java Android开发 UED
🧠Android多线程与异步编程实战!告别卡顿,让应用响应如丝般顺滑!🧵
在Android开发中,为应对复杂应用场景和繁重计算任务,多线程与异步编程成为保证UI流畅性的关键。本文将介绍Android中的多线程基础,包括Thread、Handler、Looper、AsyncTask及ExecutorService等,并通过示例代码展示其实用性。AsyncTask适用于简单后台操作,而ExecutorService则能更好地管理复杂并发任务。合理运用这些技术,可显著提升应用性能和用户体验,避免内存泄漏和线程安全问题,确保UI更新顺畅。
35 5
|
14天前
|
前端开发 Java 数据库
💡Android开发者必看!掌握这5大框架,轻松打造爆款应用不是梦!🏆
在Android开发领域,框架犹如指路明灯,助力开发者加速应用开发并提升品质。本文将介绍五大必备框架:Retrofit简化网络请求,Room优化数据库访问,MVVM架构提高代码可维护性,Dagger 2管理依赖注入,Jetpack Compose革新UI开发。掌握这些框架,助你在竞争激烈的市场中脱颖而出,打造爆款应用。
80 3
|
14天前
|
存储 API Android开发
"解锁Android权限迷宫:一场惊心动魄的动态权限请求之旅,让你的应用从平凡跃升至用户心尖的宠儿!"
随着Android系统的更新,权限管理成为应用开发的关键。尤其在Android 6.0(API 级别 23)后,动态权限请求机制的引入提升了用户隐私保护,要求开发者进行更精细的权限管理。
41 2
|
15天前
|
搜索推荐 Java 测试技术
打造个性化安卓应用:从设计到发布的完全指南
【9月更文挑战第17天】在这个数字时代,拥有一款个性化的安卓应用无疑是展现创意、实现梦想的一大步。本文将带你走进安卓应用的开发世界,从设计理念的孕育到实际代码的编写,再到最终的应用发布,我们将一步步揭开应用开发的神秘面纱。无论你是编程新手还是希望提升现有技能,这篇文章都将是你的宝贵资源。让我们开始这段激动人心的旅程吧!
|
19天前
|
监控 算法 数据可视化
深入解析Android应用开发中的高效内存管理策略在移动应用开发领域,Android平台因其开放性和灵活性备受开发者青睐。然而,随之而来的是内存管理的复杂性,这对开发者提出了更高的要求。高效的内存管理不仅能够提升应用的性能,还能有效避免因内存泄漏导致的应用崩溃。本文将探讨Android应用开发中的内存管理问题,并提供一系列实用的优化策略,帮助开发者打造更稳定、更高效的应用。
在Android开发中,内存管理是一个绕不开的话题。良好的内存管理机制不仅可以提高应用的运行效率,还能有效预防内存泄漏和过度消耗,从而延长电池寿命并提升用户体验。本文从Android内存管理的基本原理出发,详细讨论了几种常见的内存管理技巧,包括内存泄漏的检测与修复、内存分配与回收的优化方法,以及如何通过合理的编程习惯减少内存开销。通过对这些内容的阐述,旨在为Android开发者提供一套系统化的内存优化指南,助力开发出更加流畅稳定的应用。
38 0
下一篇
无影云桌面