2022-01-26 Android应用角标适配方法,源码在三星和华为上测试通过。

一、应用的角标如下面的红点,提示用户有新的信息更新。角标,英语是badge,也就是“徽章,像章,奖章; 象征,标记”的意思。一般来说,应用的角标是用来标记有多少条提醒(Notification)没读(unread),一旦点击提示进应用阅读了,角标也会消失。

二、如何实现呢?原生是不支持应用角标的,是各个手机厂商自己在系统中实现的应用角标,并且部分厂商提供了设置的方式,所以需要对各个厂商的系统进行适配。

三、华为手机的实现代码,参考华为开发者文档,需要添加权限

    <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE "/>
    private static boolean setHuaweiBadge(int count, Context context) {
        try {
            String launchClassName = getLauncherClassName(context);
            if (TextUtils.isEmpty(launchClassName)) {
                return false;
            }
            Bundle bundle = new Bundle();
            bundle.putString("package", context.getPackageName());
            bundle.putString("class", launchClassName);
            bundle.putInt("badgenumber", count);
            context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher" +
                    ".settings/badge/"), "change_badge", null, bundle);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

文档中心https://developer.huawei.com/consumer/cn/doc/30802

四、三星手机角标实现代码,三星手机发送一个notification后(或者已经有未读notification)和应用关闭的情况在角标才有效,这点跟华为不一样。

    private static boolean setSamsungBadge(int count, Context context) {
        try {
            String launcherClassName = getLauncherClassName(context);
            if (TextUtils.isEmpty(launcherClassName)) {
                return false;
            }
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", count);
            intent.putExtra("badge_count_package_name", context.getPackageName());
            intent.putExtra("badge_count_class_name", launcherClassName);
            context.sendBroadcast(intent);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

五、源码实例测试

1、MainActivity.java

package com.giada.myapplication;


import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;

import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.NotificationCompat;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * 为应用添加角标,提示用户有新的未读消息
 */
public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private static int badgeCount = 100; //角标数量
    NotificationManager notificationManager;
    public static int notificationId  = 1;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        findViewById(R.id.badge_count_reduce_btn).setOnClickListener(this);
        findViewById(R.id.badge_count_add_btn).setOnClickListener(this);
        //设置角标数量
        BadgeUtils.setBadgeCount(this,100);
    }

    private static String getLauncherClassName(Context context) {
        ComponentName launchComponent = getLauncherComponentName(context);
        if (launchComponent == null) {
            return "";
        } else {
            return launchComponent.getClassName();
        }
    }

    private static ComponentName getLauncherComponentName(Context context) {
        Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(context
                .getPackageName());
        if (launchIntent != null) {
            return launchIntent.getComponent();
        } else {
            return null;
        }
    }
    private static boolean setHuaweiBadge(int count, Context context) {
        try {
            String launchClassName = getLauncherClassName(context);
            if (TextUtils.isEmpty(launchClassName)) {
                return false;
            }
            Bundle bundle = new Bundle();
            bundle.putString("package", context.getPackageName());
            bundle.putString("class", launchClassName);
            bundle.putInt("badgenumber", count);
            context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher" +
                    ".settings/badge/"), "change_badge", null, bundle);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    public static boolean setNotificationBadge(int count, Context context) {
        NotificationManager notificationManager = (NotificationManager) context.getSystemService
                (Context.NOTIFICATION_SERVICE);
        if (notificationManager == null) {
            return false;
        }
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            // 8.0之后添加角标需要NotificationChannel
            NotificationChannel channel = new NotificationChannel("badge", "badge",
                    NotificationManager.IMPORTANCE_DEFAULT);
            channel.setShowBadge(true);
            notificationManager.createNotificationChannel(channel);
        }
        Intent intent = new Intent(context, MainActivity.class);
        PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
        Notification notification = new NotificationCompat.Builder(context, "badge")
                .setContentTitle("应用角标")
                .setContentText("您有" + count + "条未读消息")
                .setLargeIcon(BitmapFactory.decodeResource(context.getResources(), R.mipmap
                        .ic_launcher))
                .setSmallIcon(R.mipmap.ic_launcher_round)
                .setAutoCancel(true)
                .setContentIntent(pendingIntent)
                .setChannelId("badge")
                .setNumber(count)
                .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL).build();
        // 小米
        try {
            Field field = notification.getClass().getDeclaredField("extraNotification");
            Object extraNotification = field.get(notification);
            Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int
                    .class);
            method.invoke(extraNotification, count);
        } catch (Exception e) {
            e.printStackTrace();
        }
        notificationManager.notify(notificationId++, notification);
        return true;
    }
    private static boolean setSamsungBadge(int count, Context context) {
        try {
            String launcherClassName = getLauncherClassName(context);
            if (TextUtils.isEmpty(launcherClassName)) {
                return false;
            }
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", count);
            intent.putExtra("badge_count_package_name", context.getPackageName());
            intent.putExtra("badge_count_class_name", launcherClassName);
            context.sendBroadcast(intent);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }
    @Override
    public void onClick(View v) {
        switch (v.getId()){
            case R.id.badge_count_reduce_btn:
                //Android原生方式 角标数量减1
               // BadgeUtils.setBadgeCount(this,--badgeCount);
                if (Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) {
                    setHuaweiBadge(--badgeCount, this);
                } else if (Build.MANUFACTURER.equalsIgnoreCase("Samsung")) {
                    setSamsungBadge(--badgeCount, this);
                    setNotificationBadge(badgeCount,this);
                    finish();
                }else {
                    setSamsungBadge(--badgeCount, this);
                    setNotificationBadge(badgeCount,this);
                    finish();
                }
                break;
            case R.id.badge_count_add_btn:

                if (Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) {
                    setHuaweiBadge(++badgeCount, this);
                } else if (Build.MANUFACTURER.equalsIgnoreCase("Samsung")) {
                    setSamsungBadge(++badgeCount, this);
                    setNotificationBadge(badgeCount,this);
                    finish();
                }else{
                    setSamsungBadge(++badgeCount, this);
                    setNotificationBadge(badgeCount,this);
                    finish();
                }

                break;

        }
    }
}

