1. ホーム
  2. アンドロイド

[注意事項】Androidデスクトップコーナー Badge公式ドキュメントと互換性ソリューション

2022-02-27 20:49:19

久しぶりにブログを書きます!プロジェクトに忙しくしていました。そんな中、リーダーから「iOSのように未読メッセージの数をリマインドできるコーナーマーカーを作りたい」という新たな要望が。データを確認したところ、最も出現頻度が高いのは ショートカットバジャー ショートカットヘルパー この2つのプロジェクトは多くの機種に対応しているのですが、どちらもしばらく前からアップデートされており、実際に使ってみると動かなくなったものが多くありました。

公式に利用可能

コーナーラベルのHuawei公式ドキュメント :

Huaweiは、コーナーラベルの使用に関する詳細を提供することについてはまだかなり良いですが、パーミッションの追加を忘れないでください。

<スパン 備考 : Huawei社のドキュメントへのリンクがうまくいかない可能性について Huawei開発者向けページ コーナーマーカーで検索すると、Huaweiのコーナーマーカー開発ガイドブックが見つかります。

Xiaomiのコーナーラベルの公式ドキュメント :

Xiaomiもオープンプラットフォームで検索してコーナーマーカーの用途を見つけるという、かなり気前の良い仕事をしていますが、まだ2つ問題があります。

Lenovo ZUKの公式ドキュメント :

市場に流通している携帯電話の中で大きなシェアを占めているわけではありませんが、コーナーマーカーの使い方の詳細が掲載されています。

ソニー公式ドキュメント :

ソニーから渡された公式のものは少し厄介で、公式サイトでバッジを検索して何度も答え合わせをして、正式な使い方を見つけたのだそうです。

Google公式ドキュメント :

これはAndroid 8.0からの新機能ですが、これもドットだけで、数字の色やコントロールはありません。

機種別互換性

Huawei

Huaweiは、データベースのURIと、データベースを外部から操作するための権限を提供しています。Interfaceメソッドを指定し、表示するコーナー数とアプリの一部のパッケージ名をHuawei Desktopに渡すことで、未読コーナー情報を表示できるようになりますが、パーミッションの追加を忘れないようにしましょう。

    private static void badgeHuawei(Context context, int badgeCount) { try {
        try {
            Bundle bunlde = new Bundle();
            bunlde.putString("package", context.getPackageName());
            bunlde.putString("class", launcherClassName);
            bunlde.putInt("badgenumber", badgeCount);
            context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge& quot;, null, bunlde);
        } catch (Exception e) {
            Log.e(TAG, e.getMessage());
        }
    }
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE " />

    private static void badgeXiaomi(final Context context, final int badgeCount) {
        new Handler().postDelayed(new Runnable() {
            @Override
            public void run() {
                // The 1 second delay is to avoid executing the operation while still inside the app, but to really avoid it you still need to control the timing of the call
                try {
                    Notification notification = getNotification(context, badgeCount);
                    Field field = notification.getClass().getDeclaredField("extraNotification");
                    Object extraNotification = field.get(notification);
                    Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
                    method.invoke(extraNotification, badgeCount);
                    BadgerUtil.notify(notification, badgeCount);
                } catch (Exception e) {
                    e.printStackTrace();
                    // the Internet is said to be miui 6 before the version, no miui6 before the version of Xiaomi phones do not know if there is valid
                    Intent localIntent = new Intent("android.intent.action.APPLICATION_MESSAGE_UPDATE");
                    localIntent.putExtra("android.intent.extra.update_application_component_name", context.getPackageName() + "/" + getLauncherClassName(context));
                    localIntent.putExtra("android.intent.extra.update_application_message_text", String.valueOf(badgeCount == 0 ? "" : badgeCount));
                    context.sendBroadcast(localIntent);
                }
            }
        }, 1000);
    }

シャオミ

Xiaomiは公式のドキュメントを提供していますが、まだ2つの問題があります。

1. コーナーマーカーを追加するメソッドを実行したときに、アプリ内または以前の通知を消去していない場合、Xiaomi携帯電話ではコーナーマーカーが表示されない。

    private static NotificationManager notificationManager;

    private static Notification getNotification(Context context, int badgeCount) {
        if (notificationManager == null) {
            notificationManager = ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //NotificationChannel is required to add corner labels after 8.0
                NotificationChannel channel = new NotificationChannel("badge", "badge", NotificationManager.IMPORTANCE_LOW);
                channel.setShowBadge(true);
                ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
            }
        }

        Notification notification = new NotificationCompat.Builder(context, "badge")
                .setContentTitle("notification")
                .setContentText("new message")
                .setSmallIcon(R.drawable.ic_launcher)
                .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
                .setNumber(badgeCount)
                .setAutoCancel(true)
                .build();
        return notification;
    }

    /**
     * Send notification
     */
    private static void notify(Notification notification, int badgeCount) {
        notificationManager.cancel(TAG, NOTIFY_ID);
        if (badgeCount > 0) {
            notificationManager.notify(TAG, NOTIFY_ID, notification);
        }
    }


