Android Icon数字角标(BadgeNumber)的实现方式

本文介绍了一种在Android系统的小米、三星和索尼手机上实现桌面应用图标数字提醒的方法。通过利用各ROM厂商提供的私有API,文章给出了具体的代码示例,包括如何根据不同设备制造商调用相应的API来更新图标上的数字。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

http://blog.youkuaiyun.com/janice0529/article/details/44344169

Android系统 小米,三星,索尼手机发送桌面快键提醒数字图标,在Android系统中,众所周知不支持BadgeNumber,虽然第三方控件BadgeView可以实现应用内的数字提醒,但对于系统的图标,特别是app的logo图标很难实现数字标志,即使是绘图的方式不断修改,但这种方式天生弊端,实用性很差。但幸运的是,某些ROM厂商提供了私有的API,但也带来了难度,API的不同意意味着代码量的增加和兼容性问题更加突出。

我们现在来实现桌面logo或者说icon右上角的图标,先来看2张图,第一张来自互联网,第二张来自个人实践!(由于实验条件有限,只能测试小米的(⊙o⊙)…,有兴趣的同学测试一下其他的吧)

互联网图片    个人手机接入

好了,上代码

public class MainActivity extends Activity {
      //必须使用,Activity启动页
      private final static String lancherActivityClassName = Welcome.class.getName();
      
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.common_listview_layout);
	}

	@Override
	protected void onResume() {
		super.onResume();
		sendBadgeNumber();
	}

	private void sendBadgeNumber() {
		String number = "35";
		if (TextUtils.isEmpty(number)) {
			number = "0";
		} else {
			int numInt = Integer.valueOf(number);
			number = String.valueOf(Math.max(0, Math.min(numInt, 99)));
		}

		if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
			sendToXiaoMi(number);
		} else if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) {
			sendToSony(number);
		} else if (Build.MANUFACTURER.toLowerCase().contains("sony")) {
			sendToSamsumg(number);
		} else {
			Toast.makeText(this, "Not Support", Toast.LENGTH_LONG).show();
		}
	}

	private void sendToXiaoMi(String number) {
		NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
		Notification notification = null;
		boolean isMiUIV6 = true;
		try {
			NotificationCompat.Builder builder = new NotificationCompat.Builder(this); 
			builder.setContentTitle("您有"+number+"未读消息");
			builder.setTicker("您有"+number+"未读消息");
			builder.setAutoCancel(true);
			builder.setSmallIcon(R.drawable.common_icon_lamp_light_red);
			builder.setDefaults(Notification.DEFAULT_LIGHTS);
			notification = builder.build(); 
			Class miuiNotificationClass = Class.forName("android.app.MiuiNotification");
			Object miuiNotification = miuiNotificationClass.newInstance();
			Field field = miuiNotification.getClass().getDeclaredField("messageCount");
			field.setAccessible(true);
			field.set(miuiNotification, number);// 设置信息数
			field = notification.getClass().getField("extraNotification"); 
			field.setAccessible(true);
        field.set(notification, miuiNotification);  
        Toast.makeText(this, "Xiaomi=>isSendOk=>1", Toast.LENGTH_LONG).show();
		}catch (Exception e) {
		    e.printStackTrace();
		    //miui 6之前的版本
		    isMiUIV6 = false;
    		    Intent localIntent = new Intent("android.intent.action.APPLICATION_MESSAGE_UPDATE");
    		    localIntent.putExtra("android.intent.extra.update_application_component_name",getPackageName() + "/"+ lancherActivityClassName );
    		    localIntent.putExtra("android.intent.extra.update_application_message_text",number);
    		    sendBroadcast(localIntent);
		}
		finally
		{
          if(notification!=null && isMiUIV6 )
		   {
		       //miui6以上版本需要使用通知发送
			nm.notify(101010, notification); 
		   }
		}

	}

	private void sendToSony(String number) {
		boolean isShow = true;
		if ("0".equals(number)) {
			isShow = false;
		}
		Intent localIntent = new Intent();
		localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE",isShow);//是否显示
		localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
		localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME",lancherActivityClassName );//启动页
		localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", number);//数字
		localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME",getPackageName());//包名
		sendBroadcast(localIntent);

		Toast.makeText(this, "Sony," + "isSendOk", Toast.LENGTH_LONG).show();
	}

	private void sendToSamsumg(String number) 
	{
		Intent localIntent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
		localIntent.putExtra("badge_count", number);//数字
		localIntent.putExtra("badge_count_package_name", getPackageName());//包名
		localIntent.putExtra("badge_count_class_name",lancherActivityClassName ); //启动页
		sendBroadcast(localIntent);
		Toast.makeText(this, "Samsumg," + "isSendOk", Toast.LENGTH_LONG).show();
	}
}

