Android 데스크 톱 아이콘 오른쪽 상단 에 읽 지 않 은 메시지 숫자 표시

배경:
Android 네 이 티 브 시스템 에 서 는 읽 지 않 은 메시지 알림 의 숫자 를 데스크 톱 아이콘 으로 표시 하 는 것 은 지원 되 지 않 는 것 으로 알려 져 있 습 니 다.제3자 컨트롤 BadgeView 는 응용 프로그램의 숫자 알림 을 실현 할 수 있 지만.그러나 시스템 아이콘,특히 app 의 로고 아이콘 은 디지털 로 고 를 실현 하기 어렵 고 그림 을 그 리 는 방식 이 계속 수정 되 더 라 도 이런 방식 은 타고 난 단점 으로 실용성 이 떨어진다.그러나 다행히도 일부 강력 한 휴대 전화 업 체(샤 오미,삼 성,소니)는 개인 API 를 제 공 했 지만 어려움 을 가 져 왔 다.API 가 다 르 면 코드 량 의 증가 와 호환성 문제 가 더욱 두 드 러 졌 다 는 것 을 의미한다.
이제 그들 이 어떻게 실현 되 었 는 지 살 펴 보 자.
실현 원리:
먼저 시작 아이콘 을 수정 하고 아이콘 을 동적 으로 수정 하 는 과정 은 주로 Launcher 에서 이 루어 진 것 이 아니 라 는 것 을 알 아야 합 니 다.설치,업데이트,마 운 트 해제 할 때 방송 에서 보 냅 니 다.Launcher 는 Launcher Application 에 광고 방송 을 등록 하고 Launcher Model 에서 방송 을 받 은 메 시 지 를 처리 합 니 다.업데이트 응용 정 보 를 다시 불 러 옵 니 다(예:아이콘,텍스트 등).그러나 네 이 티 브 안 드 로 이 드 시스템 은 이 기능 을 지원 하지 않 습 니 다(특정한 시스템 방송 을 통 해 시작 아이콘 을 동적 으로 수정 하 는 효 과 를 얻 을 수 없습니다).그러나 강력 한 제3자 안 드 로 이 드 핸드폰 업 체(예 를 들 어 삼 성,샤 오미)의 시스템 소스 코드 깊이 맞 춤 형 제작 을 통 해 Launcher 소스 코드 를 수정 한 적 이 있 습 니 다.새로운 방송 수신 기 를 추가/등록 하여 응용 프로그램 에서 보 낸 읽 지 않 은 메시지 수 방송 을 받 습 니 다.방송 을 받 은 후에 시스템 은 읽 지 않 은 메시지 의 수량 표시 이 벤트 를 Launcher 에 맡 기 고 관련 방법 으로 응용 프로그램의 icon 을 다시 그 려 서 최종 적 으로 동적 업데이트 응용 아이콘 의 효 과 를 얻 습 니 다.
예제 코드:

public class LauncherBadgeHelper {

 /**
  * Set badge count

  *    Samsung / xiaomi / sony     
  *
  * @param context The context of the application package.
  * @param count Badge count to be set
  */
 public static void setBadgeCount(Context context, int count) {
  if (count <= 0) {
   count = 0;
  } else {
   count = Math.max(0, Math.min(count, 99));
  }

  if (Build.MANUFACTURER.equalsIgnoreCase("Xiaomi")) {
   sendToXiaoMi(context, count);
  } else if (Build.MANUFACTURER.equalsIgnoreCase("sony")) {
   sendToSony(context, count);
  } else if (Build.MANUFACTURER.toLowerCase().contains("samsung")) {
   sendToSamsumg(context, count);
  } else {
   sendToSamsumg(context, count);
  }
 }

 /**
  *               
  *
  * @param count
  */
 private static void sendToXiaoMi(Context context, int count) {
  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(count == 0 ? "" : count)); //      -->       miui 6  
  } catch (Exception e) {
   LogController.e(e.toString());
   // miui 6     
   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(count == 0 ? "" : count));
   context.sendBroadcast(localIntent);
  }
 }

 /**
  *               

  *   :     :<uses-permission android:name="com.sonyericsson.home.permission.BROADCAST_BADGE"> [   ]
  *
  * @param count
  */
 private static void sendToSony(Context context, int count) {
  String launcherClassName = getLauncherClassName(context);
  if (launcherClassName == null) {
   return;
  }

  boolean isShow = true;
  if (count == 0) {
   isShow = false;
  }
  Intent localIntent = new Intent();
  localIntent.setAction("com.sonyericsson.home.action.UPDATE_BADGE");
  localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", isShow);//    
  localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName);//   
  localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(count));//  
  localIntent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName());//  
  context.sendBroadcast(localIntent);
 }

 /**
  *               
  *
  * @param count
  */
 private static void sendToSamsumg(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);
 }

 /**
  *   、  Badge     

  *
  * @param context
  */
 public static void resetBadgeCount(Context context) {
  setBadgeCount(context, 0);
 }

 /**
  * Retrieve launcher activity name of the application from the context
  *
  * @param context The context of the application package.
  * @return launcher activity name of this application. From the
  * "android:name" attribute.
  */
 private static String getLauncherClassName(Context context) {
  PackageManager packageManager = context.getPackageManager();

  Intent intent = new Intent(Intent.ACTION_MAIN);
  // To limit the components this Intent will resolve to, by setting an
  // explicit package name.
  intent.setPackage(context.getPackageName());
  intent.addCategory(Intent.CATEGORY_LAUNCHER);

  // All Application must have 1 Activity at least.
  // Launcher activity must be found!
  ResolveInfo info = packageManager
    .resolveActivity(intent, PackageManager.MATCH_DEFAULT_ONLY);

  // get a ResolveInfo containing ACTION_MAIN, CATEGORY_LAUNCHER
  // if there is no Activity which has filtered by CATEGORY_DEFAULT
  if (info == null) {
   info = packageManager.resolveActivity(intent, 0);
  }

  return info.activityInfo.name;
 }
}</uses-permission>
샤 오미,삼 성,소니 의 처리 방식 은 모두 방송 발송 을 통 해 이 루어 진 것 으로 보인다.
그러나 샤 오미 MIUI 6 이후 처리 방식 이 바 뀌 었 고 라디오 를 보 내 는 방식 을 버 리 고 알림 을 보 내 는 방식 으로 바 뀌 었 다.
기본 소개
1.기본 적 인 상황
app 이 알림 표시 줄 에 알림 을 보 냈 을 때(진행 표시 줄 이 없 으 며 사용자 가 삭제 할 수 있 음 을 알 립 니 다)데스크 톱 app icon 각 표 는 1 을 표시 합 니 다.이때 app 이 표시 하 는 각 표 지 는 알림 표시 줄 에 app 이 보 낸 알림 수 와 대응 합 니 다.즉,알림 표시 줄 에 보 낸 알림 표시 줄 에 보 낸 만큼 의 각 표 지 를 표시 합 니 다.
구현 코드
제3자 app 은 반사 로 호출 해 야 합 니 다.참고 코드:

NotificationManager mNotificationManager = (NotificationManager) this

.getSystemService(Context.NOTIFICATION_SERVICE);

Notification.Builder builder = new Notification.Builder(this)

.setContentTitle(“title”).setContentText(“text”).setSmallIcon(R.drawable.icon);

Notification notification = builder.build();

try {

Field field = notification.getClass().getDeclaredField(“extraNotification”);

Object extraNotification = field.get(notification);

Method method = extraNotification.getClass().getDeclaredMethod(“setMessageCount”, int.class);

method.invoke(extraNotification, mCount);

} catch (Exception e) {

e.printStackTrace();

}
mNotificationManager.notify(0,notification);
자신의 이전 코드 는 공식 코드 에 따라 새로운 방법 을 다음 과 같이 요약 한다.

/**
 *               miui6  
 *
 * @param count
 */
 private static void sendToXiaoMi2(Context context, int count) {
  NotificationManager mNotificationManager = (NotificationManager) MyApplication.getContext().getSystemService(Context.NOTIFICATION_SERVICE);
  Notification.Builder builder = new Notification.Builder(MyApplication.getContext()).setContentTitle("title").setContentText("text").setSmallIcon(R.drawable.ico_haoyilogo);
  Notification notification = null;
  if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN) {
   notification = builder.build();
  }
  try {
   Field field = notification.getClass().getDeclaredField("extraNotification");
   Object extraNotification = field.get(notification);
   Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class);
   method.invoke(extraNotification, count);
   mNotificationManager.notify(10, notification);
  } catch (Exception e) {
   e.printStackTrace();
   LogController.e(e.toString());
   // miui 6     
   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(count == 0 ? "" : count));
   context.sendBroadcast(localIntent);
  }
 }
이렇게 하면 MIUI 6 이전의 것 도 호 환 할 수 있 고 MIUI 6 이후 의 것 도 실현 할 수 있다.자신 이 개발 할 때 테스트 를 통 해 MIUI 내부 에 같은 메시지 숫자 가 표시 되 지 않 는 다 는 것 을 알 게 되 었 습 니 다.제 가 테스트 할 때 죽은 숫자 를 써 서 시행 착 오 를 많이 겪 었 습 니 다.그리고 자 료 를 찾 을 때 많은 친구 들 이 이런 문 제 를 겪 었 다 는 것 을 알 게 되 었 습 니 다.메 시 지 를 읽 지 않 은 숫자 는 처음 설치 할 때 만 표시 되 고 들 어간 후에 설정 하면 없어 집 니 다.저 는 모두 숫자 가 같 아서 생 긴 것 이 라 고 생각 합 니 다.
곰 곰 이 생각해 보면 MIUI 도 좋 습 니 다.메시지 숫자 와 알림 이 연결 되 어 있 습 니 다.알림 을 받 을 때 이벤트 가 발생 하여 데스크 톱 아이콘 의 숫자 가 동적 으로 변 합 니 다.우리 가 분명히 통지 할 때,숫자 를 비 워 라.자신 도 iOS 의 방법 을 조사 연 구 했 습 니 다.그들 은 시스템 을 호출 하 는 한 방법 으로 메시지 숫자 를 전달 하면 됩 니 다.안 드 로 이 드 가 방송 방식 을 통 해 삼 성과 마찬가지 입 니 다.
그렇다면 샤 오 미 는 어떻게 누 적 된 것 일 까?
전역 변수 count 를 정의 하고 초기 값 을 1 로 설정 한 다음 알림 을 보 낸 후 count 값 을 수 동 으로 변경 합 니 다.count=count+1.
우정 링크:
https://github.com/lixiangers/BadgeUtil
이상 은 본 고의 모든 내용 입 니 다.본 고의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.또한 저 희 를 많이 지지 해 주시 기 바 랍 니 다!

좋은 웹페이지 즐겨찾기