2、Android 8.0は、最初の設定NotificationChannelを使用する必要が通知の使用に調整を加え、それ以外の場合は、エラーメッセージを表示されます、あなたは、特定の見ることができます 公式ドキュメント を使用します。

    private static void badgeZuk(Context context, int badgeCount) {
        Bundle extra = new Bundle();
        extra.putInt("app_badge_count", badgeCount);
        context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extra );
    }
    <uses-permission android:name="android.permission.READ_APP_BADGE" />

レノボZUK

zukの使い方もLenovoと同様で、データベースを操作する機能を提供し、また、パーミッションの追加も必要です。

    <use-permission android:name="com.sonymobile.home.permission.PROVIDER_INSERT_BADGE" />
    <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
    <uses-permission android:name="com.sonyericsson.home.action.UPDATE_BADGE" />

    private static void badgeSamsung(Context context, int badgeCount) {
        Uri uri = Uri.parse("content://com.sec.badge/apps");
        String columnId = "_id";
        String columnPackage = "package";
        String columnClass = "class";
        String columnBadgeCount = "badgeCount";
        Cursor cursor = null;
        try {
            ContentResolver contentResolver = context.getContentResolver();
            cursor = contentResolver.query(uri, new String[]{columnId}, columnPackage + "=? ", new String[]{context.getPackageName()}, null);

            if (cursor == null || !cursor.moveToFirst()) {
                ContentValues contentValues = new ContentValues();
                contentValues.put(columnPackage, context.getPackageName());
                contentValues.put(columnClass, launcherClassName);
                contentValues.put(columnBadgeCount, badgeCount);
                contentResolver.insert(uri, contentValues);
            } else {
                int idColumnIndex = cursor.getColumnIndex(columnId);

                ContentValues contentValues = new ContentValues();
                contentValues.put(columnBadgeCount, badgeCount);
                contentResolver.update(uri, contentValues, columnId + "=? ", new String[]{String.valueOf(cursor.getInt(idColumnIndex))});
            }
        } catch (Exception e) {
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", badgeCount);
            intent.putExtra("badge_count_package_name", context.getPackageName());
            intent.putExtra("badge_count_class_name", launcherClassName);
            context.sendBroadcast(intent);
        } finally {
            if (cursor ! = null) {
                cursor.close();
            }
        }
    }

    <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />

ソニー

