Android 角标适配

角标是从 iOS 那边 copy 过来的一个功能,目前 Android 没有提供系统 API 对此做支持。如果需要适配这个功能需要遵循主流的 Android 手机厂商的适配规范,文章列举的 华为 三星 vivo  HTC 的适配方式。

 

一 判断机型

if (Build.MANUFACTURER.equalsIgnoreCase("HUAWEI")) {
            // luncherPackageName : com.huawei.android.internal.app
            badgeHandler = new HuaweiBadgeHandler(context);
            return;
        }
        if (Build.MANUFACTURER.equalsIgnoreCase("vivo")) {
            badgeHandler = new VivoBadgeHandler(context);
            return;
        }
        if (Build.MANUFACTURER.equalsIgnoreCase("samsung")) {
            badgeHandler = new SamsungBadgeHandler(context);
            return;
        }
        if (Build.MANUFACTURER.equalsIgnoreCase("HTC")) {
            badgeHandler = new HtcBadgeHandler(context);
            return;
        }

二 各机型适配规则:

1 华为:

public class HuaweiBadgeHandler implements IBadgeHandler {

    private static final String TAG = HuaweiBadgeHandler.class.getSimpleName();

    private Context context;
    private boolean isSupportedBade = false;
    private String packageName;
    private String launchClassName;
    private ExecutorService executorService = Executors.newSingleThreadExecutor();

    HuaweiBadgeHandler(Context context) {
        this.context = context;
        try {
            packageName = context.getPackageName();
            launchClassName = context.getPackageManager()
                    .getLaunchIntentForPackage(packageName)
                    .getComponent().getClassName();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    @Override
    public void updateBadgeCount(int count) {
        checkIsSupportedByVersion();
        if (isSupportedBade) {
            ChangeBadgeRunnable runnable = new ChangeBadgeRunnable(count);
            executorService.submit(runnable);
        }
    }

    private void checkIsSupportedByVersion() {
        if (launchClassName == null) {
            isSupportedBade = false;
            return;
        }
        try {
            PackageManager manager = context.getPackageManager();
            PackageInfo info = manager.getPackageInfo("com.huawei.android.launcher",
                    0);
            if (info.versionCode >= 63025) {
                isSupportedBade = true;
            }
            RLog.d(TAG, "checkIsSupportedByVersion versionCode " + info.versionCode + " isSupportedBade: " + isSupportedBade);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private class ChangeBadgeRunnable implements Runnable {

        private int count;

        ChangeBadgeRunnable(int count) {
            this.count = count;
        }

        @Override
        public void run() {
            try {
                Bundle bundle = new Bundle();//需要存储的数据
                bundle.putString("package", packageName);//包名
                bundle.putString("class", launchClassName);//启动的Activity完整名称
                bundle.putInt("badgenumber", count);//未读信息条数
                context.getContentResolver().call(
                        Uri.parse("content://com.huawei.android.launcher.settings/badge/"),
                        "change_badge", null, bundle);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

2 Htc:

public class HtcBadgeHandler implements IBadgeHandler {

    private Context context;

    private static final String EXTRA_COMPONENT = "com.htc.launcher.extra.COMPONENT";
    private static final String EXTRA_COUNT = "com.htc.launcher.extra.COUNT";
    private static final String INTENT_SET_NOTIFICATION = "com.htc.launcher.action.SET_NOTIFICATION";
    private static final String INTENT_UPDATE_SHORTCUT = "com.htc.launcher.action.UPDATE_SHORTCUT";
    private static final String COUNT = "count";
    private static final String PACKAGENAME = "packagename";
    private ComponentName componentName;

    public HtcBadgeHandler(Context context) {
        this.context = context;
        componentName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent();
    }

    @Override
    public void updateBadgeCount(int count) {
        Intent intent = new Intent(INTENT_SET_NOTIFICATION);
        intent.putExtra(EXTRA_COMPONENT, componentName.flattenToShortString());
        intent.putExtra(EXTRA_COUNT, count);

        Intent intent1 = new Intent(INTENT_UPDATE_SHORTCUT);
        intent1.putExtra(PACKAGENAME, context.getPackageName());
        intent1.putExtra(COUNT, count);

        if (canResolveBroadcast(intent) || canResolveBroadcast(intent1)) {
            context.sendBroadcast(intent);
            context.sendBroadcast(intent1);
        }
    }

    private boolean canResolveBroadcast(Intent intent) {
        PackageManager packageManager = context.getPackageManager();
        List<ResolveInfo> receivers = packageManager.queryBroadcastReceivers(intent, 0);
        return receivers != null && receivers.size() > 0;
    }
}

 

3 三星:

 

public class SamsungBadgeHandler implements IBadgeHandler {

    private Context context;

    public SamsungBadgeHandler(Context context) {
        this.context = context;
    }

    @Override
    public void updateBadgeCount(int count) {
        String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
        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", launchClassName);
        context.sendBroadcast(intent);
    }
}

4 Vivo:

 

public class VivoBadgeHandler implements IBadgeHandler {

    private Context context;

    public VivoBadgeHandler(Context context) {
        this.context = context;
    }

    @Override
    public void updateBadgeCount(int count) {
        Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM");
        intent.putExtra("packageName", context.getPackageName());
        String launchClassName = context.getPackageManager().getLaunchIntentForPackage(context.getPackageName()).getComponent().getClassName();
        intent.putExtra("className", launchClassName);
        intent.putExtra("notificationNum", count);
        context.sendBroadcast(intent);
    }
}

角标适配的复杂在于机型厂商多样,以及如何更好的跟自身业务结合,例如一些需要杀死主进程还需要提醒角标的场景。

希望后续 google 可以在某个版本出系统级别的 API 接口来规范 Android 角标的问题。

 

推荐参考项目 : https://github.com/leolin310148/ShortcutBadger

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值