web-dev-qa-db-ja.com

Androidのアプリケーションアイコンにバッジを追加する方法はありますか?

IPhoneでは、番号付きバッジをアプリケーションアイコンに追加できます。 BlackBerryでは、プログラム中にアプリケーションのアイコンに画像を正常に描画しました。これをAndroidでも行います。通知バーはすぐに通知する必要がないため、通知バーは使用しません。代わりに、ユーザーにアプリケーションアイコンを見るだけで、アプリケーション内の新しいメッセージの数を確認できます。

47
groomsy

残念ながら、Androidは、プログラムがコンパイルされるとAPKに封印されるため、アプリケーションアイコンの変更を許可しません。プログラムで「描画可能」に変更する方法はありません。

アイコンの代わりにウィジェットを使用して、目標を達成できます。ウィジェットは高度にカスタマイズ可能であり、必要なことを実行できます。

IPhoneのアイコン通知とウィジェットの使用の違いについては、ここで簡単に説明します。

http://www.cnet.com/8301-19736_1-10278814-251.html

お気づきのとおり、ウィジェットまたはアイコンを使用しても、サイズと外観は同じであるため、実質的に違いはありません。

32
HXCaine

これは、SonyのXperia Homeでも実行できます。私はそれについて here についてブログに書いたが、重要な部分は以下にある。 Sonyデバイスは、BadgeRecieverという名前のクラスを使用します。

  1. マニフェストファイルでcom.sonyericsson.home.permission.BROADCAST_BADGE権限を宣言します。

  2. IntentBadgeReceiverにブロードキャストします。

    Intent intent = new Intent();
    
    intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", "com.yourdomain.yourapp.MainActivity");
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", "99");
    intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", "com.yourdomain.yourapp");
    
    sendBroadcast(intent);
    
  3. できたこのIntentがブロードキャストされると、ランチャーはアプリケーションアイコンにバッジを表示します。

  4. バッジを再度削除するには、SHOW_MESSAGEをfalseに設定して新しいブロードキャストを送信するだけです:

    intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", false);
    

答えを短くするためにこれを見つけた方法の詳細を除外しましたが、それはすべてブログで入手できます。誰かにとって興味深い読み物かもしれません。

また、別のSOこれについての質問 here を投稿し、許可されたらそこに完全な回答を追加します(自分の質問に答えるには10の評判が必要です) 8時間以内)。

16
Marcus

ShortcutBadger ライブラリはそれを可能にし、LG、Sony、Samsung、HTC、およびその他のカスタムランチャーで動作します。

Pure Androidデバイスデスクトップでバッジカウントを表示する方法もあります。

アプリケーションアイコンのバッジカウントの更新は、呼び出すのと同じくらい簡単です。

int badgeCount = 1;
ShortcutBadger.setBadge(getApplicationContext(), badgeCount);

動作をテストできるデモアプリケーションが含まれています。

OR

アクティビティエイリアスを試すこともできますが、この場合、バッジ値を持つ異なるアイコンを作成する必要があります。これは、2つの異なるアプリアイコンを切り替える必要がある場合に役立ちます(表示するために異なるアクティビティエイリアスを作成する必要があります)別のアイコン、つまりアイコンが多い=アクティビティエイリアスが多い)。

9
Gagan Deep

Asusデバイス:

public static class AsusHomeBadger implements Badger {

    private static final String INTENT_ACTION = "Android.intent.action.BADGE_COUNT_UPDATE";
    private static final String INTENT_EXTRA_BADGE_COUNT = "badge_count";
    private static final String INTENT_EXTRA_PACKAGENAME = "badge_count_package_name";
    private static final String INTENT_EXTRA_ACTIVITY_NAME = "badge_count_class_name";

    @Override
    public void executeBadge(int badgeCount) {
        final Intent intent = new Intent(INTENT_ACTION);
        intent.putExtra(INTENT_EXTRA_BADGE_COUNT, badgeCount);
        intent.putExtra(INTENT_EXTRA_PACKAGENAME, componentName.getPackageName());
        intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
        intent.putExtra("badge_vip_count", 0);
        if (canResolveBroadcast(intent)) {
            AndroidUtilities.runOnUIThread(new Runnable() {
                @Override
                public void run() {
                    ApplicationLoader.applicationContext.sendBroadcast(intent);
                }
            });
        }
    }

    @Override
    public List<String> getSupportLaunchers() {
        return Arrays.asList("com.asus.launcher");
    }
}

Huaweiデバイス:

public static class HuaweiHomeBadger implements Badger {

