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

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

 

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

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

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

    

好了,上代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
<code class = "hljs java" ><span class = "hljs-keyword" > public  <span class = "hljs-class" ><span class = "hljs-keyword" > class  <span class = "hljs-title" >MainActivity <span class = "hljs-keyword" > extends  <span class = "hljs-title" >Activity {
       <span class = "hljs-comment" > //必须使用,Activity启动页
       <span class = "hljs-keyword" > private  <span class = "hljs-keyword" > final  <span class = "hljs-keyword" > static  String lancherActivityClassName = Welcome. class .getName();
       
     <span class = "hljs-meta" > @Override
     <span class = "hljs-function" ><span class = "hljs-keyword" > protected  <span class = "hljs-keyword" > void  <span class = "hljs-title" >onCreate<span class = "hljs-params" >(Bundle savedInstanceState) {
         <span class = "hljs-keyword" > super .onCreate(savedInstanceState);
         setContentView(R.layout.common_listview_layout);
     }
 
     <span class = "hljs-meta" > @Override
     <span class = "hljs-function" ><span class = "hljs-keyword" > protected  <span class = "hljs-keyword" > void  <span class = "hljs-title" >onResume<span class = "hljs-params" >() {
         <span class = "hljs-keyword" > super .onResume();
         sendBadgeNumber();
     }
 
     <span class = "hljs-function" ><span class = "hljs-keyword" > private  <span class = "hljs-keyword" > void  <span class = "hljs-title" >sendBadgeNumber<span class = "hljs-params" >() {
         String number = <span class = "hljs-string" > "35" ;
         <span class = "hljs-keyword" > if  (TextUtils.isEmpty(number)) {
             number = <span class = "hljs-string" > "0" ;
         } <span class = "hljs-keyword" > else  {
             <span class = "hljs-keyword" > int  numInt = Integer.valueOf(number);
             number = String.valueOf(Math.max(<span class = "hljs-number" > 0 , Math.min(numInt, <span class = "hljs-number" > 99 )));
         }
 
         <span class = "hljs-keyword" > if  (Build.MANUFACTURER.equalsIgnoreCase(<span class = "hljs-string" > "Xiaomi" )) {
             sendToXiaoMi(number);
         } <span class = "hljs-keyword" > else  <span class = "hljs-keyword" > if  (Build.MANUFACTURER.equalsIgnoreCase(<span class = "hljs-string" > "samsung" )) {
             sendToSony(number);
         } <span class = "hljs-keyword" > else  <span class = "hljs-keyword" > if  (Build.MANUFACTURER.toLowerCase().contains(<span class = "hljs-string" > "sony" )) {
             sendToSamsumg(number);
         } <span class = "hljs-keyword" > else  {
             Toast.makeText(<span class = "hljs-keyword" > this , <span class = "hljs-string" > "Not Support" , Toast.LENGTH_LONG).show();
         }
     }
 
     <span class = "hljs-function" ><span class = "hljs-keyword" > private  <span class = "hljs-keyword" > void  <span class = "hljs-title" >sendToXiaoMi<span class = "hljs-params" >(String number) {
         NotificationManager nm = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
         Notification notification = <span class = "hljs-keyword" > null ;
         <span class = "hljs-keyword" > boolean  isMiUIV6 = <span class = "hljs-keyword" > true ;
         <span class = "hljs-keyword" > try  {
             NotificationCompat.Builder builder = <span class = "hljs-keyword" > new  NotificationCompat.Builder(<span class = "hljs-keyword" > this ); 
             builder.setContentTitle(<span class = "hljs-string" > "您有" +number+<span class = "hljs-string" > "未读消息" );
             builder.setTicker(<span class = "hljs-string" > "您有" +number+<span class = "hljs-string" > "未读消息" );
             builder.setAutoCancel(<span class = "hljs-keyword" > true );
             builder.setSmallIcon(R.drawable.common_icon_lamp_light_red);
             builder.setDefaults(Notification.DEFAULT_LIGHTS);
             notification = builder.build(); 
             Class miuiNotificationClass = Class.forName(<span class = "hljs-string" > "android.app.MiuiNotification" );
             Object miuiNotification = miuiNotificationClass.newInstance();
             Field field = miuiNotification.getClass().getDeclaredField(<span class = "hljs-string" > "messageCount" );
             field.setAccessible(<span class = "hljs-keyword" > true );
             field.set(miuiNotification, number);<span class = "hljs-comment" > // 设置信息数
             field = notification.getClass().getField(<span class = "hljs-string" > "extraNotification" ); 
             field.setAccessible(<span class = "hljs-keyword" > true );
         field.set(notification, miuiNotification);  
         Toast.makeText(<span class = "hljs-keyword" > this , <span class = "hljs-string" > "Xiaomi=>isSendOk=>1" , Toast.LENGTH_LONG).show();
         }<span class = "hljs-keyword" > catch  (Exception e) {
             e.printStackTrace();
             <span class = "hljs-comment" > //miui 6之前的版本
             isMiUIV6 = <span class = "hljs-keyword" > false ;
                 Intent localIntent = <span class = "hljs-keyword" > new  Intent(<span class = "hljs-string" > "android.intent.action.APPLICATION_MESSAGE_UPDATE" );
                 localIntent.putExtra(<span class = "hljs-string" > "android.intent.extra.update_application_component_name" ,getPackageName() + <span class = "hljs-string" > "/" + lancherActivityClassName );
                 localIntent.putExtra(<span class = "hljs-string" > "android.intent.extra.update_application_message_text" ,number);
                 sendBroadcast(localIntent);
         }
         <span class = "hljs-keyword" > finally
         {
           <span class = "hljs-keyword" > if (notification!=<span class = "hljs-keyword" > null  && isMiUIV6 )
            {
                <span class = "hljs-comment" > //miui6以上版本需要使用通知发送
             nm.notify(<span class = "hljs-number" > 101010 , notification); 
            }
         }
 
     }
 
     <span class = "hljs-function" ><span class = "hljs-keyword" > private  <span class = "hljs-keyword" > void  <span class = "hljs-title" >sendToSony<span class = "hljs-params" >(String number) {
         <span class = "hljs-keyword" > boolean  isShow = <span class = "hljs-keyword" > true ;
         <span class = "hljs-keyword" > if  (<span class = "hljs-string" > "0" .equals(number)) {
             isShow = <span class = "hljs-keyword" > false ;
         }
         Intent localIntent = <span class = "hljs-keyword" > new  Intent();
         localIntent.putExtra(<span class = "hljs-string" > "com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE" ,isShow);<span class = "hljs-comment" > //是否显示
         localIntent.setAction(<span class = "hljs-string" > "com.sonyericsson.home.action.UPDATE_BADGE" );
         localIntent.putExtra(<span class = "hljs-string" > "com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME" ,lancherActivityClassName );<span class = "hljs-comment" > //启动页
         localIntent.putExtra(<span class = "hljs-string" > "com.sonyericsson.home.intent.extra.badge.MESSAGE" , number);<span class = "hljs-comment" > //数字
         localIntent.putExtra(<span class = "hljs-string" > "com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME" ,getPackageName());<span class = "hljs-comment" > //包名
         sendBroadcast(localIntent);
 
         Toast.makeText(<span class = "hljs-keyword" > this , <span class = "hljs-string" > "Sony,"  + <span class = "hljs-string" > "isSendOk" , Toast.LENGTH_LONG).show();
     }
 
     <span class = "hljs-function" ><span class = "hljs-keyword" > private  <span class = "hljs-keyword" > void  <span class = "hljs-title" >sendToSamsumg<span class = "hljs-params" >(String number) 
     {
         Intent localIntent = <span class = "hljs-keyword" > new  Intent(<span class = "hljs-string" > "android.intent.action.BADGE_COUNT_UPDATE" );
         localIntent.putExtra(<span class = "hljs-string" > "badge_count" , number);<span class = "hljs-comment" > //数字
         localIntent.putExtra(<span class = "hljs-string" > "badge_count_package_name" , getPackageName());<span class = "hljs-comment" > //包名
         localIntent.putExtra(<span class = "hljs-string" > "badge_count_class_name" ,lancherActivityClassName ); <span class = "hljs-comment" > //启动页
         sendBroadcast(localIntent);
         Toast.makeText(<span class = "hljs-keyword" > this , <span class = "hljs-string" > "Samsumg,"  + <span class = "hljs-string" > "isSendOk" , Toast.LENGTH_LONG).show();
     }
}</span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<code class = "hljs xml" > <span class = "hljs-tag" ><<span class = "hljs-name" >activity
             <span class = "hljs-attr" >android:name=<span class = "hljs-string" > "com.sample.activites.Welcome"
             <span class = "hljs-attr" >android:configChanges=<span class = "hljs-string" > "locale|keyboard|screenSize"
             <span class = "hljs-attr" >android:label=<span class = "hljs-string" > "@string/app_name"
             <span class = "hljs-attr" >android:screenOrientation=<span class = "hljs-string" > "portrait"  >
             <span class = "hljs-tag" ><<span class = "hljs-name" >intent-filter>
                 <span class = "hljs-tag" ><<span class = "hljs-name" >action <span class = "hljs-attr" >android:name=<span class = "hljs-string" > "android.intent.action.MAIN"  />
 
                 <span class = "hljs-tag" ><<span class = "hljs-name" >category <span class = "hljs-attr" >android:name=<span class = "hljs-string" > "android.intent.category.LAUNCHER"  />
             <span class = "hljs-tag" ></<span class = "hljs-name" >intent-filter>
             <span class = "hljs-tag" ><<span class = "hljs-name" >intent-filter>
                 <span class = "hljs-tag" ><<span class = "hljs-name" >action <span class = "hljs-attr" >android:name=<span class = "hljs-string" > "android.intent.action.CREATE_SHORTCUT"  />
             <span class = "hljs-tag" ></<span class = "hljs-name" >intent-filter>
         <span class = "hljs-tag" ></<span class = "hljs-name" >activity></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></span></code>

