版權聲明:本文為HaiyuKing原創文章,轉載請注明出處!
概述
本文主要使用的開源庫是 leolin310148/ShortcutBadger,但是在其基礎上做了一些修改。
什么是應用角標?
1、角標,英文名badge,即桌面上顯示未讀消息的小數字,原ios功能,Android原生並沒有該功能。(原生的Android系統,是不支持應用角標的)
應用角標最開始是在ios系統中出現的,大概長這樣:
不知道從什么時候開始,國內各大安卓手機系統上,也慢慢出現了應用角標的身影,到現在幾乎成為了安卓系統的標配。
2、目前被大部分android廠商所支持,但都是廠商自己支持,所以要考慮不同品牌的兼容問題。
3、應用角標是一個帶有爭議的設計,有些強迫症用戶對應用角標咬牙切齒,有些用戶看不到應用角標又渾身癢癢。
如何支持應用角標?
1、安卓應用的角標是由Launcher支持的,而原生的Android系統Launcher並沒有提供角標支持,所以各大手機廠商只能自己定制Launcher來實現,然后提供接口給外部使用。
2、主流的做法都是通過廣播Intent的形式來提供接口,不同的手機系統所支持的廣播Intent也不太一樣,所以需要針對不同的手機系統來做適配(恭喜你又成功跳入一個系統適配的坑!)。
3、添加角標的原理就是發送一個Broadcast(廣播),在廣播的Intent中指定需要被添加角標的應用的packageName(包名),className(類名),count(角標數目)。當然了,不同廠商的手機的角標操作的Intent的action是不一樣的。
4、這里需要注意的是,是否支持角標並不與手機廠商有關,而是你當前使用的launcher開發廠商有關。
比如:你用着華為手機,卻用着魅族的launcher,那肯定是不會成功的顯示出桌面角標的;
相反的,你用着某一款手機卻用着華為的launcher,一樣可以顯示出桌面圖標角標。
角標實現方案
方案:使用開源庫leolin310148/ShortcutBadger,然后對比主流機型上的代碼是否官網最新代碼,更新到最新代碼
將開源庫leolin310148/ShortcutBadger的代碼下載下來,作為一個module添加到項目中;然后根據需要修改下面的類文件。
主流機型適配介紹
華為
參考:
小米
oppo
oppo角標提醒目前只針對內部軟件還有微信、QQ開放,其他的暫時無法提供。
OPPO,R9后台的通知設置里,有顯示角標的選項,事實上該選項並不是對所有app開放的,就微信、QQ等國民應用有打開該選項的權限,目測是OPPO做了白名單限制,對這些機型也沒有辦法。
vivo
官網上沒有說明。
網上的實現方案:參考leolin310148/ShortcutBadger中的VivoHomeBadger.java類。
/** * @author leolin */ public class VivoHomeBadger implements Badger { @Override public void executeBadge(Context context, ComponentName componentName, int badgeCount) throws ShortcutBadgeException { Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM"); intent.putExtra("packageName", context.getPackageName()); intent.putExtra("className", componentName.getClassName()); intent.putExtra("notificationNum", badgeCount); context.sendBroadcast(intent); } @Override public List<String> getSupportLaunchers() { return Arrays.asList("com.vivo.launcher"); } }
集成ShortcutBadger
1、新建module
注意:包名建議跟第三方庫的包名一致。
新建的空的module如下:
2、將下面的文件復制到shortcutbadge這個module中
將從第三方庫中下面的文件復制到module中。
效果如下:
3、在這個module的AndroidManifest.xml文件中添加以下代碼
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="me.leolin.shortcutbadger"> <!--for android--> <!--<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>--> <!--<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS"/>--> <!--<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />--> <!--<uses-permission android:name="com.android.launcher.permission.UNINSTALL_SHORTCUT" />--> <!--for Samsung--> <uses-permission android:name="com.sec.android.provider.badge.permission.READ"/> <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/> <!--for htc--> <uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/> <uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/> <!--for sony--> <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/> <uses-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE"/> <!--for apex--> <uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/> <!--for solid--> <uses-permission android:name="com.majeur.launcher.permission.UPDATE_BADGE"/> <!--for huawei--> <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE"/> <uses-permission android:name="com.huawei.android.launcher.permission.READ_SETTINGS"/> <uses-permission android:name="com.huawei.android.launcher.permission.WRITE_SETTINGS"/> <!--for ZUK--> <uses-permission android:name="android.permission.READ_APP_BADGE"/> <!--for OPPO--> <uses-permission android:name="com.oppo.launcher.permission.READ_SETTINGS"/> <uses-permission android:name="com.oppo.launcher.permission.WRITE_SETTINGS"/> <!--for EvMe--> <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_READ"/> <uses-permission android:name="me.everything.badger.permission.BADGE_COUNT_WRITE"/> </manifest>
4、在這個module的proguard-rules.pro文件中添加以下代碼,進行代碼混淆
#https://github.com/leolin310148/ShortcutBadger/issues/46 -keep class me.leolin.shortcutbadger.impl.** { <init>(...); }
5、在這個module的build.gradle中修改minifyEnabled的值為true【用於代碼混淆】
apply plugin: 'com.android.library'
android {
compileSdkVersion rootProject.ext.globalCompileSdkVersion
defaultConfig {
minSdkVersion rootProject.ext.globalMinSdkVersion
targetSdkVersion rootProject.ext.globalTargetSdkVersion
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
6、在APP的build.gradle中引用shortcutbadger這個module
apply plugin: 'com.android.application'
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.why.project.shortcutbadgerdemo"
minSdkVersion 16
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
//引用shortcutbadger implementation project(':shortcutbadger')
}
7、至此可以使用了,不過如果想要實現小米設備上的角標功能,需要在shortcutbadger這個module中添加以下文件
其中badger_notification_icon.png文件是背景透明,前景圖標的48X48的圖標(demo中借用的是極光推送的圖標):
然后在APP的module的AndroidManifest.xml文件中<application節點下注冊服務
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.why.project.shortcutbadgerdemo"> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> <!--注冊小米設備的角標服務【應用角標功能相關】【不建議在小米設備上使用,因為小米上只要打開APP,角標就會消失,目前項目中用不到】--> <service android:name="me.leolin.shortcutbadger.BadgeIntentService" android:exported="false"></service> </application> </manifest>
8、使用
package com.why.project.shortcutbadgerdemo; import android.content.Context; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.widget.Toast; import me.leolin.shortcutbadger.ShortcutBadgeException; import me.leolin.shortcutbadger.ShortcutBadger; public class MainActivity extends AppCompatActivity { private Context mContext; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mContext = this; //一般設備上的顯示角標的代碼--可以結合RomUtil進行機型判斷 try { ShortcutBadger.applyCountOrThrow(mContext, 9); } catch (ShortcutBadgeException e) { e.printStackTrace(); //如果還沒有提示過toast,則進行提示 Toast.makeText(mContext,"本APP暫時無法在該設備上實現應用角標功能",Toast.LENGTH_SHORT).show(); } //下面是小米設備上的顯示角標的關鍵代碼--可以結合RomUtil進行機型判斷 /*finish();//在小米設備上APP打開着的情況下,是不顯示角標的,只有APP關閉了才會顯示角標 startService(new Intent(MainActivity.this, BadgeIntentService.class).putExtra("badgeCount", 9));*/ } }
項目結構
小米設備上運行效果圖
注意:通知欄中會有一個空白通知。
總結
Android的角標添加和移除畢竟是基於各大手機廠商的Launcher的定制,因此不是正統的Android技巧,隨着廠商的Launcher的改變,也許你的代碼未來就不一定有用了,因此需要不斷修改,“推陳出新”。
項目Demo下載地址
https://github.com/haiyuKing/ShortcutBadgerDemo