    @Override
    public void executeBadge(int badgeCount) {
        final Bundle localBundle = new Bundle();
        localBundle.putString("package", ApplicationLoader.applicationContext.getPackageName());
        localBundle.putString("class", componentName.getClassName());
        localBundle.putInt("badgenumber", badgeCount);
        AndroidUtilities.runOnUIThread(new Runnable() {
            @Override
            public void run() {
                try {
                    ApplicationLoader.applicationContext.getContentResolver().call(Uri.parse("content://com.huawei.Android.launcher.settings/badge/"), "change_badge", null, localBundle);
                } catch (Exception e) {
                    FileLog.e(e);
                }
            }
        });
    }

    @Override
    public List<String> getSupportLaunchers() {
        return Arrays.asList(
                "com.huawei.Android.launcher"
        );
    }
}

HTCデバイス:

public static class NewHtcHomeBadger implements Badger {

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

    @Override
    public void executeBadge(int badgeCount) {

        final Intent intent1 = new Intent(INTENT_SET_NOTIFICATION);
        intent1.putExtra(EXTRA_COMPONENT, componentName.flattenToShortString());
        intent1.putExtra(EXTRA_COUNT, badgeCount);

        final Intent intent = new Intent(INTENT_UPDATE_SHORTCUT);
        intent.putExtra(PACKAGENAME, componentName.getPackageName());
        intent.putExtra(COUNT, badgeCount);

        if (canResolveBroadcast(intent1) || canResolveBroadcast(intent)) {
            AndroidUtilities.runOnUIThread(new Runnable() {
                @Override
                public void run() {
                    ApplicationLoader.applicationContext.sendBroadcast(intent1);
                    ApplicationLoader.applicationContext.sendBroadcast(intent);
                }
            });
        }
    }

    @Override
    public List<String> getSupportLaunchers() {
        return Arrays.asList("com.htc.launcher");
    }
}

Samsungデバイス:

public static class SamsungHomeBadger implements Badger {
    private static final String CONTENT_URI = "content://com.sec.badge/apps?notify=true";
    private static final String[] CONTENT_PROJECTION = new String[]{"_id","class"};

    private static DefaultBadger defaultBadger;

    @Override
    public void executeBadge(int badgeCount) {
        try {
            if (defaultBadger == null) {
                defaultBadger = new DefaultBadger();
            }
            defaultBadger.executeBadge(badgeCount);
        } catch (Exception ignore) {

        }

        Uri mUri = Uri.parse(CONTENT_URI);
        ContentResolver contentResolver = ApplicationLoader.applicationContext.getContentResolver();
        Cursor cursor = null;
        try {
            cursor = contentResolver.query(mUri, CONTENT_PROJECTION, "package=?", new String[]{componentName.getPackageName()}, null);
            if (cursor != null) {
                String entryActivityName = componentName.getClassName();
                boolean entryActivityExist = false;
                while (cursor.moveToNext()) {
                    int id = cursor.getInt(0);
                    ContentValues contentValues = getContentValues(componentName, badgeCount, false);
                    contentResolver.update(mUri, contentValues, "_id=?", new String[]{String.valueOf(id)});
                    if (entryActivityName.equals(cursor.getString(cursor.getColumnIndex("class")))) {
                        entryActivityExist = true;
                    }
                }

                if (!entryActivityExist) {
                    ContentValues contentValues = getContentValues(componentName, badgeCount, true);
                    contentResolver.insert(mUri, contentValues);
                }
            }
        } finally {
            close(cursor);
        }
    }

    private ContentValues getContentValues(ComponentName componentName, int badgeCount, boolean isInsert) {
        ContentValues contentValues = new ContentValues();
        if (isInsert) {
            contentValues.put("package", componentName.getPackageName());
            contentValues.put("class", componentName.getClassName());
        }

        contentValues.put("badgecount", badgeCount);

        return contentValues;
    }

    @Override
    public List<String> getSupportLaunchers() {
        return Arrays.asList(
                "com.sec.Android.app.launcher",
                "com.sec.Android.app.twlauncher"
        );
    }
}

Sonyデバイス:

public static class SonyHomeBadger implements Badger {

    private static final String INTENT_ACTION = "com.sonyericsson.home.action.UPDATE_BADGE";
    private static final String INTENT_EXTRA_PACKAGE_NAME = "com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME";
    private static final String INTENT_EXTRA_ACTIVITY_NAME = "com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME";
    private static final String INTENT_EXTRA_MESSAGE = "com.sonyericsson.home.intent.extra.badge.MESSAGE";
    private static final String INTENT_EXTRA_SHOW_MESSAGE = "com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE";

    private static final String PROVIDER_CONTENT_URI = "content://com.sonymobile.home.resourceprovider/badge";
    private static final String PROVIDER_COLUMNS_BADGE_COUNT = "badge_count";
    private static final String PROVIDER_COLUMNS_PACKAGE_NAME = "package_name";
    private static final String PROVIDER_COLUMNS_ACTIVITY_NAME = "activity_name";
    private static final String SONY_HOME_PROVIDER_NAME = "com.sonymobile.home.resourceprovider";
    private final Uri BADGE_CONTENT_URI = Uri.parse(PROVIDER_CONTENT_URI);