相互学习,共同进步!

联系方式:240803830

主页:http://www.cnblogs.com/taoboy/

<think>好的,用户想了解小米手机在Android系统上的桌面适配问题。首先,我得明确什么是桌面,也就是应用图上显示的通知数量的小红点或数字。这个问题可能涉及不同Android版本的适配,特别是MIUI的定制带来的差异。 接下来,我需要回忆一下Android原生的机制。通常,Android使用NotificationListenerService来管理通知,应用可以通过发送带有数字的Notification来触发显示。但MIUI作为深度定制的系统,可能有自己的实现方式,比如需要特殊权限或者特定的Intent。 然后,用户可能遇到的问题是,他们的应用在小米手机上无法正确显示,或者显示不一致。这可能是因为MIUI限制了后台启动Activity,或者需要用户手动授权应用发送通知的权限。此外,不同MIUI版本可能有不同的处理方式,导致适配困难。 还需要考虑小米的API是否有文档支持,或者是否有隐藏的Intent可以用来触发。比如,有些厂商会提供特定的广播Action,发送这些广播可以更新。例如,发送一个特定的Intent,包含包名和数字,可能可以更新。 另外,用户可能需要检查应用的通知渠道设置是否正确,因为MIUI可能会将某些通知渠道默认静音,导致不显示。还有应用是否被省电策略限制,需要在后台运行权限里允许应用自启动和相关权限。 可能还需要查阅小米的开放平台文档,或者开发者论坛,看看有没有官方推荐的适配方法。如果没有,可能需要通过反射或者其他Hack方式实现,但这样可能存在兼容性问题,尤其是MIUI版本更新后可能失效。 总结下来,适配小米的桌面需要注意以下几点:检查通知权限是否开启,使用正确的Notification构造方法,处理MIUI的后台限制,可能需要发送特定的广播或使用小米提供的SDK,以及测试不同MIUI版本的兼容性。</think>在Android开发中,适配小米手机桌面(应用图未读消息数)需要注意以下关键点: **一、MIUI特性差异** 1. MIUI系统存在特殊权限控制: - 需用户手动开启`显示悬浮窗`权限(路径:设置→应用设置→权限管理→悬浮窗) - 需开启`自启动`权限避免进程被清理 **二、原生适配方案** ```java // 准Notification构建方式 NotificationCompat.Builder builder = new NotificationCompat.Builder(context, CHANNEL_ID) .setContentTitle("新消息") .setContentText("您有未读消息") .setNumber(5) // 关键数值设置 .setSmallIcon(R.drawable.ic_notification); ``` **三、MIUI专属适配策略** 1. 反射调用系统服务(兼容旧版本MIUI): ```java try { Bundle extras = new Bundle(); extras.putString("package", context.getPackageName()); extras.putString("class", launcherClassName); extras.putInt("badgenumber", count); context.getContentResolver().call( Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extras); } catch (Exception e) { // 处理兼容性异常 } ``` 2. 广播方式(推荐新版本): ```java Intent intent = new Intent("android.intent.action.APPLICATION_MESSAGE_UPDATE"); intent.putExtra("android.intent.extra.update_application_component_name", context.getPackageName() + "/" + launcherClassName); intent.putExtra("android.intent.extra.update_application_message_text", count); context.sendBroadcast(intent); ``` **四、注意事项** 1. 动态获取启动类: ```java // 获取默认启动Activity Intent launchIntent = context.getPackageManager().getLaunchIntentForPackage(packageName); String className = launchIntent.getComponent().getClassName(); ``` 2. 版本兼容检测: ```java if (Build.MANUFACTURER.equalsIgnoreCase("xiaomi")) { // 执行MIUI专属适配逻辑 handleMiuiBadge(count); } else if (...) { // 其他厂商适配 } ``` 3. 需在清单文件声明权限: ```xml <uses-permission android:name="com.xiaomi.permission.UPDATE_APP_ICON"/> ``` **五、常见问题排查** 1. 不生效时检查: - 是否开启`通知管理`权限 - 是否开启`悬浮窗`权限 - 是否被系统电池优化限制 - 应用是否被强制停止 2. 桌面兼容问题: - 不同MIUI版本(如MIUI12/13)实现差异 - 不同桌面主题可能覆盖样式 - 第三方桌面应用(如Nova Launcher)的特殊处理 建议在实际开发中结合小米开放平台最新文档,并测试覆盖主流机型(Redmi K系列、Note系列等)。可通过`Build.VERSION.INCREMENTAL`字段获取具体MIUI版本号进行精准适配。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值