ソニーが出している公式の方法は、ネットの多くが使っている方法とは違うようで、ソニーの携帯がないとテストできないし、パーミッションもちょっと違うので、ここに全部追加しておきました。

    private static void badgeSony(Context context, int badgeCount) { {
        if (asyncQueryHandler == null) {
            asyncQueryHandler = new AsyncQueryHandler(context.getContentResolver()) { 非同期クエリハンドラ。
            };
        
        トライ
            //公式メソッド
            ContentValues contentValues = new ContentValues();
            contentValues.put("badge_count", badgeCount);
            contentValues.put("package_name", context.getPackageName());
            contentValues.put("activity_name", launcherClassName);
            asyncQueryHandler.startInsert(0, null, Uri.parse("content://com.sonymobile.home.resourceprovider/badge"), contentValues).を実行します。
        } キャッチ (例外 e) {
            // ほとんどのメソッドはオンラインで使用
            Intent intent = new Intent("com.sonyericsson.home.action.UPDATE_BADGE");
            intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", badgeCount > 0);
            intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);
            intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(badgeCount > 0 ? badgeCount : "")));
            intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());
            context.sendBroadcast(intent)を実行します。
        }
    }


    private static void badgeHtc(Context context, int badgeCount) { try {
        try {
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", badgeCount);
            intent.putExtra("badge_count_package_name", context.getPackageName());
            intent.putExtra("badge_count_class_name", launcherClassName);
            context.sendBroadcast(intent);
        } catch (Exception e) {

        }
    }

サムスン

ShortcutBadgerでデータベース操作を使っているが、非推奨のコメントを追加している、もしかしたら旧バージョンで使われていて新バージョンで使えないのかもしれない。

    private static NotificationManager notificationManager;

    private static Notification getNotification(Context context, int badgeCount) {
        if (notificationManager == null) {
            notificationManager = ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //NotificationChannel is required to add corner labels after 8.0
                NotificationChannel channel = new NotificationChannel("badge", "badge", NotificationManager.IMPORTANCE_LOW);
                channel.setShowBadge(true);
                ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
            }
        }

        Notification notification = new NotificationCompat.Builder(context, "badge")
                .setContentTitle("notification")
                .setContentText("new message")
                .setSmallIcon(R.drawable.ic_launcher)
                .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
                .setNumber(badgeCount)
                .setAutoCancel(true)
                .build();
        return notification;
    }

    /**
     * Send notification
     */
    private static void notify(Notification notification, int badgeCount) {
        notificationManager.cancel(TAG, NOTIFY_ID);
        if (badgeCount > 0) {
            notificationManager.notify(TAG, NOTIFY_ID, notification);
        }
    }

    <uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
    <uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />

HTC

HTCはブロードキャスト送信のみ必要で、パーミッションは必要ない、5.0, 7.0 pro-testは動作する

    private static void badgeHtc(Context context, int badgeCount) { try {
        try {
            Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE");
            intent.putExtra("badge_count", badgeCount);
            intent.putExtra("badge_count_package_name", context.getPackageName());
            intent.putExtra("badge_count_class_name", launcherClassName);
            context.sendBroadcast(intent);
        } catch (Exception e) {

        }
    }

グーグル

Android 8.0では、数字や色の変更ができない点線のコーナーマーカーが表示されるようになりました

    private static NotificationManager notificationManager;

    private static Notification getNotification(Context context, int badgeCount) {
        if (notificationManager == null) {
            notificationManager = ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE));
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
                //NotificationChannel is required to add corner labels after 8.0
                NotificationChannel channel = new NotificationChannel("badge", "badge", NotificationManager.IMPORTANCE_LOW);
                channel.setShowBadge(true);
                ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel);
            }
        }

        Notification notification = new NotificationCompat.Builder(context, "badge")
                .setContentTitle("notification")
                .setContentText("new message")
                .setSmallIcon(R.drawable.ic_launcher)
                .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL)
                .setNumber(badgeCount)
                .setAutoCancel(true)
                .build();
        return notification;
    }

    /**
     * Send notification
     */
    private static void notify(Notification notification, int badgeCount) {
        notificationManager.cancel(TAG, NOTIFY_ID);
        if (badgeCount > 0) {
            notificationManager.notify(TAG, NOTIFY_ID, notification);
        }
    }

OPPOとvivo

この2機種は、広告やオフラインの店舗により、今でもかなりのシェアを占めていますが、コーナーラベルの使い方が非常に情けないです。まずOPPOですが、公式文書がなく、カスタマーサービスを探した結果、非常に、非常に、非常に面倒としか言いようがありません

それなら、QQやWeChatでみんながどうするか見るしかないでしょう

QQの実装。

WeChatの実装。

ネットで実装方法を確認し、使用するコードに追加してみたが、うまくいかなかった。気になったのでパッケージ名をcom.tencent.mobileqqに変更、コーナーがオンラインになりましたね、おめでとうございます。OPPOとVivoが使えるようになりました。言葉を失いました...。

ソースコード

詳細なコードはGitHubをご覧ください。質問がある場合はコメントを残してください。