问题
Samsung\'s TWLauncher allows apps to create badge counts on app icons.
This is completely undocumented! There is no mention of it anywhere, and only a handful of apps are using it (e.g. Facebook, eBay).
How do you use this functionality to add a count to your app icon?
This is very specific to Samsung devices. I am not asking about Android in general. I\'m only asking about badging Samsung\'s Touchwhiz interface which currently allows badging. Android does not.
回答1:
First you'll need to add the following permissions to your AndroidManifest.xml file.
<uses-permission android:name="com.sec.android.provider.badge.permission.READ" />
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE" />
The column structure is as follows:
(integer) _id, (text) package, (text) class, (integer) badgecount, (blob) icon, (???) extraData
In order to query ALL results from the BadgeProvider do the following:
// This is the content uri for the BadgeProvider
Uri uri = Uri.parse("content://com.sec.badge/apps");
Cursor c = getContentResolver().query(uri, null, null, null, null);
// This indicates the provider doesn't exist and you probably aren't running
// on a Samsung phone running TWLauncher. This has to be outside of try/finally block
if (c == null) {
return;
}
try {
if (!c.moveToFirst()) {
// No results. Nothing to query
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));
}
} finally {
c.close();
}
In order to add a badge count to your application icon
ContentValues cv = new ContentValues();
cv.put("package", getPackageName());
// Name of your activity declared in the manifest as android.intent.action.MAIN.
// Must be fully qualified name as shown below
cv.put("class", "com.example.badge.activity.Test");
cv.put("badgecount", 1); // integer count you want to display
// Execute insert
getContentResolver().insert(Uri.parse("content://com.sec.badge/apps"), cv);
If you want to clear the badge count on your icon
ContentValues cv = new ContentValues();
cv.put("badgecount", 0);
getContentResolver().update(Uri.parse("content://com.sec.badge/apps"), cv, "package=?", new String[] {getPackageName()});
NEW
I have created an open source project that you can import as a library to assist with this. It's licensed as Apache so feel free to use it as you please.
You can get it from here: https://github.com/shafty023/SamsungBadger
回答2:
There is another cool open source library that support different devices: https://github.com/leolin310148/ShortcutBadger/
回答3:
add these permissions to manifest
<!--for android badge-->
<uses-permission android:name="com.android.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.android.launcher.permission.WRITE_SETTINGS"/>
<!--for Samsung badge-->
<uses-permission android:name="com.sec.android.provider.badge.permission.READ"/>
<uses-permission android:name="com.sec.android.provider.badge.permission.WRITE"/>
<!--for htc badge-->
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS"/>
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT"/>
<!--for sony badge-->
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"/>
<!--for apex badge-->
<uses-permission android:name="com.anddoes.launcher.permission.UPDATE_COUNT"/>
add these package names to your class :
final String HOME_PACKAGE_SONY = "com.sonyericsson.home";
final String HOME_PACKAGE_SAMSUNG = "com.sec.android.app.launcher";
final String HOME_PACKAGE_LG = "com.lge.launcher2";
final String HOME_PACKAGE_HTC = "com.htc.launcher";
final String HOME_PACKAGE_ANDROID = "com.android.launcher";
final String HOME_PACKAGE_APEX = "com.anddoes.launcher";
final String HOME_PACKAGE_ADW = "org.adw.launcher";
final String HOME_PACKAGE_ADW_EX = "org.adwfreak.launcher";
final String HOME_PACKAGE_NOVA = "com.teslacoilsw.launcher";
for use :
// just put your pachage and main activity class path
String classPath = "ir.faasaa.resa.MainActivity";
ContentValues cv = new ContentValues();
cv.put("package", context.getPackageName());
cv.put("class", classPath);
cv.put("badgecount", count);
context.getContentResolver().insert(Uri.parse(HOME_PACKAGE_SAMSUNG), cv);
thanks to ShortcutBadger
回答4:
In android, we don't have badge style approach as iOS but some manufactures are supporting to display badge on app icons.
Support for sony and HTC.
Example for badge style icon on app in android
Sony and HTC supports adding badge to the app icon.
For Sony
<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
Intent intent= new Intent("com.sonyericsson.home.action.UPDATE_BADGE");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", Class Name);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE",number);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", packageName);
sendBroadcast(intent);
for HTC:
<uses-permission android:name="com.htc.launcher.permission.READ_SETTINGS" />
<uses-permission android:name="com.htc.launcher.permission.UPDATE_SHORTCUT" />
Intent updateIntent = new Intent("com.htc.launcher.action.UPDATE_SHORTCUT");
updateIntent.putExtra("packagename", packageName);
updateIntent.putExtra("count", number);
this.sendBroadcast(updateIntent);
Intent setNotificationIntent = new Intent("com.htc.launcher.action.SET_NOTIFICATION");
ComponentName localComponentName = new ComponentName(packageName, className);
setNotificationIntent.putExtra("com.htc.launcher.extra.COMPONENT", localComponentName.flattenToShortString());
setNotificationIntent.putExtra("com.htc.launcher.extra.COUNT", number);
this.sendBroadcast(setNotificationIntent);
回答5:
I use this class for Samsung and Sony devices (also available https://gist.github.com/Tadas44/cdae2f5995f21bf1c27f). Don't forget to add <uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE" />
to AndroidManifest.xml
public class BadgeUtils {
public static void setBadge(Context context, int count) {
setBadgeSamsung(context, count);
setBadgeSony(context, count);
}
public static void clearBadge(Context context) {
setBadgeSamsung(context, 0);
clearBadgeSony(context);
}
private static void setBadgeSamsung(Context context, int count) {
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
return;
}
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", launcherClassName);
context.sendBroadcast(intent);
}
private static void setBadgeSony(Context context, int count) {
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
return;
}
Intent intent = new Intent();
intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", true);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(count));
intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());
context.sendBroadcast(intent);
}
private static void clearBadgeSony(Context context) {
String launcherClassName = getLauncherClassName(context);
if (launcherClassName == null) {
return;
}
Intent intent = new Intent();
intent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", false);
intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(0));
intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());
context.sendBroadcast(intent);
}
private static String getLauncherClassName(Context context) {
PackageManager pm = context.getPackageManager();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_LAUNCHER);
List<ResolveInfo> resolveInfos = pm.queryIntentActivities(intent, 0);
for (ResolveInfo resolveInfo : resolveInfos) {
String pkgName = resolveInfo.activityInfo.applicationInfo.packageName;
if (pkgName.equalsIgnoreCase(context.getPackageName())) {
String className = resolveInfo.activityInfo.name;
return className;
}
}
return null;
}
}
回答6:
There is another tool that you can use for Xperia devices
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.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", "10");
More details as below
http://www.marcusforsberg.net/blog/android-notification-badge-app-icon-sony/
回答7:
For Android 8.0 Oreo Users-
For those who are getting trouble in showing badge count for Samsung S8, S9 or Pixel devices having Oreo in them note that ShortcutBadger Library does not supports API>26
for Samsung
Reported here in issues. Here you have to check it first if isBadgeCounterSupported
like that -
public boolean isBadgeCounterSupported() {
// Workaround for bug in ShortcutBadger in version 1.1.19, registered as
// https://github.com/leolin310148/ShortcutBadger/issues/266
if (Build.MANUFACTURER.equalsIgnoreCase("Samsung") && Build.VERSION.SDK_INT >= 26) {
Log.d("LOG_TAG", "Launcher icon badge (ShortcutBadger) is not supported on Samsung devices running Android 8 (or newer).");
return false;
}
return ShortcutBadger.isBadgeCounterSupported(context);
}
The only way is to apply Badges from Notification. As for applying badges from your notifications, see the Android documentation, and note the section "Set custom notification count".
Notification notification = new NotificationCompat.Builder(MainActivity.this, "my_channel_01")
.setContentTitle("New Messages")
.setContentText("You've received 3 new messages.")
.setSmallIcon(R.drawable.ic_notify_status)
.setNumber(messageCount) //this badge count
.build();
For more on Notifications in Android 8.0 refer to this answer .
来源:https://stackoverflow.com/questions/20136483/how-to-interface-with-the-badgeprovider-on-samsung-phones-to-add-a-count-to-the