На iPhone вы можете добавить пронумерованный значок к значку приложения. На BlackBerry я успешно нарисовал изображение на значке приложения в программе. Я хочу сделать это и для Android. Я не хочу использовать панель уведомлений, так как это не то, что нужно немедленно уведомлять. Вместо этого я просто хочу, чтобы пользователь мог видеть, сколько новых сообщений находится в приложении, просто глядя на значок приложения.
Есть ли способ добавить значок к значку приложения в Android?
Ответ 1
К сожалению, Android не позволяет изменять значок приложения, поскольку он запечатан в APK после компиляции программы. Невозможно программно изменить его на "drawable".
Вы можете достичь своей цели, используя виджет вместо значка. Виджеты очень настраиваемые и могут делать то, что вы хотите.
Здесь кратко обсуждается разница между уведомлением значка iPhone и использованием виджетов здесь:
http://www.cnet.com/8301-19736_1-10278814-251.html
Как вы заметили, практически нет разницы между использованием виджета или значка, поскольку они могут быть одного размера и выглядеть одинаково.
Ответ 2
Это также можно сделать для Sony Xperia Home. Я писал об этом здесь, но важные части ниже. Устройства Sony используют класс с именем BadgeReciever
.
-
Объявите разрешение
com.sonyericsson.home.permission.BROADCAST_BADGE
в файле манифеста: -
Распространяйте
Intent
наBadgeReceiver
: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);
-
Готово. Как только этот
Intent
транслируется, пусковая установка должна показывать значок на вашем значке приложения. -
Чтобы снова удалить значок, просто отправьте новую трансляцию, на этот раз с
SHOW_MESSAGE
установите значение false:intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", false);
Я исключил детали о том, как я нашел это, чтобы сохранить ответ короче, но все это доступно в блоге. Может быть интересно прочитать кого-то.
Я также разместил отдельный SO-вопрос об этом здесь и добавлю полный ответ там, как только мне позволено (нужно 10 репутации, чтобы ответить на мои собственные вопрос в течение 8 часов).
Ответ 3
ShortcutBadger библиотека позволяет и работает с LG, Sony, Samsung, HTC и другими пользовательскими пусковыми установками.
У него даже есть способ отображения значка "Значок" на рабочем столе "Чистый Android".
Обновление значка в значке приложения так же просто, как и вызов:
int badgeCount = 1;
ShortcutBadger.setBadge(getApplicationContext(), badgeCount);
Он включает демонстрационное приложение, которое позволяет вам проверять его поведение.
ИЛИ
вы также можете попробовать алиас активности, чтобы сделать это, но в этом вам нужно создать разные значки с значками значков, он отлично подойдет в случае, если вам нужно переключиться между двумя различными значками приложения (нужно создать различные действия - псевдоним для отображения различного значка, т.е. больше значков = больше псевдонимов активности).
Ответ 4
Вот как это сделать для:
Я думаю, что есть и способ сделать это на пусковой установке LG, но пока не понял.
Ответ 5
Устройства 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"
);
}
}