    private static AsyncQueryHandler mQueryHandler;

    @Override
    public void executeBadge(int badgeCount) {
        if (sonyBadgeContentProviderExists()) {
            executeBadgeByContentProvider(badgeCount);
        } else {
            executeBadgeByBroadcast(badgeCount);
        }
    }

    @Override
    public List<String> getSupportLaunchers() {
        return Arrays.asList("com.sonyericsson.home", "com.sonymobile.home");
    }

    private static void executeBadgeByBroadcast(int badgeCount) {
        final Intent intent = new Intent(INTENT_ACTION);
        intent.putExtra(INTENT_EXTRA_PACKAGE_NAME, componentName.getPackageName());
        intent.putExtra(INTENT_EXTRA_ACTIVITY_NAME, componentName.getClassName());
        intent.putExtra(INTENT_EXTRA_MESSAGE, String.valueOf(badgeCount));
        intent.putExtra(INTENT_EXTRA_SHOW_MESSAGE, badgeCount > 0);
        AndroidUtilities.runOnUIThread(new Runnable() {
            @Override
            public void run() {
                ApplicationLoader.applicationContext.sendBroadcast(intent);
            }
        });
    }

    private void executeBadgeByContentProvider(int badgeCount) {
        if (badgeCount < 0) {
            return;
        }

        if (mQueryHandler == null) {
            mQueryHandler = new AsyncQueryHandler(ApplicationLoader.applicationContext.getApplicationContext().getContentResolver()) {

                @Override
                public void handleMessage(Message msg) {
                    try {
                        super.handleMessage(msg);
                    } catch (Throwable ignore) {

                    }
                }
            };
        }
        insertBadgeAsync(badgeCount, componentName.getPackageName(), componentName.getClassName());
    }

    private void insertBadgeAsync(int badgeCount, String packageName, String activityName) {
        final ContentValues contentValues = new ContentValues();
        contentValues.put(PROVIDER_COLUMNS_BADGE_COUNT, badgeCount);
        contentValues.put(PROVIDER_COLUMNS_PACKAGE_NAME, packageName);
        contentValues.put(PROVIDER_COLUMNS_ACTIVITY_NAME, activityName);
        mQueryHandler.startInsert(0, null, BADGE_CONTENT_URI, contentValues);
    }

    private static boolean sonyBadgeContentProviderExists() {
        boolean exists = false;
        ProviderInfo info = ApplicationLoader.applicationContext.getPackageManager().resolveContentProvider(SONY_HOME_PROVIDER_NAME, 0);
        if (info != null) {
            exists = true;
        }
        return exists;
    }
}

Xiaomiデバイス:

public static class XiaomiHomeBadger implements Badger {

    public static final String INTENT_ACTION = "Android.intent.action.APPLICATION_MESSAGE_UPDATE";
    public static final String EXTRA_UPDATE_APP_COMPONENT_NAME = "Android.intent.extra.update_application_component_name";
    public static final String EXTRA_UPDATE_APP_MSG_TEXT = "Android.intent.extra.update_application_message_text";

    @Override
    public void executeBadge(int badgeCount) {
        try {
            Class miuiNotificationClass = Class.forName("Android.app.MiuiNotification");
            Object miuiNotification = miuiNotificationClass.newInstance();
            Field field = miuiNotification.getClass().getDeclaredField("messageCount");
            field.setAccessible(true);
            field.set(miuiNotification, String.valueOf(badgeCount == 0 ? "" : badgeCount));
        } catch (Throwable e) {
            final Intent localIntent = new Intent(INTENT_ACTION);
            localIntent.putExtra(EXTRA_UPDATE_APP_COMPONENT_NAME, componentName.getPackageName() + "/" + componentName.getClassName());
            localIntent.putExtra(EXTRA_UPDATE_APP_MSG_TEXT, String.valueOf(badgeCount == 0 ? "" : badgeCount));
            if (canResolveBroadcast(localIntent)) {
                AndroidUtilities.runOnUIThread(new Runnable() {
                    @Override
                    public void run() {
                        ApplicationLoader.applicationContext.sendBroadcast(localIntent);
                    }
                });
            }
        }
    }

    @Override
    public List<String> getSupportLaunchers() {
        return Arrays.asList(
                "com.miui.miuilite",
                "com.miui.home",
                "com.miui.miuihome",
                "com.miui.miuihome2",
                "com.miui.mihome",
                "com.miui.mihome2"
        );
    }
}
0
amin saffar