2、布局文件app\src\main\res\layout\activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:orientation="vertical"
    android:gravity="center"
    tools:context="com.giada.myapplication.MainActivity">

    <!--角标数量减1-->
    <Button
        android:id="@+id/badge_count_reduce_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="角标数量减1"
        android:layout_marginTop="10dp"/>

    <!--角标数量加1-->
    <Button
        android:id="@+id/badge_count_add_btn"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="角标数量加1"
        android:layout_marginTop="50dp"/>


</LinearLayout>

3、测试界面

 六、三星手机和华为手机测试效果

 

七、最有价值的参考文章

Android开发:史上最全Android应用角标适配方法 - 简书

有关 Android 应用桌面角标 (BadgeNumber) 实现的探讨 - 灰信网(软件开发博客聚合)

文档中心

八、其他参考文章

https://www.jb51.net/article/111315.htm

https://www.jb51.net/article/119787.htm

Android系统 应用图标显示未读消息数(BadgeNumber) 桌面app图标的角标显示_llixiangjian的博客-CSDN博客_android 显示未读消息数

android之在app图标添加角标,Android之在app图标添加角标_暧昧散尽的博客-CSDN博客

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
下载包包含以下软件或ROM: 华为光猫ONT使能维修工具773-华为ONT组播版本配置工具773 ,支持市面最新V5版本,支持列表有显示都50多项华为ONT设备,需要的速度,多谢支持。包括最新版.HS8145V5等一系列产品。不可多得产品。 开启telnet的方法网上看到有2种: 第一种是备份配置文件 通过改备份文件再恢复来开通telnet。这种的前提是你有超级管理员账号和密码。 第二种是使用华为的ONT组播版本配置工具来开启。 我使用的是第二种方法。下面开始吧。 第一步:打开电脑的telnet服务。设置电脑IP。 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 设置电脑IP:192.168.1.xx 网关设置成:192.168.1.1 第二步: 光猫通电,等待约2分钟完全启动完毕。网线连接电脑(确保电脑只有这个光猫一个联网设备,网线务必插在光猫的悦me口也就是LAN1口) 打开命令提示符:ping 192.168.1.1 ping通了说明设置正确。 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 接下来打开工具包里的“华为光猫破解工具V300R13C10SPC800” 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 点击“启动”,开始观察桌面右下角的网络连接标识,当网络断开时,点击“停止”,关闭软件。 正常情况下已经开启telnet了。 第三步:打开命令提示符,输入telnet 192.168.1.1 用户名:root,密码:admin(键盘上按就行了不会显示的) 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 登录后 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 第四步:进su改模,命令:set upport mode 1(GPON); set upport mode 2(EPON) ; set upport mode 4(双模)华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 出现:success!就成功了。 第五步:拔电重启光猫后进shell恢复华为界面,命令:restorehwmode.sh 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 华为SA1456光猫开启telnet 改双模 详细过程 适合新手参考 出现:success!就成功了。拔电重启光猫。大功告成 恢复华为界面后,电脑IP要改成:192.168.100.xx 网关:192.168.100.1 光猫登录地址:192.168.100.1 用户名:telecomadmin 密码:admintelecom Yanzi52351
华为手机上,可以通过 BadgeProvider 提供的 API 来设置应用角标数。具体实现方法如下: 1. 首先,需要在 AndroidManifest.xml 文件中注册一个广播接收器,用于接收设置应用角标数的请求。代码如下: ```xml <receiver android:name=".BadgeReceiver" android:enabled="true" android:exported="true"> <intent-filter> <action android:name="android.intent.action.BADGE_COUNT_UPDATE" /> <action android:name="android.intent.action.PACKAGE_REPLACED" /> <data android:scheme="package" /> </intent-filter> </receiver> ``` 2. 在 BadgeReceiver 中处理接收到的设置应用角标数的请求。代码如下: ```java public class BadgeReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (intent.getAction() != null) { switch (intent.getAction()) { case "android.intent.action.BADGE_COUNT_UPDATE": // 获取应用的包名和角标数 String packageName = intent.getStringExtra("badge_package_name"); int badgeCount = intent.getIntExtra("badge_count", 0); // 设置应用角标数 setBadgeCount(context, packageName, badgeCount); break; case "android.intent.action.PACKAGE_REPLACED": // 应用更新后需要重新设置角标数 setBadgeCount(context, context.getPackageName(), 0); break; } } } /** * 设置应用角标数 */ private void setBadgeCount(Context context, String packageName, int badgeCount) { try { Bundle extras = new Bundle(); extras.putString("package", packageName); extras.putString("class", getLauncherClassName(context)); extras.putInt("badgenumber", badgeCount); context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, extras); } catch (Exception e) { e.printStackTrace(); } } /** * 获取应用的启动 Activity 的类名 */ private String getLauncherClassName(Context context) { PackageManager pm = context.getPackageManager(); Intent intent = new Intent(Intent.ACTION_MAIN); intent.addCategory(Intent.CATEGORY_LAUNCHER); intent.setPackage(context.getPackageName()); List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0); if (resolveInfos != null && resolveInfos.size() > 0) { return resolveInfos.get(0).activityInfo.name; } return ""; } } ``` 3. 在应用中设置角标数时,可以通过 Intent 来发送广播请求。代码如下: ```java int badgeCount = 10; Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); intent.putExtra("badge_package_name", getPackageName()); intent.putExtra("badge_count", badgeCount); sendBroadcast(intent); ``` 需要注意的是,华为手机上的角标数设置功能只在 EMUI 4.1 及以上版本上支持。如果您的应用需要在其他手机上设置角标数,可以使用第三方库 ShortcutBadger。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值