前言:android原生系统是不支持角标的,需要厂商自己实现,所以接口需要分别实现。项目需求,目前只在三星和小米上实现了角标功能。没有找到华为和魅族的实现方法。
怎么区分手机类型
//小米手机
Build.MANUFACTURER.equalsIgnoreCase("Xiaomi");
//三星手机
Build.MANUFACTURER.toLowerCase().contains("samsung")
测试成功的图片(像素有点低)
三星手机消息角标
第一步:在清单文件里面配置
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" /> <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
第二步:在项目第一次进入的时候注册一下
/**
* 注册三星权限 这个方法在程序第一次进入的时候要调用一下
*
* @param context
*/
public static void reguesterSamsung(Context context) {
ContentValues cv = new ContentValues();
cv.put("package", getPackageName());
//写入加载页的全路径名称 如:com.xxx.xx.ui.activity.SplashActivity
cv.put("class", getLauncherClassName(context));
cv.put("badgecount", 0); // integer count you want to display
// Execute insert
context.getContentResolver().insert(Uri.parse("content://com.sec.badge/apps"), cv);
}
下面这个方法是获取app的加载页的全名称
/**
* Retrieve launcher activity name of the application from the context
*
* @param context The context of the application package.
* @return launcher activity name of this application. From the
* "android:name" attribute.
*/
private static String getLauncherClassName(Context context) {
PackageManager packageManager = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
// To limit the components this Intent will resolve to, by setting an
// explicit package name.
intent.setPackage(context.getPackageName());
intent.addCategory(Intent.CATEGORY_LAUNCHER);
// All Application must have 1 Activity at least.
// Launcher activity must be found!
ResolveInfo info = packageManager
.resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);
// get a ResolveInfo containing ACTION_MAIN, CATEGORY_LAUNCHER
// if there is no Activity which has filtered by CATEGORY_DEFAULT
if (info == null) {
info = packageManager.resolveActivity(intent, 0);
}
return info.activityInfo.name;
}
第三步:进行消息设置,设置为零时清空消息
//主要代码部分
ContentValues cv = new ContentValues();
//count为int类型 消息的数量
cv.put("badgecount", count); context.getContentResolver().update(Uri.parse("content://com.sec.badge/apps"), cv, "package=?", new String[]{context.getPackageName()});
获取该app是否注册的方法
//检测是否注册成功 会打印出来
private static void testReguster(Context context) {
Uri uri = Uri.parse("content://com.sec.badge/apps");
Cursor c = context.getContentResolver().query(uri, null, null, null, null);
if (c == null) {
return;
}
try {
if (!c.moveToFirst()) {
return;
}
c.moveToPosition(-1);
while (c.moveToNext()) {
String pkg = c.getString(1);
String clazz = c.getString(2);
int badgeCount = c.getInt(3);
// Log.d("BadgeTest", "package: " + pkg + ", class: " + clazz + ", count: " + String.valueOf(cnt));
Log.d("BadgeTest", "package: " + pkg + ", class: " + clazz + ", count: ");
}
} finally {
c.close();
}
}
用极光推送测试的消息展示,进入app后消息角标不会消失。需要自行处理一下,我的方法是在MainActivity结束时重新展示一下。
小米手机消息角标
小米手机不需要什么权限,值得注意的是点击app后,消息自动清除。消息的角标是基于
Notification的,miui系统重写了这个系统类(好像是com.android.MiUINotification)。目前只支持MIUI 6以上(以下版本我没有兼容)
这是官方的连接http://dev.xiaomi.com/doc/p=3904/。
具体代码:
NotificationCompat.Builder builder = new NotificationCompat.Builder(context)
.setSmallIcon(R.mipmap.ic_launcher) //
.setContentTitle(title)
.setContentText(info);
NotificationManagerCompat managerCompat = NotificationManagerCompat.from(context);
Notification notification = builder.build();
try { //防止miui6.0以下抛异常
//通过反射的方式获属性和方法
Field field = notification.getClass().getDeclaredField("extraNotification");
Object extraNotification = field.get(notification);
Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
method.invoke(extraNotification, count); //设置消息数 int类型(不要写错了)
} catch (Exception e) {
e.printStackTrace();
}
基本就是这些,测试机是红米,有个问题就是 极光消息推送后,如果程序在后台可能接收不到,消息不展示。
代码集成在项目中了,不能提供demo见谅。