├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── sjl │ │ └── badger │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── sjl │ │ │ └── badger │ │ │ ├── AnotherActivity.java │ │ │ ├── App.java │ │ │ ├── AppUtil.java │ │ │ ├── BadgerUtil.java │ │ │ └── MainActivity.java │ └── res │ │ ├── drawable │ │ └── ic_launcher.png │ │ ├── layout │ │ ├── activity_another.xml │ │ └── activity_main.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ └── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ └── test │ └── java │ └── com │ └── sjl │ └── badger │ └── ExampleUnitTest.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | build 4 | .idea 5 | /local.properties 6 | /.idea/workspace.xml 7 | /.idea/libraries 8 | .DS_Store 9 | /build 10 | /captures 11 | .externalNativeBuild 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Badger 2 | 实现部分Android桌面角标Badge,并提供相关资料链接 3 | 4 | ### 相关资料 5 | #### [华为角标官方文档](https://developer.huawei.com/consumer/cn/devservice/doc/30802) 6 | 华为还是蛮不错的提供了角标的详细使用,但不要忘了添加权限。 7 | 8 | 9 | 注:关于华为文档链接可能失效的问题,到华为开发者页面搜索角标,能找到华为角标开发指南书。 10 | 11 | 12 | #### [小米角标官方文档](https://dev.mi.com/console/doc/detail?pId=939) 13 | 小米做的也挺厚道,在开放平台上搜索就能找到角标的使用,但仍存在两个问题。 14 | #### [联想ZUK官方文档](http://developer.zuk.com/detail/12) 15 | 虽然在市面上占的手机份额不是很多,但却也给出了详细的使用角标的方法。 16 | #### [索尼官方文档](https://github.com/sonyxperiadev/home-badge) 17 | 索尼官方给出的有点麻烦,官网搜索badge之后看了好几个答案才发现了官方使用方法。 18 | #### [谷歌官方文档](https://developer.android.com/training/notify-user/badges.html) 19 | 这是Android8.0新添加的,但也仅仅是圆点,没有数字颜色也不受控制。 20 | 21 | ### 详细说明 22 | [博客](https://blog.csdn.net/q1113225201/article/details/79858032) -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 26 5 | defaultConfig { 6 | applicationId "com.sjl.badger" 7 | minSdkVersion 16 8 | targetSdkVersion 26 9 | versionCode 1 10 | versionName "1.0" 11 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 12 | } 13 | buildTypes { 14 | release { 15 | minifyEnabled false 16 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 17 | } 18 | } 19 | } 20 | 21 | dependencies { 22 | implementation fileTree(include: ['*.jar'], dir: 'libs') 23 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 24 | testImplementation 'junit:junit:4.12' 25 | androidTestImplementation 'com.android.support.test:runner:1.0.1' 26 | androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.1' 27 | implementation 'com.android.support:appcompat-v7:26.1.0' 28 | } 29 | -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/sjl/badger/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package com.sjl.badger; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumented test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("com.sjl.badger", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/badger/AnotherActivity.java: -------------------------------------------------------------------------------- 1 | package com.sjl.badger; 2 | 3 | import android.app.Activity; 4 | import android.os.Bundle; 5 | 6 | public class AnotherActivity extends Activity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | setContentView(R.layout.activity_another); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/badger/App.java: -------------------------------------------------------------------------------- 1 | package com.sjl.badger; 2 | 3 | import android.app.Activity; 4 | import android.app.Application; 5 | import android.os.Bundle; 6 | 7 | /** 8 | * App 9 | * 10 | * @author 林zero 11 | * @date 2018/4/9 12 | */ 13 | 14 | public class App extends Application implements Application.ActivityLifecycleCallbacks { 15 | public static int count = 0; 16 | @Override 17 | public void onCreate() { 18 | super.onCreate(); 19 | registerActivityLifecycleCallbacks(this); 20 | } 21 | 22 | @Override 23 | public void onActivityCreated(Activity activity, Bundle savedInstanceState) { 24 | 25 | } 26 | 27 | @Override 28 | public void onActivityStarted(Activity activity) { 29 | 30 | } 31 | 32 | @Override 33 | public void onActivityResumed(Activity activity) { 34 | 35 | } 36 | 37 | @Override 38 | public void onActivityPaused(Activity activity) { 39 | 40 | } 41 | 42 | @Override 43 | public void onActivityStopped(Activity activity) { 44 | if(AppUtil.isBackground(this)) { 45 | BadgerUtil.addBadger(this, count); 46 | } 47 | } 48 | 49 | @Override 50 | public void onActivitySaveInstanceState(Activity activity, Bundle outState) { 51 | 52 | } 53 | 54 | @Override 55 | public void onActivityDestroyed(Activity activity) { 56 | 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/badger/AppUtil.java: -------------------------------------------------------------------------------- 1 | package com.sjl.badger; 2 | 3 | import android.app.ActivityManager; 4 | import android.app.usage.UsageStats; 5 | import android.app.usage.UsageStatsManager; 6 | import android.content.ClipData; 7 | import android.content.ClipboardManager; 8 | import android.content.Context; 9 | import android.content.Intent; 10 | import android.content.pm.ApplicationInfo; 11 | import android.content.pm.PackageManager; 12 | import android.content.pm.ResolveInfo; 13 | import android.graphics.Point; 14 | import android.os.Build; 15 | import android.util.Log; 16 | import android.view.WindowManager; 17 | 18 | import java.lang.reflect.Field; 19 | import java.util.ArrayList; 20 | import java.util.List; 21 | import java.util.SortedMap; 22 | import java.util.TreeMap; 23 | 24 | import static android.content.Context.CLIPBOARD_SERVICE; 25 | 26 | /** 27 | * App常用工具 28 | * 29 | * @author SJL 30 | * @date 2016/11/21 21:33 31 | */ 32 | public class AppUtil { 33 | /** 34 | * 判断当前应用是否是后台运行 35 | * @param context 36 | * @return 37 | */ 38 | public static boolean isBackground(Context context) { 39 | ActivityManager activityManager = (ActivityManager) context.getSystemService(Context.ACTIVITY_SERVICE); 40 | String packname = null; 41 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { 42 | //5.0之后getRunningTasks废弃 43 | //当前程序是否前台运行 44 | //详见ActivityManager.START_TASK_TO_FRONT(hide),前台任务 45 | int START_TASK_TO_FRONT = 2; 46 | Field field = null; 47 | try { 48 | field = ActivityManager.RunningAppProcessInfo.class.getField("processState"); 49 | } catch (NoSuchFieldException e) { 50 | e.printStackTrace(); 51 | } 52 | List runningAppProcessInfoList = activityManager.getRunningAppProcesses(); 53 | for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfoList) { 54 | if (runningAppProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) { 55 | //如果当前是运行在前台的UI 56 | try { 57 | Integer processState = field.getInt(runningAppProcessInfo); 58 | if (START_TASK_TO_FRONT == processState) { 59 | packname = runningAppProcessInfo.processName; 60 | } 61 | } catch (Exception e) { 62 | e.printStackTrace(); 63 | } 64 | } 65 | } 66 | } else { 67 | //5.0之前可直接使用getRunningTasks 68 | // 69 | List runningTaskInfoList = activityManager.getRunningTasks(1); 70 | packname = runningTaskInfoList.get(0).topActivity.getPackageName(); 71 | } 72 | return !context.getPackageName().equals(packname); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/badger/BadgerUtil.java: -------------------------------------------------------------------------------- 1 | package com.sjl.badger; 2 | 3 | import android.app.Notification; 4 | import android.app.NotificationChannel; 5 | import android.app.NotificationManager; 6 | import android.content.AsyncQueryHandler; 7 | import android.content.ComponentName; 8 | import android.content.ContentResolver; 9 | import android.content.ContentValues; 10 | import android.content.Context; 11 | import android.content.Intent; 12 | import android.content.pm.PackageManager; 13 | import android.content.pm.ResolveInfo; 14 | import android.database.Cursor; 15 | import android.net.Uri; 16 | import android.os.Build; 17 | import android.os.Bundle; 18 | import android.os.Handler; 19 | import android.support.v4.app.NotificationCompat; 20 | import android.text.TextUtils; 21 | import android.util.Log; 22 | 23 | import java.lang.reflect.Field; 24 | import java.lang.reflect.Method; 25 | import java.util.List; 26 | 27 | /** 28 | * BadgerUtil 29 | * 30 | * @author 林zero 31 | * @date 2018/3/29 32 | */ 33 | 34 | public class BadgerUtil { 35 | private static final String TAG = "BadgerUtil"; 36 | private static final int NOTIFY_ID = 10; 37 | 38 | public static void addBadger(Context context, int badgeCount) { 39 | if (TextUtils.isEmpty(getLauncherClassName(context))) { 40 | Log.e(TAG, "launcherClassName==null"); 41 | return; 42 | } 43 | 44 | badgeCount = Math.min(Math.abs(badgeCount), 99); 45 | String manufacturer = Build.MANUFACTURER.toLowerCase(); 46 | if (TextUtils.isEmpty(manufacturer)) { 47 | return; 48 | } 49 | if (manufacturer.contains("huawei")) { 50 | badgeHuawei(context, badgeCount); 51 | } else if (manufacturer.contains("xiaomi")) { 52 | badgeXiaomi(context, badgeCount); 53 | } else if (manufacturer.contains("sony")) { 54 | badgeSony(context, badgeCount); 55 | } else if (manufacturer.contains("zuk")) { 56 | badgeZuk(context, badgeCount); 57 | } else if (manufacturer.contains("samsung")) { 58 | badgeSamsung(context, badgeCount); 59 | } else if (manufacturer.contains("htc")) { 60 | badgeHtc(context, badgeCount); 61 | } else if (manufacturer.contains("vivo")) { 62 | badgeVivo(context, badgeCount); 63 | } else if (manufacturer.contains("oppo")) { 64 | badgeOppo(context, badgeCount); 65 | } else { 66 | badgeDefault(context, badgeCount); 67 | } 68 | } 69 | 70 | /** 71 | * 默认 72 | */ 73 | private static void badgeDefault(Context context, int badgeCount) { 74 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 75 | Notification notification = BadgerUtil.getNotification(context, badgeCount); 76 | BadgerUtil.notify(notification, badgeCount); 77 | } else { 78 | //参考其他开发者写法,不一定有效 79 | try { 80 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); 81 | intent.putExtra("badge_count", badgeCount); 82 | intent.putExtra("badge_count_package_name", context.getPackageName()); 83 | intent.putExtra("badge_count_class_name", launcherClassName); 84 | context.sendBroadcast(intent); 85 | } catch (Exception e) { 86 | 87 | } 88 | } 89 | } 90 | 91 | private static NotificationManager notificationManager; 92 | 93 | private static Notification getNotification(Context context, int badgeCount) { 94 | if (notificationManager == null) { 95 | notificationManager = ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)); 96 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { 97 | //8.0之后添加角标需要NotificationChannel 98 | NotificationChannel channel = new NotificationChannel("badge", "badge", NotificationManager.IMPORTANCE_LOW); 99 | channel.setShowBadge(true); 100 | ((NotificationManager) context.getSystemService(Context.NOTIFICATION_SERVICE)).createNotificationChannel(channel); 101 | } 102 | } 103 | 104 | Notification notification = new NotificationCompat.Builder(context, "badge") 105 | .setContentTitle("通知") 106 | .setContentText("新消息") 107 | .setSmallIcon(R.drawable.ic_launcher) 108 | .setBadgeIconType(NotificationCompat.BADGE_ICON_SMALL) 109 | .setNumber(badgeCount) 110 | .setAutoCancel(true) 111 | .build(); 112 | return notification; 113 | } 114 | 115 | /** 116 | * 发送通知 117 | */ 118 | private static void notify(Notification notification, int badgeCount) { 119 | notificationManager.cancel(TAG, NOTIFY_ID); 120 | if (badgeCount > 0) { 121 | notificationManager.notify(TAG, NOTIFY_ID, notification); 122 | } 123 | } 124 | 125 | /** 126 | * HTC 127 | */ 128 | private static void badgeHtc(Context context, int badgeCount) { 129 | try { 130 | Intent intent = new Intent("android.intent.action.BADGE_COUNT_UPDATE"); 131 | intent.putExtra("badge_count", badgeCount); 132 | intent.putExtra("badge_count_package_name", context.getPackageName()); 133 | intent.putExtra("badge_count_class_name", launcherClassName); 134 | context.sendBroadcast(intent); 135 | } catch (Exception e) { 136 | 137 | } 138 | } 139 | 140 | /** 141 | * QQ反编译获得,实际使用中需要在oppo开发者平台审核通过 142 | */ 143 | private static void badgeOppo(Context context, int badgeCount) { 144 | try { 145 | Bundle extras = new Bundle(); 146 | extras.putInt("app_badge_count", badgeCount); 147 | context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extras); 148 | } catch (Exception e) { 149 | badgeDefault(context, badgeCount); 150 | } 151 | } 152 | 153 | /** 154 | * 联想ZUK权限 155 | * 156 | */ 157 | private static void badgeZuk(Context context, int badgeCount) { 158 | Bundle extra = new Bundle(); 159 | extra.putInt("app_badge_count", badgeCount); 160 | context.getContentResolver().call(Uri.parse("content://com.android.badge/badge"), "setAppBadgeCount", null, extra); 161 | } 162 | 163 | /** 164 | * 三星权限 165 | * 166 | * 167 | */ 168 | private static void badgeSamsung(Context context, int badgeCount) { 169 | Uri uri = Uri.parse("content://com.sec.badge/apps"); 170 | String columnId = "_id"; 171 | String columnPackage = "package"; 172 | String columnClass = "class"; 173 | String columnBadgeCount = "badgeCount"; 174 | Cursor cursor = null; 175 | try { 176 | ContentResolver contentResolver = context.getContentResolver(); 177 | cursor = contentResolver.query(uri, new String[]{columnId}, columnPackage + "=?", new String[]{context.getPackageName()}, null); 178 | 179 | if (cursor == null || !cursor.moveToFirst()) { 180 | ContentValues contentValues = new ContentValues(); 181 | contentValues.put(columnPackage, context.getPackageName()); 182 | contentValues.put(columnClass, launcherClassName); 183 | contentValues.put(columnBadgeCount, badgeCount); 184 | contentResolver.insert(uri, contentValues); 185 | } else { 186 | int idColumnIndex = cursor.getColumnIndex(columnId); 187 | 188 | ContentValues contentValues = new ContentValues(); 189 | contentValues.put(columnBadgeCount, badgeCount); 190 | contentResolver.update(uri, contentValues, columnId + "=?", new String[]{String.valueOf(cursor.getInt(idColumnIndex))}); 191 | } 192 | } catch (Exception e) { 193 | badgeDefault(context, badgeCount); 194 | } finally { 195 | if (cursor != null) { 196 | cursor.close(); 197 | } 198 | } 199 | } 200 | 201 | private static AsyncQueryHandler asyncQueryHandler; 202 | 203 | /** 204 | * 索尼权限 205 | * 206 | * 207 | * 208 | */ 209 | private static void badgeSony(Context context, int badgeCount) { 210 | if (asyncQueryHandler == null) { 211 | asyncQueryHandler = new AsyncQueryHandler(context.getContentResolver()) { 212 | }; 213 | } 214 | try { 215 | //官方给出方法 216 | ContentValues contentValues = new ContentValues(); 217 | contentValues.put("badge_count", badgeCount); 218 | contentValues.put("package_name", context.getPackageName()); 219 | contentValues.put("activity_name", launcherClassName); 220 | asyncQueryHandler.startInsert(0, null, Uri.parse("content://com.sonymobile.home.resourceprovider/badge"), contentValues); 221 | } catch (Exception e) { 222 | //网上大部分使用方法 223 | Intent intent = new Intent("com.sonyericsson.home.action.UPDATE_BADGE"); 224 | intent.putExtra("com.sonyericsson.home.intent.extra.badge.SHOW_MESSAGE", badgeCount > 0); 225 | intent.putExtra("com.sonyericsson.home.intent.extra.badge.ACTIVITY_NAME", launcherClassName); 226 | intent.putExtra("com.sonyericsson.home.intent.extra.badge.MESSAGE", String.valueOf(badgeCount > 0 ? badgeCount : "")); 227 | intent.putExtra("com.sonyericsson.home.intent.extra.badge.PACKAGE_NAME", context.getPackageName()); 228 | context.sendBroadcast(intent); 229 | } 230 | } 231 | 232 | /** 233 | * 小米 234 | * 小米手机如果在app内或未清理掉之前通知情况下执行添加角标操作,已显示的角标会消失 235 | * 解决方案是清理掉之前发送的通知,并在app退到后台的时候执行添加角标操作 236 | */ 237 | private static void badgeXiaomi(final Context context, final int badgeCount) { 238 | new Handler().postDelayed(new Runnable() { 239 | @Override 240 | public void run() { 241 | //延迟1秒是为了避免执行操作的时候还在app内,如要真正避免还是需要控制调用的时机 242 | try { 243 | Notification notification = BadgerUtil.getNotification(context, badgeCount); 244 | Field field = notification.getClass().getDeclaredField("extraNotification"); 245 | Object extraNotification = field.get(notification); 246 | Method method = extraNotification.getClass().getDeclaredMethod("setMessageCount", int.class); 247 | method.invoke(extraNotification, badgeCount); 248 | BadgerUtil.notify(notification, badgeCount); 249 | } catch (Exception e) { 250 | e.printStackTrace(); 251 | // 网上找的据说是miui 6之前的版本,没有miui6之前版本的小米手机不知道有没有效 252 | Intent localIntent = new Intent("android.intent.action.APPLICATION_MESSAGE_UPDATE"); 253 | localIntent.putExtra("android.intent.extra.update_application_component_name", context.getPackageName() + "/" + getLauncherClassName(context)); 254 | localIntent.putExtra("android.intent.extra.update_application_message_text", String.valueOf(badgeCount == 0 ? "" : badgeCount)); 255 | context.sendBroadcast(localIntent); 256 | } 257 | } 258 | }, 1000); 259 | } 260 | 261 | /** 262 | * vivo 263 | * 据说有用,但在部分vivo手机上不显示,如x6s 264 | * 包名改成QQ或微信的就能显示角标 265 | */ 266 | private static void badgeVivo(Context context, int badgeCount) { 267 | Intent intent = new Intent("launcher.action.CHANGE_APPLICATION_NOTIFICATION_NUM"); 268 | intent.putExtra("packageName", context.getPackageName()); 269 | intent.putExtra("className", launcherClassName); 270 | intent.putExtra("notificationNum", badgeCount); 271 | context.sendBroadcast(intent); 272 | } 273 | 274 | /** 275 | * 华为权限 276 | * 277 | * 278 | */ 279 | private static void badgeHuawei(Context context, int badgeCount) { 280 | try { 281 | Bundle bunlde = new Bundle(); 282 | bunlde.putString("package", context.getPackageName()); 283 | bunlde.putString("class", launcherClassName); 284 | bunlde.putInt("badgenumber", badgeCount); 285 | context.getContentResolver().call(Uri.parse("content://com.huawei.android.launcher.settings/badge/"), "change_badge", null, bunlde); 286 | } catch (Exception e) { 287 | Log.e(TAG, e.getMessage()); 288 | } 289 | } 290 | 291 | private static String launcherClassName; 292 | 293 | private static String getLauncherClassName(Context context) { 294 | if (!TextUtils.isEmpty(launcherClassName)) { 295 | return launcherClassName; 296 | } 297 | Intent intent = new Intent(Intent.ACTION_MAIN); 298 | intent.addCategory(Intent.CATEGORY_LAUNCHER); 299 | PackageManager packageManager = context.getPackageManager(); 300 | List resolveInfoList = packageManager.queryIntentActivities(intent, 0); 301 | for (ResolveInfo resolveInfo : resolveInfoList) { 302 | if (context != null && context.getPackageName().equalsIgnoreCase(resolveInfo.activityInfo.applicationInfo.packageName)) { 303 | launcherClassName = resolveInfo.activityInfo.name; 304 | break; 305 | } 306 | } 307 | return launcherClassName; 308 | } 309 | } 310 | -------------------------------------------------------------------------------- /app/src/main/java/com/sjl/badger/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.sjl.badger; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.View; 7 | import android.widget.EditText; 8 | import android.widget.Toast; 9 | 10 | public class MainActivity extends Activity { 11 | private EditText etNum; 12 | 13 | @Override 14 | protected void onCreate(Bundle savedInstanceState) { 15 | super.onCreate(savedInstanceState); 16 | setContentView(R.layout.activity_main); 17 | etNum = findViewById(R.id.etNum); 18 | } 19 | 20 | public void addBadger(View view) { 21 | try { 22 | App.count = Math.abs(Integer.valueOf(etNum.getText().toString())); 23 | }catch (Exception e){ 24 | Toast.makeText(this,"请输入正整数",Toast.LENGTH_SHORT).show(); 25 | } 26 | } 27 | 28 | public void jump(View view){ 29 | startActivity(new Intent(this,AnotherActivity.class)); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/q1113225201/Badger/92630599f20e7942257b31b9665ec2e72fedc62b/app/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_another.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 15 | 16 |