注意lancherActivityClassName 必须被配置为 启动页   android.intent.category.LAUNCHER

 <activity
            android:name="com.sample.activites.Welcome"
            android:configChanges="locale|keyboard|screenSize"
            android:label="@string/app_name"
            android:screenOrientation="portrait" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <intent-filter>
                <action android:name="android.intent.action.CREATE_SHORTCUT" />
            </intent-filter>
        </activity>

转载于:https://www.cnblogs.com/taoboy/p/5597155.html

### Android 数字实现方法 在 Android 开发中,数字是一种常见的 UI 需求,用于提示用户某些事件的发生次数或者未读消息的数量。以下是几种常用的实现方式: #### 方法一:通过 `BadgeView` 库实现 可以借助第三方库来快速实现数字功能。例如,GitHub 上有一个名为 `BadgeView` 的开源项目[^2],它提供了简单易用的 API 来创建和管理。 ```java // 初始化 BadgeView 并绑定到目 View BadgeView badge = new QBadgeView(context); badge.bindTarget(targetView).setBadgeNumber(99); // 设置数值 ``` 需要注意的是,在使用此类库时可能会遇到与其他组件(如 `FloatingActionButton`)交互冲突的情况。如果发生这种情况,建议深入研究其源码并调整实现逻辑以适应具体需求。 #### 方法二:自定义 TabLayout 中的 TextView 添加 当需要在 `TabLayout` 中展示带有数字的小红点时,可以通过自定义布局完成此操作。下面是一个例子说明如何修改默认签项的内容结构以便支持动态更新通知数目[^1]: ```xml <!-- 定义一个新的 tab_item.xml 文件 --> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:gravity="center_horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/tab_label" android:textSize="14sp" android:paddingBottom="8dp" android:layout_gravity="bottom|start" android:layout_width="wrap_content" android:layout_height="wrap_content"/> <!-- 小圆圈作为提醒志 --> <TextView android:id="@+id/badge_count" android:background="#FF0000" android:textColor="#FFFFFF" android:visibility="gone" android:minWidth="16dp" android:minHeight="16dp" android:gravity="center" android:paddingLeft="4dp" android:paddingRight="4dp" android:layout_marginTop="-7dp" android:layout_width="wrap_content" android:layout_height="wrap_content"/> </LinearLayout> ``` 接着可以在 Java/Kotlin 代码里加载这些视图元素,并根据业务场景控制它们的状态变化: ```java for (int i=0;i<tabCount;i++) { final LinearLayout layout = LayoutInflater.from(this).inflate(R.layout.tab_item, null); ((TextView)layout.findViewById(R.id.badge_count)).setText(String.valueOf(i)); ((TextView)layout.findViewById(R.id.badge_count)).setVisibility(View.VISIBLE); tabs.getTabAt(i).setCustomView(layout); } ``` 这种方法虽然稍微复杂一点,但它完全由开发者掌控每一个细节部分,灵活性更高[^1]。 #### 方法三:利用系统级桌面图记机制 对于希望影响整个设备主屏幕上的快捷方式外观而言,则需调用特定厂商扩展接口来进行全局性的更改处理[^3]。比如针对华为手机平台来说存在如下函数原型可供参考: ```java Intent intent = new Intent("com.huawei.intent.action.BADGE"); intent.setComponent(new ComponentName("com.huawei.systemmanager", "com.huawei.notificationmanager.service.BadgeService")); intent.putExtra("package", getPackageName()); intent.putExtra("class", MainActivity.class.getName()); intent.putExtra("badgenumber", count); sendBroadcast(intent); ``` 不过值得注意的是不同品牌之间可能采用完全不同甚至互不兼容的技术方案去达成相似目的效果,所以在跨机型部署之前务必做好充分测试验证工作[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值