Repository: Blankj/AndroidUtilCode Branch: master Commit: 7b4caf9e5440 Files: 661 Total size: 3.0 MB Directory structure: gitextract_m5v2g_mv/ ├── .github/ │ ├── FUNDING.yml │ ├── ISSUE_TEMPLATE/ │ │ ├── bug_report.md │ │ ├── bug_report_cn.md │ │ ├── feature-request.md │ │ └── feature-request_cn.md │ └── workflows/ │ └── android.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README-CN.md ├── README.md ├── build.gradle ├── buildApp.gradle ├── buildCommon.gradle ├── buildLib.gradle ├── buildSrc/ │ ├── .gitignore │ ├── build.gradle │ ├── settings.gradle │ └── src/ │ └── main/ │ ├── groovy/ │ │ ├── Config.groovy │ │ ├── ConfigUtils.groovy │ │ ├── GLog.groovy │ │ ├── LibConfig.groovy │ │ ├── ModuleConfig.groovy │ │ ├── PluginConfig.groovy │ │ └── TaskDurationUtils.groovy │ └── java/ │ └── com/ │ └── blankj/ │ └── plugin/ │ └── readme/ │ ├── FormatUtils.groovy │ ├── ReadmeCorePlugin.groovy │ ├── ReadmeExtension.groovy │ └── ReadmeSubPlugin.groovy ├── config/ │ ├── flavor.gradle │ └── publish.gradle ├── feature/ │ ├── launcher/ │ │ └── app/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── launcher/ │ │ └── app/ │ │ └── LauncherApp.java │ ├── main/ │ │ ├── app/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── main/ │ │ │ └── app/ │ │ │ └── MainApp.java │ │ └── pkg/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── main/ │ │ │ └── pkg/ │ │ │ ├── MainActivity.kt │ │ │ └── SplashActivity.kt │ │ └── res/ │ │ ├── layout/ │ │ │ └── activity_main.xml │ │ └── values/ │ │ └── strings.xml │ ├── mock/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── mock/ │ │ ├── subutil/ │ │ │ └── SubUtilApiMock.java │ │ └── utilcode/ │ │ └── UtilCodeApiMock.java │ ├── subutil/ │ │ ├── app/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── subutil/ │ │ │ └── app/ │ │ │ └── SubUtilApp.kt │ │ ├── export/ │ │ │ ├── .gitignore │ │ │ ├── build.gradle │ │ │ ├── proguard-rules.pro │ │ │ └── src/ │ │ │ └── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── subutil/ │ │ │ └── export/ │ │ │ └── api/ │ │ │ └── SubUtilApi.java │ │ └── pkg/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── subutil/ │ │ │ └── pkg/ │ │ │ ├── Config.kt │ │ │ ├── SubUtilApiImpl.java │ │ │ └── feature/ │ │ │ ├── SubUtilActivity.kt │ │ │ ├── appStore/ │ │ │ │ └── AppStoreActivity.kt │ │ │ ├── battery/ │ │ │ │ └── BatteryActivity.kt │ │ │ ├── country/ │ │ │ │ └── CountryActivity.kt │ │ │ ├── dangerous/ │ │ │ │ └── DangerousActivity.kt │ │ │ ├── location/ │ │ │ │ ├── LocationActivity.kt │ │ │ │ └── LocationService.kt │ │ │ └── pinyin/ │ │ │ └── PinyinActivity.kt │ │ └── res/ │ │ └── values/ │ │ └── strings.xml │ └── utilcode/ │ ├── app/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── utilcode/ │ │ └── app/ │ │ └── UtilCodeApp.kt │ ├── export/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── utilcode/ │ │ └── export/ │ │ └── api/ │ │ └── UtilCodeApi.java │ └── pkg/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ └── test/ │ │ ├── sub/ │ │ │ └── test.txt │ │ └── test.txt │ ├── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── utilcode/ │ │ └── pkg/ │ │ ├── Config.kt │ │ ├── UtilCodeApiImpl.java │ │ ├── feature/ │ │ │ ├── CoreUtilActivity.kt │ │ │ ├── activity/ │ │ │ │ ├── ActivityActivity.kt │ │ │ │ └── SubActivityActivity.kt │ │ │ ├── adaptScreen/ │ │ │ │ ├── AdaptCloseActivity.kt │ │ │ │ ├── AdaptHeightActivity.kt │ │ │ │ ├── AdaptScreenActivity.kt │ │ │ │ └── AdaptWidthActivity.kt │ │ │ ├── api/ │ │ │ │ ├── ApiActivity.kt │ │ │ │ └── other/ │ │ │ │ ├── export/ │ │ │ │ │ └── OtherModuleApi.java │ │ │ │ └── pkg/ │ │ │ │ └── OtherPkgApiImpl.java │ │ │ ├── app/ │ │ │ │ └── AppActivity.kt │ │ │ ├── bar/ │ │ │ │ ├── BarActivity.kt │ │ │ │ ├── nav/ │ │ │ │ │ └── BarNavActivity.kt │ │ │ │ ├── notification/ │ │ │ │ │ └── BarNotificationActivity.kt │ │ │ │ └── status/ │ │ │ │ ├── BarStatusActivity.kt │ │ │ │ ├── BarStatusActivityAlpha.kt │ │ │ │ ├── BarStatusActivityColor.kt │ │ │ │ ├── BarStatusActivityCustom.kt │ │ │ │ ├── BarStatusActivityDrawer.kt │ │ │ │ ├── BarStatusActivityImageView.kt │ │ │ │ └── fragment/ │ │ │ │ ├── BarStatusFragmentActivity.kt │ │ │ │ ├── BarStatusFragmentAlpha.kt │ │ │ │ ├── BarStatusFragmentColor.kt │ │ │ │ ├── BarStatusFragmentCustom.kt │ │ │ │ └── BarStatusFragmentImageView.kt │ │ │ ├── brightness/ │ │ │ │ └── BrightnessActivity.kt │ │ │ ├── bus/ │ │ │ │ ├── BusActivity.kt │ │ │ │ └── BusCompareActivity.kt │ │ │ ├── clean/ │ │ │ │ └── CleanActivity.kt │ │ │ ├── click/ │ │ │ │ └── ClickActivity.kt │ │ │ ├── clipboard/ │ │ │ │ └── ClipboardActivity.kt │ │ │ ├── device/ │ │ │ │ └── DeviceActivity.kt │ │ │ ├── file/ │ │ │ │ └── FileActivity.kt │ │ │ ├── flashlight/ │ │ │ │ └── FlashlightActivity.kt │ │ │ ├── fragment/ │ │ │ │ ├── ChildFragment.kt │ │ │ │ ├── ContainerFragment.kt │ │ │ │ ├── FragmentActivity.kt │ │ │ │ └── RootFragment.kt │ │ │ ├── image/ │ │ │ │ └── ImageActivity.kt │ │ │ ├── intent/ │ │ │ │ └── IntentActivity.kt │ │ │ ├── keyboard/ │ │ │ │ └── KeyboardActivity.kt │ │ │ ├── language/ │ │ │ │ └── LanguageActivity.kt │ │ │ ├── log/ │ │ │ │ └── LogActivity.kt │ │ │ ├── messenger/ │ │ │ │ ├── MessengerActivity.kt │ │ │ │ └── MessengerRemoteActivity.kt │ │ │ ├── metaData/ │ │ │ │ └── MetaDataActivity.kt │ │ │ ├── mvp/ │ │ │ │ ├── MvpActivity.java │ │ │ │ ├── MvpModel.java │ │ │ │ ├── MvpMvp.java │ │ │ │ ├── MvpPresenter.java │ │ │ │ └── MvpView.java │ │ │ ├── network/ │ │ │ │ └── NetworkActivity.kt │ │ │ ├── notification/ │ │ │ │ └── NotificationActivity.kt │ │ │ ├── path/ │ │ │ │ └── PathActivity.kt │ │ │ ├── permission/ │ │ │ │ └── PermissionActivity.kt │ │ │ ├── phone/ │ │ │ │ └── PhoneActivity.kt │ │ │ ├── process/ │ │ │ │ └── ProcessActivity.kt │ │ │ ├── reflect/ │ │ │ │ ├── ReflectActivity.kt │ │ │ │ └── TestPrivateStaticFinal.java │ │ │ ├── resource/ │ │ │ │ └── ResourceActivity.kt │ │ │ ├── rom/ │ │ │ │ └── RomActivity.kt │ │ │ ├── screen/ │ │ │ │ └── ScreenActivity.kt │ │ │ ├── sdcard/ │ │ │ │ └── SDCardActivity.kt │ │ │ ├── shadow/ │ │ │ │ └── ShadowActivity.kt │ │ │ ├── snackbar/ │ │ │ │ └── SnackbarActivity.kt │ │ │ ├── spStatic/ │ │ │ │ └── SPStaticActivity.kt │ │ │ ├── span/ │ │ │ │ └── SpanActivity.kt │ │ │ ├── toast/ │ │ │ │ ├── CustomToast.kt │ │ │ │ └── ToastActivity.kt │ │ │ ├── uiMessage/ │ │ │ │ └── UiMessageActivity.kt │ │ │ ├── vibrate/ │ │ │ │ └── VibrateActivity.kt │ │ │ └── volume/ │ │ │ └── VolumeActivity.kt │ │ └── helper/ │ │ └── DialogHelper.kt │ └── res/ │ ├── anim/ │ │ ├── fade_in_1000.xml │ │ ├── fade_out_1000.xml │ │ ├── slide_bottom_in_200.xml │ │ ├── slide_bottom_out_200.xml │ │ ├── slide_left_out_1000.xml │ │ └── slide_right_in_1000.xml │ ├── animator/ │ │ ├── fragment_slide_left_enter.xml │ │ ├── fragment_slide_left_exit.xml │ │ ├── fragment_slide_right_enter.xml │ │ └── fragment_slide_right_exit.xml │ ├── drawable/ │ │ ├── bar_status_custom.xml │ │ ├── bar_status_nav_alpha.xml │ │ ├── bar_status_nav_color.xml │ │ ├── bar_status_nav_custom.xml │ │ ├── bar_status_nav_image.xml │ │ ├── fragment_nav.xml │ │ ├── keyboard_dialog_bg.xml │ │ ├── shadow_circle.xml │ │ ├── shadow_round_rect.xml │ │ ├── snackbar_custom_bg.xml │ │ ├── span_block_high.xml │ │ ├── span_block_low.xml │ │ └── toast_round_rect.xml │ ├── layout/ │ │ ├── activity_adaptscreen.xml │ │ ├── activity_item_shared_element_activity.xml │ │ ├── activity_sub_activity.xml │ │ ├── adaptscreen_close_activity.xml │ │ ├── adaptscreen_height_activity.xml │ │ ├── adaptscreen_width_activity.xml │ │ ├── bar_status_alpha_activity.xml │ │ ├── bar_status_alpha_fragment.xml │ │ ├── bar_status_color_fragment.xml │ │ ├── bar_status_custom_fragment.xml │ │ ├── bar_status_drawer_activity.xml │ │ ├── bar_status_fragment_activity.xml │ │ ├── bar_status_image_view_activity.xml │ │ ├── bar_status_image_view_fragment.xml │ │ ├── fragment_activity.xml │ │ ├── fragment_child.xml │ │ ├── fragment_container.xml │ │ ├── fragment_dialog.xml │ │ ├── fragment_item_shared_element.xml │ │ ├── fragment_root.xml │ │ ├── keyboard_activity.xml │ │ ├── keyboard_dialog.xml │ │ ├── mvp_activity.xml │ │ ├── screen_dialog.xml │ │ ├── shadow_activity.xml │ │ ├── snackbar_custom.xml │ │ ├── span_activity.xml │ │ ├── toast_custom.xml │ │ └── toast_dialog.xml │ ├── menu/ │ │ ├── fragment_nav.xml │ │ └── status_bar_nav.xml │ ├── raw/ │ │ └── test.txt │ ├── transition/ │ │ ├── explode_1000.xml │ │ ├── fade_1000.xml │ │ └── slide_1000.xml │ ├── values/ │ │ ├── ids.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── values-en-rUS/ │ │ └── strings.xml │ └── values-zh-rCN/ │ └── strings.xml ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradle.properties ├── gradlew ├── gradlew.bat ├── lib/ │ ├── base/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── base/ │ │ │ ├── BaseActivity.java │ │ │ ├── BaseApplication.java │ │ │ ├── BaseFragment.java │ │ │ ├── IBaseView.java │ │ │ ├── dialog/ │ │ │ │ ├── BaseDialog.java │ │ │ │ ├── BaseDialogFragment.java │ │ │ │ ├── DialogCallback.java │ │ │ │ └── DialogLayoutCallback.java │ │ │ ├── mvp/ │ │ │ │ ├── BaseModel.java │ │ │ │ ├── BasePresenter.java │ │ │ │ └── BaseView.java │ │ │ ├── rv/ │ │ │ │ ├── BaseItem.java │ │ │ │ ├── BaseItemAdapter.java │ │ │ │ ├── ItemViewHolder.java │ │ │ │ └── RecycleViewDivider.java │ │ │ └── view/ │ │ │ └── EmptyGoneTextView.java │ │ └── res/ │ │ └── layout/ │ │ ├── activity_back.xml │ │ └── fragment_lazy.xml │ ├── common/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── assets/ │ │ │ └── test_install │ │ ├── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── common/ │ │ │ ├── CommonApplication.java │ │ │ ├── activity/ │ │ │ │ ├── CommonActivity.java │ │ │ │ ├── CommonActivityDrawerView.java │ │ │ │ ├── CommonActivityItemsView.java │ │ │ │ └── CommonActivityTitleView.java │ │ │ ├── dialog/ │ │ │ │ ├── CommonDialogContent.java │ │ │ │ └── CommonDialogLoading.java │ │ │ ├── fragment/ │ │ │ │ └── CommonFragment.java │ │ │ ├── helper/ │ │ │ │ └── PermissionHelper.kt │ │ │ ├── item/ │ │ │ │ ├── CommonItem.java │ │ │ │ ├── CommonItemClick.java │ │ │ │ ├── CommonItemImage.java │ │ │ │ ├── CommonItemSeekBar.java │ │ │ │ ├── CommonItemSwitch.java │ │ │ │ └── CommonItemTitle.java │ │ │ └── view/ │ │ │ └── RotateView.java │ │ └── res/ │ │ ├── anim/ │ │ │ ├── slide_in_left.xml │ │ │ ├── slide_in_right.xml │ │ │ ├── slide_out_left.xml │ │ │ └── slide_out_right.xml │ │ ├── drawable/ │ │ │ ├── common_button_bg.xml │ │ │ ├── common_button_txt_color.xml │ │ │ ├── common_content_dialog_bg.xml │ │ │ ├── common_content_dialog_btn_bg.xml │ │ │ ├── common_item_divider.xml │ │ │ ├── common_loading_bg.xml │ │ │ ├── common_rotate_loading.xml │ │ │ ├── common_scrollbar_thumb.xml │ │ │ ├── common_seekbar_progress.xml │ │ │ ├── common_seekbar_thumb.xml │ │ │ ├── common_splash.xml │ │ │ ├── main_menu_blog.xml │ │ │ └── main_menu_github.xml │ │ ├── drawable-xxhdpi/ │ │ │ ├── common_switch_thumb.xml │ │ │ └── common_switch_track.xml │ │ ├── layout/ │ │ │ ├── common_activity_drawer.xml │ │ │ ├── common_activity_drawer_nav_header.xml │ │ │ ├── common_activity_title.xml │ │ │ ├── common_activity_title_stub_no_scroll.xml │ │ │ ├── common_activity_title_stub_scroll.xml │ │ │ ├── common_dialog_content.xml │ │ │ ├── common_dialog_loading.xml │ │ │ ├── common_item.xml │ │ │ ├── common_item_title_click.xml │ │ │ ├── common_item_title_content.xml │ │ │ ├── common_item_title_image.xml │ │ │ ├── common_item_title_seekbar.xml │ │ │ └── common_item_title_switch.xml │ │ ├── menu/ │ │ │ └── common_drawer.xml │ │ └── values/ │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── strings.xml │ │ └── styles.xml │ ├── subutil/ │ │ ├── .gitignore │ │ ├── README-CN.md │ │ ├── README.md │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── subutil/ │ │ │ └── util/ │ │ │ ├── AppStoreUtils.java │ │ │ ├── BatteryUtils.java │ │ │ ├── BitUtils.java │ │ │ ├── CameraUtils.java │ │ │ ├── CoordinateUtils.java │ │ │ ├── CountryUtils.java │ │ │ ├── DangerousUtils.java │ │ │ ├── GlideUtils.java │ │ │ ├── HttpsUtil.java │ │ │ ├── LocationUtils.java │ │ │ ├── LunarUtils.java │ │ │ ├── PinyinUtils.java │ │ │ ├── RetrofitUtils.java │ │ │ ├── TemperatureUtils.java │ │ │ ├── Utils.java │ │ │ └── http/ │ │ │ ├── Chain.java │ │ │ ├── ExecutorFactory.java │ │ │ ├── Headers.java │ │ │ ├── HttpUtils.java │ │ │ ├── Interceptor.java │ │ │ ├── Request.java │ │ │ ├── Response.java │ │ │ ├── ResponseCallback.java │ │ │ └── SSLConfig.java │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── subutil/ │ │ └── util/ │ │ ├── BaseTest.java │ │ ├── CoordinateUtilsTest.java │ │ ├── LunarUtilsTest.java │ │ ├── TemperatureUtilsTest.java │ │ ├── TestConfig.java │ │ └── http/ │ │ ├── HttpUtilsTest.java │ │ └── UserBean.java │ ├── utilcode/ │ │ ├── .gitignore │ │ ├── README-CN.md │ │ ├── README.md │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ ├── main/ │ │ │ ├── AndroidManifest.xml │ │ │ ├── java/ │ │ │ │ └── com/ │ │ │ │ └── blankj/ │ │ │ │ └── utilcode/ │ │ │ │ ├── constant/ │ │ │ │ │ ├── CacheConstants.java │ │ │ │ │ ├── MemoryConstants.java │ │ │ │ │ ├── PermissionConstants.java │ │ │ │ │ ├── RegexConstants.java │ │ │ │ │ └── TimeConstants.java │ │ │ │ └── util/ │ │ │ │ ├── ActivityUtils.java │ │ │ │ ├── AdaptScreenUtils.java │ │ │ │ ├── ApiUtils.java │ │ │ │ ├── AppUtils.java │ │ │ │ ├── ArrayUtils.java │ │ │ │ ├── BarUtils.java │ │ │ │ ├── BrightnessUtils.java │ │ │ │ ├── BusUtils.java │ │ │ │ ├── CacheDiskStaticUtils.java │ │ │ │ ├── CacheDiskUtils.java │ │ │ │ ├── CacheDoubleStaticUtils.java │ │ │ │ ├── CacheDoubleUtils.java │ │ │ │ ├── CacheMemoryStaticUtils.java │ │ │ │ ├── CacheMemoryUtils.java │ │ │ │ ├── CleanUtils.java │ │ │ │ ├── ClickUtils.java │ │ │ │ ├── ClipboardUtils.java │ │ │ │ ├── CloneUtils.java │ │ │ │ ├── CloseUtils.java │ │ │ │ ├── CollectionUtils.java │ │ │ │ ├── ColorUtils.java │ │ │ │ ├── ConvertUtils.java │ │ │ │ ├── CrashUtils.java │ │ │ │ ├── DebouncingUtils.java │ │ │ │ ├── DeviceUtils.java │ │ │ │ ├── DialogUtils.java │ │ │ │ ├── EncodeUtils.java │ │ │ │ ├── EncryptUtils.java │ │ │ │ ├── FileIOUtils.java │ │ │ │ ├── FileUtils.java │ │ │ │ ├── FlashlightUtils.java │ │ │ │ ├── FragmentUtils.java │ │ │ │ ├── GsonUtils.java │ │ │ │ ├── ImageUtils.java │ │ │ │ ├── IntentUtils.java │ │ │ │ ├── JsonUtils.java │ │ │ │ ├── KeyboardUtils.java │ │ │ │ ├── LanguageUtils.java │ │ │ │ ├── LogUtils.java │ │ │ │ ├── MapUtils.java │ │ │ │ ├── MessengerUtils.java │ │ │ │ ├── MetaDataUtils.java │ │ │ │ ├── NetworkUtils.java │ │ │ │ ├── NotificationUtils.java │ │ │ │ ├── NumberUtils.java │ │ │ │ ├── ObjectUtils.java │ │ │ │ ├── PathUtils.java │ │ │ │ ├── PermissionUtils.java │ │ │ │ ├── PhoneUtils.java │ │ │ │ ├── ProcessUtils.java │ │ │ │ ├── ReflectUtils.java │ │ │ │ ├── RegexUtils.java │ │ │ │ ├── ResourceUtils.java │ │ │ │ ├── RomUtils.java │ │ │ │ ├── SDCardUtils.java │ │ │ │ ├── SPStaticUtils.java │ │ │ │ ├── SPUtils.java │ │ │ │ ├── ScreenUtils.java │ │ │ │ ├── ServiceUtils.java │ │ │ │ ├── ShadowUtils.java │ │ │ │ ├── ShellUtils.java │ │ │ │ ├── SizeUtils.java │ │ │ │ ├── SnackbarUtils.java │ │ │ │ ├── SpanUtils.java │ │ │ │ ├── StringUtils.java │ │ │ │ ├── ThreadUtils.java │ │ │ │ ├── ThrowableUtils.java │ │ │ │ ├── TimeUtils.java │ │ │ │ ├── ToastUtils.java │ │ │ │ ├── TouchUtils.java │ │ │ │ ├── UiMessageUtils.java │ │ │ │ ├── UriUtils.java │ │ │ │ ├── Utils.java │ │ │ │ ├── UtilsActivityLifecycleImpl.java │ │ │ │ ├── UtilsBridge.java │ │ │ │ ├── UtilsFileProvider.java │ │ │ │ ├── UtilsTransActivity.java │ │ │ │ ├── UtilsTransActivity4MainProcess.java │ │ │ │ ├── VibrateUtils.java │ │ │ │ ├── ViewUtils.java │ │ │ │ ├── VolumeUtils.java │ │ │ │ └── ZipUtils.java │ │ │ └── res/ │ │ │ ├── drawable/ │ │ │ │ └── utils_toast_bg.xml │ │ │ ├── layout/ │ │ │ │ └── utils_toast_view.xml │ │ │ ├── values/ │ │ │ │ └── styles.xml │ │ │ ├── values-v21/ │ │ │ │ └── styles.xml │ │ │ └── xml/ │ │ │ └── util_code_provider_paths.xml │ │ └── test/ │ │ ├── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── utilcode/ │ │ │ └── util/ │ │ │ ├── ApiUtilsTest.java │ │ │ ├── ArrayUtilsTest.java │ │ │ ├── BaseTest.java │ │ │ ├── BusUtilsTest.java │ │ │ ├── BusUtilsVsEventBusTest.java │ │ │ ├── CacheDiskStaticUtilsTest.java │ │ │ ├── CacheDiskUtilsTest.java │ │ │ ├── CacheDoubleStaticUtilsTest.java │ │ │ ├── CacheDoubleUtilsTest.java │ │ │ ├── CacheMemoryStaticUtilsTest.java │ │ │ ├── CacheMemoryUtilsTest.java │ │ │ ├── CloneUtilsTest.java │ │ │ ├── CollectionUtilsTest.java │ │ │ ├── ColorUtilsTest.java │ │ │ ├── ConvertUtilsTest.java │ │ │ ├── EncodeUtilsTest.java │ │ │ ├── EncryptUtilsTest.java │ │ │ ├── FileIOUtilsTest.java │ │ │ ├── FileUtilsTest.java │ │ │ ├── GsonUtilsTest.java │ │ │ ├── ImageUtilsTest.java │ │ │ ├── LogUtilsTest.java │ │ │ ├── MapUtilsTest.java │ │ │ ├── NumberUtilsTest.java │ │ │ ├── ObjectUtilsTest.java │ │ │ ├── PathUtilsTest.java │ │ │ ├── RegexUtilsTest.java │ │ │ ├── StringUtilsTest.java │ │ │ ├── TestConfig.java │ │ │ ├── ThreadUtilsTest.java │ │ │ ├── TimeUtilsTest.java │ │ │ ├── UiMessageUtilsTest.java │ │ │ ├── ZipUtilsTest.java │ │ │ └── reflect/ │ │ │ ├── PrivateConstructors.java │ │ │ ├── ReflectUtilsTest.java │ │ │ ├── Test1.java │ │ │ ├── Test10.java │ │ │ ├── Test2.java │ │ │ ├── Test3.java │ │ │ ├── Test4.java │ │ │ ├── Test5.java │ │ │ ├── Test6.java │ │ │ ├── Test7.java │ │ │ ├── Test8.java │ │ │ ├── Test9.java │ │ │ ├── TestHierarchicalMethodsBase.java │ │ │ ├── TestHierarchicalMethodsSubclass.java │ │ │ └── TestPrivateStaticFinal.java │ │ └── res/ │ │ ├── encrypt/ │ │ │ └── MD5.txt │ │ ├── file/ │ │ │ ├── GBK.txt │ │ │ ├── UTF16BE.txt │ │ │ ├── UTF8.txt │ │ │ ├── Unicode.txt │ │ │ └── recuresive/ │ │ │ └── UTF8.txt │ │ ├── image/ │ │ │ └── ic_launcher.tif │ │ └── zip/ │ │ ├── test.txt │ │ ├── testDir/ │ │ │ └── test.txt │ │ ├── 测试.txt │ │ └── 测试文件夹/ │ │ └── 测试.txt │ ├── utildebug/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ ├── proguard-rules.pro │ │ └── src/ │ │ └── main/ │ │ ├── AndroidManifest.xml │ │ ├── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── utildebug/ │ │ │ ├── DebugUtils.java │ │ │ ├── base/ │ │ │ │ ├── drawable/ │ │ │ │ │ └── PolygonDrawable.java │ │ │ │ ├── rv/ │ │ │ │ │ ├── BaseItem.java │ │ │ │ │ ├── BaseItemAdapter.java │ │ │ │ │ ├── ItemViewHolder.java │ │ │ │ │ └── RecycleViewDivider.java │ │ │ │ └── view/ │ │ │ │ ├── BaseContentFloatView.java │ │ │ │ ├── BaseContentView.java │ │ │ │ ├── BaseFloatView.java │ │ │ │ ├── EmptyGoneTextView.java │ │ │ │ ├── FloatEditText.java │ │ │ │ ├── FloatToast.java │ │ │ │ ├── FloatViewManager.java │ │ │ │ ├── SearchEditText.java │ │ │ │ ├── SwipeRightMenu.java │ │ │ │ └── listener/ │ │ │ │ ├── OnBackListener.java │ │ │ │ └── OnRefreshListener.java │ │ │ ├── config/ │ │ │ │ └── DebugConfig.java │ │ │ ├── debug/ │ │ │ │ ├── IDebug.java │ │ │ │ └── tool/ │ │ │ │ ├── AbsToolDebug.java │ │ │ │ ├── appInfo/ │ │ │ │ │ ├── AppInfoDebug.java │ │ │ │ │ ├── AppInfoFloatView.java │ │ │ │ │ └── AppInfoItem.java │ │ │ │ ├── clearCache/ │ │ │ │ │ └── ClearCacheDebug.java │ │ │ │ ├── clearStorage/ │ │ │ │ │ └── ClearStorageDebug.java │ │ │ │ ├── deviceInfo/ │ │ │ │ │ ├── DeviceInfoDebug.java │ │ │ │ │ ├── DeviceInfoFloatView.java │ │ │ │ │ └── DeviceInfoItem.java │ │ │ │ ├── fileExplorer/ │ │ │ │ │ ├── FileContentView.java │ │ │ │ │ ├── FileExplorerDebug.java │ │ │ │ │ ├── FileExplorerFloatView.java │ │ │ │ │ ├── FileItem.java │ │ │ │ │ ├── image/ │ │ │ │ │ │ └── ImageViewer.java │ │ │ │ │ ├── sp/ │ │ │ │ │ │ ├── SpItem.java │ │ │ │ │ │ ├── SpModifyContentView.java │ │ │ │ │ │ └── SpViewerContentView.java │ │ │ │ │ └── text/ │ │ │ │ │ └── TextViewer.java │ │ │ │ ├── logcat/ │ │ │ │ │ └── LogcatDebug.java │ │ │ │ └── restartApp/ │ │ │ │ └── RestartAppDebug.java │ │ │ ├── helper/ │ │ │ │ ├── FileHelper.java │ │ │ │ ├── ImageLoader.java │ │ │ │ ├── ShadowHelper.java │ │ │ │ ├── SpHelper.java │ │ │ │ └── WindowHelper.java │ │ │ ├── icon/ │ │ │ │ └── DebugIcon.java │ │ │ └── menu/ │ │ │ ├── DebugItem.java │ │ │ ├── DebugMenu.java │ │ │ ├── DebugMenuItem.java │ │ │ └── ReminderView.java │ │ └── res/ │ │ ├── anim/ │ │ │ ├── float_in.xml │ │ │ └── float_out.xml │ │ ├── drawable/ │ │ │ ├── du_rotate_refresh.xml │ │ │ ├── du_sel_et_bg.xml │ │ │ ├── du_shape_base_float_bg.xml │ │ │ ├── du_shape_base_float_title_adjust_bg.xml │ │ │ ├── du_shape_base_float_title_bg.xml │ │ │ ├── du_shape_base_float_title_close_bg.xml │ │ │ ├── du_shape_btn.xml │ │ │ ├── du_shape_divider.xml │ │ │ ├── du_shape_file_divider.xml │ │ │ ├── du_shape_input_bg.xml │ │ │ ├── du_shape_item_menu_bg.xml │ │ │ ├── du_shape_positive_btn.xml │ │ │ ├── du_shape_shadow.xml │ │ │ ├── du_shape_toast.xml │ │ │ ├── du_switch_thumb.xml │ │ │ └── du_switch_track.xml │ │ ├── layout/ │ │ │ ├── du_base_content_float.xml │ │ │ ├── du_debug_app_info.xml │ │ │ ├── du_debug_device_info.xml │ │ │ ├── du_debug_file_explorer.xml │ │ │ ├── du_debug_file_explorer_image.xml │ │ │ ├── du_debug_file_explorer_sp.xml │ │ │ ├── du_debug_file_explorer_sp_modify.xml │ │ │ ├── du_debug_icon.xml │ │ │ ├── du_debug_menu.xml │ │ │ ├── du_float_toast.xml │ │ │ ├── du_item_base_info.xml │ │ │ ├── du_item_empty.xml │ │ │ ├── du_item_file.xml │ │ │ ├── du_item_menu.xml │ │ │ ├── du_item_menu_item.xml │ │ │ ├── du_item_sp.xml │ │ │ └── du_reminder_view.xml │ │ ├── values/ │ │ │ ├── colors.xml │ │ │ ├── dimens.xml │ │ │ ├── ids.xml │ │ │ ├── strings.xml │ │ │ └── styles.xml │ │ └── values-zh-rCN/ │ │ └── strings.xml │ └── utildebug-no-op/ │ ├── .gitignore │ ├── build.gradle │ ├── proguard-rules.pro │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ └── java/ │ └── com/ │ └── blankj/ │ └── utildebug/ │ ├── DebugUtils.java │ └── debug/ │ └── IDebug.java ├── module_config.gradle ├── module_config.json ├── plugin/ │ ├── api-gradle-plugin/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── build.gradle │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── api/ │ │ │ ├── ApiClassVisitor.java │ │ │ ├── ApiExtension.groovy │ │ │ ├── ApiInfo.java │ │ │ ├── ApiInject.groovy │ │ │ ├── ApiPlugin.groovy │ │ │ ├── ApiUtilsClassVisitor.java │ │ │ └── Config.groovy │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── api/ │ │ ├── ApiTest.java │ │ └── ApiUtils.java │ ├── buildSrc-plugin/ │ │ ├── .gitignore │ │ ├── build.gradle │ │ └── src/ │ │ └── main/ │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── buildSrc/ │ │ ├── BuildSrcPlugin.groovy │ │ └── ModuleCfg.groovy │ ├── bus-gradle-plugin/ │ │ ├── .gitignore │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── build.gradle │ │ └── src/ │ │ ├── main/ │ │ │ └── java/ │ │ │ └── com/ │ │ │ └── blankj/ │ │ │ └── bus/ │ │ │ ├── BusClassVisitor.java │ │ │ ├── BusExtension.groovy │ │ │ ├── BusInfo.java │ │ │ ├── BusInject.groovy │ │ │ ├── BusPlugin.groovy │ │ │ ├── BusUtilsClassVisitor.java │ │ │ └── Config.groovy │ │ └── test/ │ │ └── java/ │ │ └── com/ │ │ └── blankj/ │ │ └── bus/ │ │ ├── BusTest.java │ │ └── BusUtils.java │ └── lib/ │ └── base-transform/ │ ├── .gitignore │ ├── CHANGELOG.md │ ├── README.md │ ├── build.gradle │ └── src/ │ └── main/ │ └── java/ │ └── com/ │ └── blankj/ │ └── base_transform/ │ ├── BaseTransformCallback.groovy │ ├── BaseTransformConfig.groovy │ ├── BaseTransformPlugin.groovy │ └── util/ │ ├── JsonUtils.groovy │ ├── LogUtils.groovy │ └── ZipUtils.java ├── script/ │ ├── gitHelp.sh │ ├── runDevDebug.sh │ └── runProductionRelease.sh ├── settings.gradle └── sign/ ├── keystore.jks └── keystore.properties ================================================ FILE CONTENTS ================================================ ================================================ FILE: .github/FUNDING.yml ================================================ # These are supported funding model platforms github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] patreon: # Replace with a single Patreon username open_collective: # Replace with a single Open Collective username ko_fi: # Replace with a single Ko-fi username tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry liberapay: # Replace with a single Liberapay username issuehunt: # Replace with a single IssueHunt username otechie: # Replace with a single Otechie username custom: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report.md ================================================ --- name: Bug report about: Make AndroidUtilCode more perfect! labels: bug assignees: Blankj --- ## Describe the bug A clear and concise description of what the bug is. - The version of AndroidUtilCode: - The device: - The version of device: ## The code of bug ``` put your code here ``` ## The stack of crash ``` put the stack of crash here ``` ## Screenshots If applicable, add screenshots to help explain your problem. ## Please delete the current line and the following. Thank you for supporting [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). ================================================ FILE: .github/ISSUE_TEMPLATE/bug_report_cn.md ================================================ --- name: 提交 Bug about: 让工具类更完美! labels: bug assignees: Blankj --- ## 描述 Bug 简洁地描述下 Bug。 - AndroidUtilCode 的版本: - 出现 Bug 的设备型号: - 设备的 Android 版本: ## 相关代码 ``` put your code here ``` ## 异常堆栈 ``` put the stack of crash here ``` ## 截图 如果有的话请添加屏幕截图以帮助解释问题。 ## 请删除当前行及以下内容 感谢支持 [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). ================================================ FILE: .github/ISSUE_TEMPLATE/feature-request.md ================================================ --- name: Feature request about: Make AndroidUtilCode more perfect! labels: help wanted assignees: Blankj --- ## Describe the feature A clear and concise description of what the feature is. ## Reference Hope to give some reference articles, links, code, if any. ## Please delete the current line and the following Thank you for supporting [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). ================================================ FILE: .github/ISSUE_TEMPLATE/feature-request_cn.md ================================================ --- name: 提交需求 about: 让工具类更健全! labels: help wanted assignees: Blankj --- ## 描述需求 简洁地描述下需求。 ## 可借鉴的 如果有的话,可以给出一些参考文章、链接、代码 ## 请删除当前行及以下内容 感谢支持 [AndroidUtilCode](https://github.com/Blankj/AndroidUtilCode). ================================================ FILE: .github/workflows/android.yml ================================================ name: Android CI on: [push] jobs: build: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: set up JDK 1.8 uses: actions/setup-java@v1 with: java-version: 1.8 - name: Build with Gradle run: ./gradlew build aR ================================================ FILE: .gitignore ================================================ *.iml __api__.json __bus__.json .gradle local.properties .idea .DS_Store /build /captures .externalNativeBuild /apk *.phrof /mavenLocal /reports */reports ================================================ FILE: CHANGELOG.md ================================================ * `22/10/15` [add] Fix some issue. Publish v1.31.1 * `21/12/06` [add] Publish v1.31.0 * `21/05/13` [add] Support publish mavenCentral. * `21/02/22` [add] Fix ToastUtils rtl bug. Publish v1.30.6. * `20/11/16` [add] Add ImageUtils#save2Album support param of dirName. * `20/11/13` [add] Fix MessengerUtils ANR. Add NetworkUtils#getWifiScanResult, [add|remove]OnWifiChangedConsumer. Publish v1.30.5. * `20/10/29` [add] Fix MessengerUtils startService IllegalStateException. Publish v1.30.4. * `20/10/28` [add] Fix BusUtils ConcurrentModificationException. Publish v1.30.3. * `20/10/27` [add] Fix AppUtils#getAppSignatures. Add DeviceUtils#isDevelopmentSettingsEnabled. Publish v1.30.2. * `20/10/26` [add] Fix AppUtils#isAppForeground. Publish v1.30.1. * `20/10/24` [add] Publish v1.30.0. * `20/10/23` [fix] LanguageUtils crash on some device. * `20/10/21` [add] LogUtils.Config#setOnConsoleOutputListener, setOnFileOutputListener, addFileExtraHead. LogUtils.getCurrentLogFilePath. * `20/10/20` [opt] ToastUtils. * `20/10/12` [add] PermissionUtils#explain. * `20/10/10` [add] ClipboardUtils. * `20/10/08` [add] VolumeUtils. * `20/09/06` [add] DebouncingUtils#isValid. * `20/09/04` [fix] ToastUtils adapt SDK 30. * `20/05/28` [fix] IntentUtils#getInstallAppIntent file exist wrong. Publish v1.29.0. * `20/05/23` [fix] BusUtils#postSticky times not right. Publish v1.28.6. * `20/05/22` [add] IntentUtils#getInstallAppIntent support Uri param. * `20/05/21` [add] Publish bus plugin v2.6. Publish api plugin v1.4. Publish. Publish v1.28.5. * `20/05/19` [fix] FileUtils#copyOrMoveDird NPE. * `20/05/18` [add] IntentUtils#getLaunchAppDetailsSettingsIntent support isNewTask. * `20/05/17` [add] ImageUtils#save2Album, NetworkUtils#getSSID, UtilsTransActivity4MainProcess. * `20/05/03` [add] Publish bus plugin v2.5. Publish api plugin v1.3. Publish. Publish v1.28.4. * `20/04/30` [add] BaseItem support partialUpdate. * `20/04/29` [add] Publish plugin lib com.blankj:base-transform:1.0. * `20/04/28` [fix] LanguageUtils#applyLanguage. * `20/04/27` [fix] BarUtils#isNavBarVisible. * `20/04/26` [fix] Utils#init fit tinker. Publish v1.28.3. * `20/04/25` [fix] UriUtils#uri2File Unknown URI. Publish 1.28.2. * `20/04/24` [add] SnackbarUtils support show on the top; UriUtils#uri2InputStream. * `20/04/23` [fix] UriUtils#uri2File not support HW; TransActivity crash below 21. * `20/04/23` [fix] PhoneUtils#getSerial, PhoneUtils#getSerial crash on Android 10. * `20/04/20` [fix] ImageUtils#isImage. * `20/04/18` [fix] PermissionUtils#callback. Publish v1.28.1. * `20/04/17` [fix] ImageUtils#view2Bitmap, ImageUtils.getBitmap(InputStream). * `20/04/16` [add] ConvertUtils#int2HexString, hexString2Int. * `20/04/15` [add] UiMessageUtils' demo. * `20/04/13` [add] NumberUtils. Publish v1.28.0. * `20/04/12` [opt] TimeUtils#SDF_THREAD_LOCAL. * `20/04/11` [add] SDCardUtils#getXxTotalSize, SDCardUtils#getXxAvailableSize. FileUtils#getFsTotalSize, FileUtils#getFsAvailableSize. * `20/04/10` [fix] FileUtils#isFileExists; FragmentUtils#getTop bug. Publish v1.27.6. * `20/04/09` [add] UriUtils#res2Uri, UriUtils#uri2File support QQBrowser; ThreadUtils#getMainHandler; PathUtils#getxxPathExternalFirst. * `20/04/08` [fix] ActivityUtils#finish bug. Publish v1.27.5. * `20/04/08` [fix] CleanUtils clean dir not work. FileUtils#isFileExists. Publish v1.27.4. * `20/04/08` [fix] CrashUtils DefaultUncaughtExceptionHandler is wrong; LogUtils write file failed; Utils#getApp failed run on remote process. Publish v1.27.3. * `20/04/07` [mdf] GsonUtils#getGson() method public. * `20/04/04` [fix] ShadowUtils bug running on lower version devices. Publish v1.27.2. * `20/04/03` [fix] UtilsActivityLifecycleImpl#HashMap#remove IllegalStateException bug. * `20/04/02` [fix] PathUtils sdcard enable state is wrong; ActivityUtils finish activity wrong; Publish v1.27.1. * `20/03/31` [add] Publish v1.27.0. * `20/03/30` [add] BatteryUtils in subutil. * `20/03/27` [add] publish.gradle. * `20/03/24` [add] UtilsBridge to clean the utils. * `20/03/22` [upd] GsonUtils support custom gson. * `20/03/20` [add] ActivityUtils#addActivityLifecycleCallbacks, ActivityUtils#removeActivityLifecycleCallbacks. * `20/01/17` [upd] Leak Canary to v2.1. * `20/01/06` [add] ClickUtils#expandClickArea, ClickUtils#back2HomeFriendly * `19/11/30` [add] Publish bus plugin v2.4. Publish api plugin v1.2. * `19/11/28` [add] Publish v1.26.0. * `19/11/27` [add] Shadow demo. * `19/11/26` [add] MVP demo. * `19/11/22` [fix] Adapt the project for Gradle version of 6.0. * `19/10/30` [add] Publish bus plugin v2.3. Publish api plugin v1.1. * `19/10/24` [upd] Demo's UI. * `19/10/22` [add] NotificationUtils and demo. * `19/10/20` [add] UiMessageUtils. * `19/09/20` [add] ShadowUtils. * `19/08/27` [add] DebugUtils. * `19/08/26` [fix] PermissionUtils NPE. * `19/08/25` [upd] ImageUtils#getImageType. [add] LogUtils#getLogFiles. Publish v1.25.9. * `19/08/24` [fix] PhoneUtils#getIMEI crash on SDK 29. * `19/08/23` [add] ViewUtils#isLayoutRtl. * `19/08/22` [add] LogUtils#getLogFiles. * `19/08/13` [add] MapUtils and MapUtilsTest. Publish v1.25.8. * `19/08/12` [add] CollectionUtils and CollectionUtilsTest. * `19/08/11` [add] ArrayUtils and ArrayUtilsTest. * `19/08/09` [fix] https://www.virustotal.com/gui/home/upload with ESET-NOD32. Publish v1.25.7. * `19/08/08` [add] BusUtils#post tag support one-to-many. Publish v1.25.6. * `19/08/04` [add] ThreadUtils#Task support timeout. * `19/08/01` [upd] EncryptUtils#rsa. * `19/07/31` [add] DeviceUtils#getUniqueDeviceId, DeviceUtils#isSameDevice. Publish v1.25.5. * `19/07/30` [fix] ThreadUtils's task can only be executed once. PhoneUtils#getIMEI wrong. * `19/07/29` [fix] BusUtils post father class useless. KeyboardUtils#hideSoft bug. Publish v1.25.4. * `19/07/28` [add] NetworkUtils#(un)registerNetworkStatusChangedListener. Publish v1.25.3. * `19/07/27` [fix] ThreadUtils memory leak. * `19/07/26` [add] ContainerUtils. Publish v1.25.2. * `19/07/25` [fix] PermissionUtils' NullPointException. * `19/07/24` [fix] ZipUtils#unzipFile. * `19/07/23` [fix] ThreadUtils of cache pool. Publish v1.25.1. * `19/07/18` [add] README of ApiUtils and BusUtils. * `19/07/15` [add] Publish v1.25.0. * `19/07/14` [upd] Bus plugin for use BusUtils. Publish bus plugin v2.0. * `19/07/13` [add] Api plugin for use ApiUtils. Publish api plugin v1.0. * `19/07/09` [upd] The frame of project. * `19/07/06` [upd] BusUtils which behave same as EventBus. * `19/07/03` [add] ApiUtils which decoupling modules. * `19/06/30` [add] LanguageUtils support activity's class name. * `19/06/29` [add] ClickUtils#OnMultiClickListener, and remove dangerous function. Publish v1.24.6. * `19/06/28` [add] LanguageUtils. Publish v1.24.5. * `19/06/20` [fix] BusUtils' permission. Publish v1.24.4. * `19/06/19` [fix] UriUtils. Publish v1.24.3. * `19/06/18` [add] ClickUtils, ViewUtils. * `19/06/07` [fix] LogUtils file name contains ':'. Publish v1.24.2. * `19/06/06` [fix] LogUtils write to file. Publish v1.24.1. * `19/06/03` [fix] Refactoring framework. Publish v1.24.0. * `19/04/25` [fix] LogUtils delete due log. * `19/04/24` [upd] The swipe panel. * `19/03/17` [fix] The ugly UI. * `19/03/14` [fix] AdaptScreenUtils didn't work on some HaWei tablet. * `19/03/09` [fix] UriUtils#uri2File. * `19/03/08` [add] LogUtils support multi process. Publish v1.23.7. * `19/03/02` [fix] LogUtils#file. * `19/02/28` [fix] ImageUtils#calculateInSampleSize. Publish v1.23.6. * `19/02/26` [fix] UriUtils#uri2File. Publish v1.23.5. * `19/01/31` [add] HttpUtils. * `19/01/30` [add] RomUtils. Publish v1.23.4. * `19/01/29` [fix] LogUtils format json when json not start with '{'. Publish v1.23.3. * `19/01/28` [fix] KeyboardUtils#fixSoftInputLeaks don't work on the device of HuaWei. * `19/01/26` [fix] NetworkUtils#getNetworkType. * `19/01/25` [add] CloneUtils, PermissionUtils support request permission of WRITE_SETTINGS and DRAW_OVERLAYS. Publish v1.23.2. * `19/01/24` [add] BrightnessUtils and FlashlightUtils. * `19/01/23` [add] Modify the demo of utilcode use kotlin. Publish v1.23.1. * `19/01/22` [fix] AppUtils#installApp. * `19/01/17` [fix] Publish v1.23.0. * `19/01/16` [fix] BarUtils get Activity from view and delete the function of set status bar alpha. * `19/01/15` [add] ColorUtils. * `19/01/04` [add] CacheDiskStaticUtils, CacheDoubleStaticUtils, CacheMemoryStaticUtils. * `19/01/03` [add] SPStaticUtils. * `19/01/02` [fix] LogUtils log object. Publish v1.22.10. * `19/01/01` [add] GsonUtils. * `18/12/29` [add] AntiShakeUtils and VibrateUtils. Publish v1.22.9. * `18/12/28` [fix] ToastUtils show behind the dialog when close notification. * `18/12/27` [fix] LogUtils print StringBuilder failed. * `18/12/24` [fix] Utils$ActivityLifecycleImpl.consumeOnActivityDestroyedListener ConcurrentModificationException. Publish v1.22.7. * `18/12/22` [fix] AdaptScreenUtils#pt2px don't work when start webview. Publish v1.22.6. * `18/12/21` [add] LogUtils support print Map, Collection and Object to String. * `18/12/19` [fix] AdaptScreenUtils don't work in MIUI on Android 5.1.1. Publish v1.22.5. * `18/12/18` [fix] ToastUtils multi show crash when run API 25. Publish v1.22.4. * `18/12/18` [fix] ImageUtils recycle ret equals src. Publish v1.22.3. * `18/12/17` [fix] Utils$FileProvider4UtilCode not found. Publish v1.22.3. * `18/12/17` [fix] ToastUtils leak. Publish v1.22.2. * `18/12/09` [add] Component for the project. * `18/12/04` [add] BusUtils. Publish v1.22.1. * `18/11/18` [fix] ToastUtils don't show in the devices grater than API 24 when close the permission of notification. Publish v1.22.0. * `18/11/17` [fix] AppUtils#isAppInstalled don't work in no launcher app. * `18/11/16` [fix] ThreadUtils#cancel block the main thread. * `18/11/15` [add] module of bus-gradle-plugin and change style of gradle. * `18/11/14` [add] BusUtils. * `18/11/13` [add] AdaptScreenUtils. * `18/11/12` [fix] SPUtils bug when use in multi threads. * `18/10/25` [fix] SpanUtils#setLineHeight bug of multi lines. Publish v1.21.2. * `18/10/24` [fix] SpanUtils#appendImage on VIVO. Publish v1.21.1. * `18/10/16` [add] BusUtils, DeviceUtils#isAdbEnabled. Publish v1.21.0. * `18/09/29` [fix] ToastUtils which causes crash in the some devices of Xiaomi. Publish v1.20.4. * `18/09/13` 修复 ToastUtils 在小米手机显示 Toast 带有 App 名,发布 1.20.3 * `18/09/12` 修复 KeyBoardUtils#fixAndroidBug5497,完善 ToastUtils,发布 1.20.2 * `18/09/11` 新增 BarUtils#isSupportNavBar,删除 BarUtils#setNavBarImmersive * `18/09/10` 修复 KeyboardUtils 中 getWindowVisibleDisplayFrame 空指针异常,更新 BarUtils#isNavBarVisible * `18/09/06` 新增 PathUtils,发布 1.20.1 * `18/09/05` 新增 KeyboardUtils#showSoftInputUsingToggle 和 KeyboardUtils#hideSoftInputUsingToggle * `18/09/04` 修复 SHA 算法名 * `18/09/03` 新增 MetaDataUtils,发布 1.20.0 * `18/08/30` 修复 PermissionUtils$PermissionActivity 的 window 背景为黑色的问题,发布 1.19.4 * `18/08/28` 新增 RegexUtils#isIDCard18Exact * `18/08/26` 新增 AppUtils#getAppSignatureSHA256 和 AppUtils#getAppSignatureMD5,发布 1.19.3 * `18/08/24` 新增 ScreenUtils#restoreAdaptScreen,利用 FileProvider4UtilCode 不再需要初始化,发布 1.19.2 * `18/08/23` 修复 适配后 ToastUtils 原生 Toast 尺寸发生改变的问题,修复 KeyboardUtils#fixSoftInputLeaks,发布 1.19.1 * `18/08/10` 修复 ScreenUtils#adaptxx 导致获取状态栏和导航栏尺寸不对问题,发布 1.19.0 * `18/08/09` 新增 IntentUtils#isIntentAvailable,ToastUtils 传入空显示 null,发布 1.18.6 * `18/08/08` 修复 ScreenUtils#adaptxx 在第三方 SDK 会出现的问题,发布 1.18.5 * `18/08/07` 修复 ScreenUtils#adaptxx 在 API 26 以下无效的 bug,发布 1.18.4 * `18/08/06` 修复 ScreenUtils#screenShot 中 decorView.getDrawingCache() 为空的问题,发布 1.18.3 * `18/08/05` 修复 1.18.0 版本删去 `if (activity.getClass() == PermissionUtils.PermissionActivity.class) return;` 造成 PermissionUtils 获取栈顶 Activity 问题,发布 1.18.2 * `18/08/04` 新增 LogUtils#Config#setSaveDays,发布 1.18.1 * `18/08/03` 新增 LogUtils#Config#addFormatter,并新增 Array, Throwable, Bundle, Intent 的格式化输出 * `18/08/02` 修复 TimeUtils 中的 SimpleDateFormat 为 ThreadLocal 实现 * `18/08/01` 删除 标记废弃的 CacheUtils, AppUtils#installApp, TimeUtils#getWeekIndex,发布 1.18.0 * `18/07/30` 替换 ScreenUtils#adaptPortraitScreen 和 ScreenUtils#adaptLandscapeScreen,为 ScreenUtils#adaptScreen4VerticalSlide 和 ScreenUtils#adaptScreen4HorizontalSlide * `18/07/28` 修复 NetworkUtils#getIPAddress * `18/07/16` 新增 ScreenUtils#adaptPortraitScreen 和 ScreenUtils#adaptLandscapeScreen,发布 1.17.3 * `18/07/13` 修复 IntentUtils 分享图片判断逻辑,CacheDiskUtils 可放入 byte[0] * `18/06/29` 修复 FragmentUtils 中 getFragmentManager 空指针错误,发布 1.17.2 * `18/06/27` 新增 UriUtils#uri2File * `18/06/25` 新增 KeyboardUtils#fixAndroidBug5497,发布 1.17.1 版本 * `18/06/21` 修复 FragmentUtils#add 死循环的 BUG * `18/06/14` 替换 CacheUtils 为 CacheDiskUtils,CacheUtils 标记 deprecated,发布 1.17.0 版本 * `18/06/13` 新增 CacheMemoryUtils 和 CacheDoubleUtils * `18/06/12` 完善 FragmentUtils#add 和 replace 新增 tag * `18/05/30` 完善 DeviceUtils#getMacAddress,发布 1.16.4 版本 * `18/05/30` 修复 ToastUtils 在 targetSdkVersion 为 27 在 api 25 机器快速 show 两次崩溃的异常,发布 1.16.3 版本 * `18/05/29` 完善 TimeUtils 的 timeSpan 带符号位,ToastUtils 去除弱引用,发布 1.16.2 版本 * `18/05/25` 新增 AppUtils#registerAppStatusChangedListener 和 AppUtils#unregisterAppStatusChangedListener,发布 1.16.1 版本 * `18/05/22` 新增 ThreadUtils,发布 1.16.0 版本 * `18/05/15` 新增 MetaDataUtils 和 ActivityUtils#startActivityForResult,发布 1.15.1 版本 * `18/05/08` 新增 ResourceUtils,发布 1.15.0 版本 * `18/05/07` 修复 ZipUtils 漏洞,发布 1.14.4 版本 * `18/05/03` 修复 ToastUtils 默认字体大小问题,发布 1.14.3 版本 * `18/05/02` 修复 PermissionUtils 空异常,发布 1.14.2 版本 * `18/04/28` 新增 FlashlightUtils,发布 1.14.1 版本 * `18/04/26` 修复 KeyboardUtils 全屏 NO_LIMIT 的 bug * `18/04/25` 修复 多个空异常 * `18/04/24` 修复 多 FileProvider 带来的问题,发布 1.14.0 版本 * `18/04/23` 新增 RSA 加解密,发布 1.13.16 版本 * `18/04/22` 新增 LogUtils 设置栈偏移 * `18/04/21` 新增 AppUtils#relaunchApp、DeviceUtils#getABIs,发布 1.13.15 版本 * `18/04/20` 新增 BarUtils#setNavBarColor、BarUtils#getNavBarColor * `18/04/19` 新增 Process#isMainProcess、Process#getCurrentProcessName,发布 1.13.14 版本 * `18/04/18` 修复 LogUtils 头部空指针异常,SPUtils、CacheUtils 存储空值异常,发布 1.13.13 版本 * `18/04/17` 修复 ToastUtils 内存泄漏问题,感谢 [LambertCoding](https://github.com/LambertCoding),发布 1.13.12 版本 * `18/04/16` 完善 AppUtils#installAppSilent 路径包含空格问题,发布 1.13.11 版本 * `18/04/10` 完善 OnCrashListener 回调崩溃信息,发布 1.13.10 版本 * `18/04/09` 修复 静默安装重载错误,发布 1.13.9 版本 * `18/04/08` 修复 获取栈顶 Activity 链表为空的异常,获取栈顶 Activity 放到 Utils 中,发布 1.13.8 版本 * `18/04/06` 新增 GsonUtils 及单元测试 * `18/04/05` 完善 README 文档 * `18/04/03` 修复 LogUtils 在 Android Studio 3.1 版本日志丑陋的问题,发布 1.13.7 版本 * `18/03/29` 兼容 Utils 的初始化传入 application,发布 1.13.6 版本 * `18/03/20` 修复 PermissionUtils 子进程的问题,发布 1.13.5 版本 * `18/03/16` 新增 gradle 插件来格式化 README * `18/03/14` 修复 KeyboardUtils#getContentViewInvisibleHeight,发布 1.13.4 版本 * `18/03/10` 完善 AppUtils#installAppSilent 和 DeviceUtils#getMacAddress,发布 1.13.3 版本 * `18/03/09` 完善 ActivityUtils#getTopActivity * `18/03/08` 新增 反射获取栈顶 Activity 的方法,发布 1.13.2 版本 * `18/03/07` 修复 PermissionUtils 请求权限为 0 的 崩溃 * `18/03/05` 修复 Library Source does not match the bytecode for class LogUtils 问题,发布 1.13.1 版本 * `18/03/04` 完善 Javadoc 中文版为英文版,发布 1.13.0 版本 * `18/03/04` 完善 Javadoc 中文版为英文版 * `18/03/03` 完善 Javadoc 中文版为英文版 * `18/03/02` 完善 Javadoc 中文版为英文版 * `18/03/01` 完善 Javadoc 中文版为英文版 * `18/02/28` 完善 Javadoc 中文版为英文版 * `18/02/27` 完善 Javadoc 中文版为英文版 * `18/02/26` 完善 Javadoc 中文版为英文版 * `18/02/25` 完善 Javadoc 中文版为英文版 * `18/02/24` 完善 Javadoc 中文版为英文版 * `18/02/23` 完善 Javadoc 中文版为英文版 * `18/02/22` 完善 Javadoc 中文版为英文版 * `18/02/21` 完善 Javadoc 中文版为英文版 * `18/02/10` 完善 Javadoc 中文版为英文版 * `18/02/09` 完善 非空转换插件 traute 的使用方式 * `18/02/08` 修复 ActivityUtils option 低版本为空的异常 * `18/01/31` 修复 default 相关的逻辑错误,发布 1.12.4,修复 ToastUtils 在 kotlin 中转义失败,发布 1.12.5 * `18/01/28` 修复 ToastUtils 默认样式问题,发布 1.12.2,新增 DeviceUtils#getSDKVersionName,发布 1.12.3 * `18/01/27` 修复 PermissionUtils 某些机型闪烁问题,发布 1.12.1 * `18/01/17` 完善 ReflectUtils 及单元测试,发布 1.12.0 版本 * `18/01/16` 完善 ReflectUtils 及单元测试 * `18/01/15` 完善 ReflectUtils 及单元测试 * `18/01/14` 完善 ReflectUtils 及单元测试 * `18/01/13` 完善 ReflectUtils 及单元测试 * `18/01/12` 完善 ReflectUtils 及单元测试 * `18/01/11` 修复 ImageUtils 的 fastBlur radius 为 1 recycle 的 bug,新增 CrashUtils 初始化崩溃监听事件,发布 1.11.1 版本 * `18/01/10` 完善 PermissionUtils 及 readme,发布 1.11.0 版本 * `18/01/09` 完善 demo 动态权限适配 * `18/01/08` 新增 SPActivity,删除 SPUtils 的单元测试 * `18/01/08` 修复 ToastUtils 在 SDK 为 18 的自定义 toast 崩溃问题 * `18/01/07` 新增 PermissionUtils 的 Demo * `18/01/06` 修复 权限相关工具类内存泄漏问题 * `18/01/05` 新增 获取 Activity icon 和 logo * `18/01/04` 完善 6.0 动态权限相关工具类 * `18/01/03` 完善 6.0 动态权限相关工具类 * `18/01/02` 完善 6.0 动态权限相关工具类 * `18/01/01` 新增 6.0 动态权限相关工具类 * `17/12/30` 删除 SpanUtils 中设置图标 * `17/12/29` 完善 SpanUtils 的 appendImage 对齐方式 * `17/12/28` 完善 ScreenUtils 设置全屏的方式,发布 1.10.0 * `17/12/26` 新增 状态栏、导航栏设置是否可见和判断是否可见 * `17/12/22` 新增 注册软键盘改变监听器、注册导航栏改变监听器方法 * `17/12/21` 完善 获取屏幕宽高,修复行宽度大于 100 字符 * `17/12/20` 修复 SpanUtils 图标的 bug,不高于 6.0 的版本不支持居中和底部对齐 * `17/12/19` 修复 SpanUtils 多图的 bug * `17/12/15` 新增 ReflectUtils * `17/12/14` 完善 手机号(精确)正则,发布 1.9.12 * `17/12/12` 完善 LogUtils,当最终日志长度为 0 时,输出 log nothing * `17/12/11` 完善 ActivityUtils 的 finish 系列,发布 1.9.11 * `17/12/04` 完善 LogUtils 边框改为单线清爽型 * `17/11/30` 修复 ToastUtils 背景问题,发布 1.9.10 * `17/11/30` 修复 ToastUtils 获取背景为空,发布 1.9.9 * `17/11/28` 修复 EmptyUtils 对 CharSequence 的判断,感谢 jiezigg * `17/11/24` 新增 readme 格式化的 gradle 脚本 * `17/11/15` 完善 资源分包位置,使其更合理 * `17/11/10` 完善 LogUtils 新增日志头部,感谢 Kanade * `17/11/07` 完善 LogUtils 无 tag 的多参数 * `17/11/06` 修复 LogUtils 多参数打印失败的问题 * `17/11/01` 完善 ShellUtil 的 Msg 换行,感谢香脆的大鸡排 * `17/10/30` 完善 README * `17/10/29` 修复 6.0 内部存储安装失败问题 * `17/10/28` 完善 compile 为 implementation, provided 为 compileOnly * `17/10/27` 修复 兼容 AS3.0 * `17/10/27` 修复 LogUtils 在 kotlin 中使用的问题 * `17/10/25` 修复 LogUtils 边框,修复 getBitmap 从流获取 * `17/09/30` 完善 FragmentUtils,发布 1.9.2 * `17/09/29` 完善 FragmentUtils 和 isInstallApp * `17/09/28` 完善 FragmentUtils * `17/09/27` 完善 FragmentUtils * `17/09/26` 完善 ActivityUtils 及 Demo,发布 1.9.1 * `17/09/25` 完善 ActivityUtils 及 Demo * `17/09/24` 完善 ActivityUtils 及 Demo * `17/09/23` 完善 FragmentUtils * `17/09/19` 修复 CrashUtils 自定义路径错误 * `17/09/18` 完善 ImageUtils 的 Demo * `17/09/17` 完善 ImageUtils 的 compress * `17/09/13` 完善 ImageUtils 的 addBorder * `17/09/13` 完善 ImageUtils 的 toRound * `17/09/13` 完善 ImageUtils 和 LogUtils * `17/09/12` 完善 ImageUtils * `17/09/10` 完善 单元测试 * `17/09/08` 完善 单元测试 * `17/09/06` 完善 SDCardUtils 获取 SD 卡路径,完善 SPUtils 新增 commit * `17/09/05` 完善 LogUtils,发布版本 1.9.0 * `17/09/04` 完善 ToastUtils,去除相关 safe 函数,都改为 safe 实现,新增 CustomToast 的 Demo * `17/09/02` 完善 ToastUtils,去除引入 view 带来的问题,发布版本 1.8.6 * `17/08/30` 修复 ToastUtils 弱引用带来的问题,修复 CacheUtils 异步问题,发布版本 1.8.5 * `17/08/28` 修复 ToastUtils 内存泄露,新增 toast 可根据系统字体显示不同字体,发布版本 1.8.4 * `17/08/20` 新增 监听 Activity 生命周期,退出 App,发布版本 1.8.3 * `17/08/11` 完善 LogUtils 的 Builder 改为 Config,发布版本 1.8.2 * `17/08/10` 完善 FileUtils 的 deleteFilesInDir 和 listFilesInDir * `17/08/08` 新增 反射工具类 ReflectUtils * `17/08/06` 完善 为按功能分包,增加 subutil 的 Demo * `17/07/31` 修复 NetworkUtils 的 isAvailableByPing 循环递归,发布 1.8.1 * `17/07/31` 完善 BarUtils,发布 1.8.0 * `17/07/31` 完善 BarUtils * `17/07/30` 完善 BarUtils * `17/07/29` 完善 BarUtils * `17/07/28` 完善 BarUtils * `17/07/27` 完善 BarUtils * `17/07/26` 完善 ActivityUtils * `17/07/25` 完善 BarUtils,更新布局文件 * `17/07/24` 完善 BarUtils * `17/07/23` 完善 BarUtils * `17/07/22` 完善 BarUtils * `17/07/21` 完善 xml 文件的格式化 * `17/07/17` 完善 NetworkUtils 的 isAvailableByPing 函数新增 ip 参数 * `17/07/14` 修复 FragmentUtils 的 FragmentNode 为 public * `17/07/11` 完善 将不常用的工具类放在 subutil 中 * `17/07/10` 新增 subutil 库 * `17/07/07` 修复 TimeUtils 中获取当天零点的 bug * `17/07/02` 完善 BarUtils 的 Demo * `17/07/01` 完善 BarUtils 的 Demo * `17/06/30` 完善 BarUtils 的 Demo * `17/06/29` 新增 README logo * `17/06/28` 新增 返回键及右划返回 * `17/06/27` 新增 Toolbar * `17/06/26` 新增 final 参数 * `17/06/23` 完善 Demo 主页 * `17/06/20` 完善 ToastUtil, SnackbarUtils 新增设置底边距 * `17/06/17` 删除 HandlerUtils * `17/06/16` 新增 insight.io 的 bandage * `17/06/14` 完善 LogUtils 回退栈,发布 1.7.1 版本 * `17/06/13` 完善 Snackbar 和 Toast 的 Demo * `17/06/12` 完善 Snackbar 为建造者模式 * `17/06/11` 完善 SpanUtils,发布版本 1.7.0 * `17/06/08` 完善 SpanUtils * `17/06/07` 完善 SpannableStringUtils 改名为 SpanUtils,即将完工 * `17/06/06` 完善 SpannableStringUtils * `17/06/05` 完善 SpannableStringUtils * `17/06/04` 完善 SpannableStringUtils * `17/06/03` 完善 SpannableStringUtils * `17/06/02` 完善 SpannableStringUtils * `17/06/01` 完善 KeyBoardUtils 及 Demo * `17/05/30` 完善 CrashUtils,发布 1.6.4 * `17/05/28` 修复 CacheUtils 的 bug,发布 1.6.3 * `17/05/27` 修复 CacheUtils 的 bug,发布 1.6.2 * `17/05/26` 完善 CacheUtils,发布 1.6.0 和 1.6.1 * `17/05/25` 完善 FileIOUtils 和 CacheUtils * `17/05/23` 新增 读取文件到字符数组中两种方式 * `17/05/19` 新增 LogUtils 文件过滤和控制台开关 * `17/05/16` 新增 ActivityUtils 动画 * `17/05/12` 新增 base 系列 * `17/05/11` 修复 SpannableStringUtils 的 setDrawable 的 bug,发布 1.5.1 * `17/05/10` 完善 7.0 安装 App,完善 AppActivity * `17/05/09` 完善 TimeUtils 单元测试 * `17/05/08` 更新 BarUtils, LogUtils 新增配置文件,TimeUtils 将 pattern 改为 format,发布 1.5.0 * `17/05/04` 新增 签名 * `17/05/03` 修复 对齐头部日期 * `17/05/02` 完善 Demo 的 string 字符串变更,完善 ToastUtils 和 SnackbarUtils * `17/04/27` 新增 Travis CI,使用 shields,发布 1.4.1 * `17/04/26` 完善 HandlerUtils 使用 Handler#CallBack 的回调接口及 SpannableStringUtils 图片对齐 * `17/04/24` 修复 拼写错误,修复 StringUtils 的 equalsIgnoreCase * `17/04/23` 完善 README * `17/04/21` 完善 TimeUtils,发布 1.4.0 * `17/04/20` 新增 SpannableStringUtils 设置字体尺寸 * `17/03/29` 修改 README * `17/03/27` 更新 LogUtils * `17/03/26` 更新 LogUtils * `17/03/25` 更新 LogUtils * `17/03/24` 完善 StringUtils * `17/03/20` 修复 链接错误 * `17/03/19` 新增 LogUtils 栈回溯 * `17/03/14` 新增 常量包 * `17/02/14` 完善 FragmentUtils 中,Demo 测试中 * `17/02/13` 完善 FragmentUtils 中 * `17/02/12` 完善 FragmentUtils 中 * `17/02/11` 完善 FragmentUtils 中 * `17/02/10` 完善 FragmentUtils 中,LogUtils 对长度进行分割 * `17/02/09` 完善 FragmentUtils 中 * `17/02/08` 完善 FragmentUtils 中 * `17/02/07` 完善 FragmentUtils 中 * `17/02/06` 完善 FragmentUtils 中,炸断肠 * `17/02/05` 完善 FragmentUtils 中 * `17/02/04` 完善 FragmentUtils 中 * `17/02/03` 完善 FragmentUtils 中 * `17/02/02` 完善 FragmentUtils 中 * `17/02/01` 完善 FragmentUtils 中 * `17/01/24` 完善 并发布版本 1.3.6 * `17/01/16` 新增 LogUtils 打印类名函数名及所在行 * `17/12/26` 新增 阴历相关工具类 * `17/12/21` 完善 SpannableStringUtils * `16/12/19` 完善 SpannableStringUtils * `16/12/18` 完善 SpannableStringUtils,采用构造者模式 * `16/12/17` 完善 SpannableStringUtils * `16/12/16` 完善 拼音工具类 * `16/12/15` 完善 拼音工具类 * `16/12/14` 新增 不低于 7.0 的 Html 解码 * `16/12/13` 新增 获取文件最后修改时间 * `16/12/12` 新增 Utils 来做初始化 context * `16/12/10` 完善 权限中 * `16/12/09` 新增 6.0 以上权限判断 * `16/12/07` 修复升级到 6.0 bug 中 * `16/12/06` 完善 FlashlightUtils 中 * `16/12/05` 完善 FlashlightUtils 兼容 Api21 之后 * `16/12/04` 新增 FlashlightUtils * `16/12/03` 完善 时间工具类 * `16/12/02` 新增 获取合适型时间差 * `16/12/01` 新增 获取生肖和星座 * `16/11/30` 新增 获取友好型时间差 * `16/11/23` 完善 LocationUtils 测试,发布 1.3.4 * `16/11/22` 修复 LocationActivity 内存泄漏 * `16/11/21` 完善 README * `16/11/20` 完善 LocationUtils * `16/11/19` 完善 SizeUtils * `16/11/18` 完善 LocationUtils * `16/11/17` 完善 LocationUtils * `16/11/16` 新增 拼音工具类,单独拎出来做了整理 * `16/11/15` 完善 正则工具类 * `16/11/14` 新增 启动服务 * `16/11/13` 新增 判断 sim 卡是否准备好 * `16/11/12` 新增 重启到 recovery 和 bootloader,新增获取 launcher activity,最近一直在博客搬家,所以更得有点少 * `16/11/04` 修复 README 的缺少 process 的 bug * `16/11/03` 修复 SnackbarUtils 中 Snackbar 持有弱引用来消除内存泄漏 * `16/11/02` 修复 内存泄漏中 * `16/11/01` 完善 发布版本 1.3.3 内存泄漏检测中 * `16/10/31` 完善 发布版本 1.3.1 和 1.3.2 * `16/10/30` 修复 获取 IpAddress 对于小米手机的 Bug * `16/10/29` 新增 文件重命名和完善 root * `16/10/23` 完善 测试中 * `16/10/22` 完善 测试中 * `16/10/21` 完善 测试中 * `16/10/20` 完善 测试中 * `16/10/19` 修复 判断网络是否可用 * `16/10/18` 完善 是否前台应用,完善网络状态 * `16/10/17` 修复 获取签名,完善是否前台应用,完善网络状态 * `16/10/16` 新增 SnackbarUtils * `16/10/15` 完善 AppUtils 的 isAppForeground * `16/10/14` 完善 README-CN 排版(强迫症一定要对齐) * `16/10/13` 完善 测试 * `16/10/12` 新增 LogUtils 建造者模式,新增获取星期,发布版本 1.3.0,cheer * `16/10/11` 新增 EncryptUtils 的 Hmac 系列加密 * `16/10/10` 完善 LogUtils * `16/10/09` 完善 ToastUtils * `16/10/08` 新增 AppUtils 静默安装和静默卸载 * `16/10/07` 完善 EmptyUtils,新增很多判空 * `16/10/05` 完善 Happy Wedding! * `16/10/04` 完善 Readme * `16/10/03` 修复 ConvertUtils * `16/10/02` 完善 CrashUtils 完毕 * `16/10/01` 完善 Happy National Day! * `16/09/30` 完善 CrashUtils * `16/09/29` 完善 CleanUtils 测试完毕 * `16/09/28` 新增 EmptyUtils,完善 AppUtils 完毕 * `16/09/27` 新增 CleanUtils,完善 AppUtils * `16/09/26` 新增 根据域名获取 ip 地址(在此感谢 jp1017),新增 ClipboardUtils 单元测试,对 ImageUtils 进行了 bug 修复 * `16/09/25` 新增 ClipboardUtils * `16/09/24` 完善 AppUtils * `16/09/23` 完善 工具类,新增 ActivityUtils、BarUtils、IntentUtils * `16/09/22` 完善 LogUtils 中 * `16/09/21` 新增 LogUtils * `16/09/20` 完善 昨天的单元测试 * `16/09/19` 新增 CameraUtils,新增获取中文首字母 * `16/09/18` 修复 少许代码,发布 1.2.1 * `16/09/15` 完善 Happy Mid-Autumn Festival! * `16/09/14` 完善 ImageUtils 完毕,完善了 6.0 及以上版本安装 App 的问题,发布版本 1.2.0 * `16/09/13` 新增 英文版 README * `16/09/12` 完善 ZipUtils 及单元测试完美谢幕(支持空文件夹) * `16/09/11` 完善 不断更 * `16/09/10` 完善 ZipUtils 和单元测试中 * `16/09/09` 新增 字符串反转,ImageUtils 单元测试卡住中,暂时换为真机测试 * `16/09/08` 修复 NetworkUtils 报空,ImageUtils 单元测试卡住中 * `16/08/31` 完善 ImageUtils 单元测试中,之后 7 天鸡儿岭放假,停更 * `16/08/30` 完善 ImageUtils 单元测试(获取保存图片有问题,卡卡卡住了) * `16/08/29` 完善 ImageUtils,新增 stack 模糊算法和快速模糊 * `16/08/28` 完善 ImageUtils * `16/08/27` 完善 ConvertUtils,新增 ZipUtils * `16/08/26` 完善 ThreadPoolUtils 线程池相关工具类 * `16/08/25` 完善 ConstUtils 时间和存储相关常量新增枚举,传参改为枚举更为友好,新增 ThreadPoolUtils 线程池相关工具类 * `16/08/24` 新增 ConvertUtils 的 InputStream 与 byte[]和 String 相互转换,应用在 FileUtils 中读文件 * `16/08/23` 修复 bug,接下来完善 SDCardUtils 和 ImageUtils * `16/08/22` 完善 SPUtils 将 commit 改为 apply 提高效率,将 SPUtils 改为构造函数法创建,FileUtils 新增查找函数,规范 JavaDoc * `16/08/21` 完善 FileUtils 单元测试,修复 FileUtils 的 bug,发布版本 1.1.2 * `16/08/20` 完善 目录、FileUtils 单元测试,发布版本 1.1.1 * `16/08/19` 完善 FileUtils 及单元测试,及其他小修小补(在此感谢 vpop 的三次 Pr) * `16/08/18` 完善 FileUtils 及单元测试,完善 ImageUtils * `16/08/17` 完善 FileUtils * `16/08/16` 新增 StringUtils 及单元测试,完善正则工具类,版本更新 1.1.0 * `16/08/15` 新增 3DES 和 AES 加密及单元检测,加密解密工具类基本完善,目录更新 * `16/08/14` 新增 DES 加密及单元检测 * `16/08/13` 新增 MD2,SHA224,SHA256,SHA384,SHA512 加密及单元测试,正折腾 DES 加密 * `16/08/12` 新增 Base64 和 Html 编码解码及他们的单元测试,新增 TimeUtils 单元测试,更新 md * `16/08/11` 新增 SDCardUtils, UnitUtils,单元测试慢慢完善中 * `16/08/09` 修复 目录排版,新增 Download, Proguard 和 License * `16/08/08` 新增 Shell 工具类,已传 jcenter 遇到好多坑,javaDoc 惹的祸,注释一定要规范 * `16/08/07` 新增 6.0 获取 Mac 地址方法,新增对 HTML 转义,新增编码解码工具类,新增 SP 工具类 * `16/08/06` 完善 名包名,新增加密相关的单元测试,MD5 加密新增文件加密重载 * `16/08/05` 新增 MD5 盐加密,完善 NetworkUtils,新增判断状态栏是否存在(在此感谢 tiandawu) * `16/08/04` 新增 时间工具类(在此感谢 yi520000 给的补充),手机正则分简单和精确(在此感谢 MIkeeJY),新增判断是否锁屏,注释分段落,目录按首字母排序 * `16/08/03` 修复 onCreate 中获取 view 尺寸的 bug, MD5 和 SHA 的 Bug 修复完成(在此感谢 ssyijiu) * `16/08/02` 修复 wifi 设置界面 bug,注释排版还在修改,获取 mac 地址增加判空,新增 QQ群:74721490,欢迎加入,新增隐藏状态栏,注释更加全面,工具类已封装,写的时候真的是一个一个测试过去的,宝宝心里苦 * `16/08/01` 新增 获取 SD 卡路径,手机和设备进行分类,代码 bug 修改部分,小修排版,正在封装类,新增目录中显示方法名,新增获取当前 App 版本 Code * `16/07/31` 新增 点击屏幕空白区域隐藏软键盘,未能成功增加本页目录跳转功能(不支持) ================================================ FILE: LICENSE ================================================ Apache License Version 2.0, January 2004 http://www.apache.org/licenses/ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 1. Definitions. "License" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document. "Licensor" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License. "Legal Entity" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, "control" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity. "You" (or "Your") shall mean an individual or Legal Entity exercising permissions granted by this License. "Source" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files. "Object" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types. "Work" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below). "Derivative Works" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof. "Contribution" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, "submitted" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as "Not a Contribution." "Contributor" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work. 2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form. 3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed. 4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions: (a) You must give any other recipients of the Work or Derivative Works a copy of this License; and (b) You must cause any modified files to carry prominent notices stating that You changed the files; and (c) You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and (d) If the Work includes a "NOTICE" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License. 5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions. 6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file. 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License. 8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages. 9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability. END OF TERMS AND CONDITIONS APPENDIX: How to apply the Apache License to your work. To apply the Apache License to your work, attach the following boilerplate notice, with the fields enclosed by brackets "{}" replaced with your own identifying information. (Don't include the brackets!) The text should be enclosed in the appropriate comment syntax for the file format. We also recommend that a file or class name and description of purpose be included on the same "printed page" as the copyright notice for easier identification within third-party archives. Copyright 2017 Blankj Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. ================================================ FILE: README-CN.md ================================================ [![logo][logo]](https://github.com/Blankj/AndroidUtilCode) [![frame][frame]](https://github.com/Blankj/AucFrameTemplate) [![auc][aucSvg]][auc] [![result][apiSvg]][result] [![build][buildSvg]][build] [![License][licenseSvg]][license] ## [README of English][readme] ## About **[AndroidUtilCode][readme]** :fire: 是一个强大易用的安卓工具类库,它合理地封装了安卓开发中常用的函数,具有完善的 Demo 和单元测试,利用其封装好的 APIs 可以大大提高开发效率,如今它主要包括两部分模块,其一是主工具类模块:**[utilcode][utilcode-cn]**,其中的工具类是开发中常用到的;其二是子工具类模块:**[subutil][subutil-cn]**,它包含的工具类并不是很常用,它的出现是为了防止主工具类的臃肿。 :fire: ## Documentation ### utilcode * [README of English][utilcode] * [README of Chinese][utilcode-cn] ### subutil * [README of English][subutil] * [README of Chinese][subutil-cn] ## Donations 如果它对你帮助很大,并且你很想支持库的后续开发和维护,那么你可以扫下方二维码随意打赏我,就当是请我喝杯咖啡或是啤酒,我将不胜感激 :-) ![donate][donate] ## Contact [![Blog][blogSvg]][blog] [![jianshu][jianshuSvg]][jianshu] [![weibo][weiboSvg]][weibo] [![QQGroup][qqgroupSvg]][qqgroup] ## [Change Log][changeLog.md] ## 打个小广告 欢迎加入我的小专栏「**[基你太美](https://xiaozhuanlan.com/Blankj)**」一起学习。 [logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png [frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame_cn.png [aucSvg]: https://github.com/Blankj/AndroidUtilCode/workflows/Android%20CI/badge.svg?branch=master [auc]: https://github.com/Blankj/AndroidUtilCode [apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg [result]: https://android-arsenal.com/result?level=14 [buildSvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master [build]: https://travis-ci.org/Blankj/AndroidUtilCode [licenseSvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg [license]: https://github.com/Blankj/AndroidUtilCode/blob/master/LICENSE [readme]: https://github.com/Blankj/AndroidUtilCode [readme-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/README-CN.md [utilcode]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README.md [utilcode-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md [subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README.md [subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README-CN.md [changeLog.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/CHANGELOG.md [donate]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png [blogSvg]: https://img.shields.io/badge/Blog-@Blankj-34a48e.svg [blog]: http://blankj.com [jianshuSvg]: https://img.shields.io/badge/简书-@Blankj-34a48e.svg [jianshu]: http://www.jianshu.com/u/46702d5c6978 [weiboSvg]: https://img.shields.io/badge/weibo-@__Blankj-34a48e.svg [weibo]: http://weibo.com/3076228982 [qqgroupSvg]: https://img.shields.io/badge/QQ群-25206533-34a48e.svg [qqgroup]: https://shang.qq.com/wpa/qunwpa?idkey=d906789f84484465e2736f7b524366b4c23afeda38733d5c7b10fc3f6e406e9b ================================================ FILE: README.md ================================================ [![logo][logo]](https://github.com/Blankj/AndroidUtilCode) [![frame][frame]](https://github.com/Blankj/AucFrameTemplate) [![auc][aucSvg]][auc] [![result][apiSvg]][result] [![build][buildSvg]][build] [![License][licenseSvg]][license] ## [README of Chinese][readme-cn] ## About **[AndroidUtilCode][readme]** :fire: is a powerful & easy to use library for Android. This library encapsulates the functions that commonly used in Android development which have complete demo and unit test. By using it's encapsulated APIs, you can greatly improve the development efficiency. The program mainly consists of two modules which is **[utilcode][utilcode-cn]**, which is commonly used in development, and **[subutil][subutil-cn]** which is rarely used in development, but the utils can be beneficial to simplify the main module. :fire: ## Documentation ### utilcode * [README of English][utilcode] * [README of Chinese][utilcode-cn] ### subutil * [README of English][subutil] * [README of Chinese][subutil-cn] ## Donations If this project helps you a lot and you want to support the project's development and maintenance of this project, feel free to scan the following QR code for donation. Your donation is highly appreciated. Thank you! ![donate][donate] ## Contact [![Blog][blogSvg]][blog] [![jianshu][jianshuSvg]][jianshu] [![weibo][weiboSvg]][weibo] [![QQGroup][qqgroupSvg]][qqgroup] ## [Change Log][changeLog.md] ## 打个小广告 欢迎加入我的小专栏「**[基你太美](https://xiaozhuanlan.com/Blankj)**」一起学习。 [logo]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/logo.png [frame]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/auc_frame.png [aucSvg]: https://github.com/Blankj/AndroidUtilCode/workflows/Android%20CI/badge.svg?branch=master [auc]: https://github.com/Blankj/AndroidUtilCode [apiSvg]: https://img.shields.io/badge/API-14+-brightgreen.svg [result]: https://android-arsenal.com/result?level=14 [buildSvg]: https://travis-ci.org/Blankj/AndroidUtilCode.svg?branch=master [build]: https://travis-ci.org/Blankj/AndroidUtilCode [licenseSvg]: https://img.shields.io/badge/License-Apache--2.0-brightgreen.svg [license]: https://github.com/Blankj/AndroidUtilCode/blob/master/LICENSE [readme]: https://github.com/Blankj/AndroidUtilCode [readme-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/README-CN.md [utilcode]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README.md [utilcode-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/utilcode/README-CN.md [subutil]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README.md [subutil-cn]: https://github.com/Blankj/AndroidUtilCode/blob/master/lib/subutil/README-CN.md [changeLog.md]: https://github.com/Blankj/AndroidUtilCode/blob/master/CHANGELOG.md [donate]: https://raw.githubusercontent.com/Blankj/AndroidUtilCode/master/art/donate.png [blogSvg]: https://img.shields.io/badge/Blog-@Blankj-34a48e.svg [blog]: http://blankj.com [jianshuSvg]: https://img.shields.io/badge/简书-@Blankj-34a48e.svg [jianshu]: http://www.jianshu.com/u/46702d5c6978 [weiboSvg]: https://img.shields.io/badge/weibo-@__Blankj-34a48e.svg [weibo]: http://weibo.com/3076228982 [qqgroupSvg]: https://img.shields.io/badge/QQ群-25206533-34a48e.svg [qqgroup]: https://shang.qq.com/wpa/qunwpa?idkey=d906789f84484465e2736f7b524366b4c23afeda38733d5c7b10fc3f6e406e9b ================================================ FILE: build.gradle ================================================ // Top-level build file where you can add configuration options common to all sub-projects/modules. buildscript { ConfigUtils.init(gradle) repositories { mavenLocal() google() mavenCentral() jcenter() } dependencies { for (def entrySet : ConfigUtils.getApplyPlugins().entrySet()) { classpath entrySet.value.path } } } allprojects { repositories { mavenLocal() maven { url "https://jitpack.io" } google() mavenCentral() jcenter() } configurations.all { resolutionStrategy.cacheChangingModulesFor 0, 'seconds' resolutionStrategy.eachDependency { if (it.requested.group == 'com.android.support' && !it.requested.name.contains( 'multidex')) { it.useVersion Config.supportVersion } } } } task clean(type: Delete) { delete rootProject.buildDir } ================================================ FILE: buildApp.gradle ================================================ apply plugin: "com.android.application" apply { from "${rootDir.path}/buildCommon.gradle" from "${rootDir.path}/config/flavor.gradle" if (Config.plugins.plugin_api.isApply) { plugin Config.plugins.plugin_api.id } if (Config.plugins.plugin_bus.isApply) { plugin Config.plugins.plugin_bus.id } } configSigning() configApkName() //if (PluginConfig.plugin_bus.isApply) { // bus { // onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' // } //} // //if (PluginConfig.plugin_api.isApply) { // api { // onlyScanLibRegex = '^([:]|(com\\.blankj)).+$' // } //} android { defaultConfig { applicationId Config.applicationId + suffix targetSdkVersion Config.targetSdkVersion multiDexEnabled true } buildTypes { debug {} release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } packagingOptions { exclude 'META-INF/*' } dexOptions { preDexLibraries true javaMaxHeapSize "8g" maxProcessCount 8 dexInProcess = true } productFlavors { dev { applicationIdSuffix ".dev" versionNameSuffix "-dev" resValue "string", "app_name", Config.appName + suffix + "-dev" } production { resValue "string", "app_name", Config.appName + suffix } } } dependencies { // LeakCanary debugImplementation Config.libs.leakcanary.path debugImplementation Config.modules.lib_utildebug.dep releaseImplementation Config.modules.lib_utildebug_no_op.dep // 根据 Config.pkgConfig 来依赖所有 pkg for (def entrySet : ConfigUtils.getApplyPkgs().entrySet()) { api entrySet.value.dep } if (Config.modules.feature_mock.isApply) { api ModuleConfig.modules.feature_mock.dep } } def getSuffix() { if (project.name == "feature_launcher_app") return "" return "." + project. name. substring("feature_".length(), project.name.length() - "_app".length()) } def configSigning() { File signPropertiesFile = file("${rootDir.path}/sign/keystore.properties") if (!signPropertiesFile.exists()) return GLog.d("${project.toString()} sign start...") project.android { Properties properties = new Properties() properties.load(new FileInputStream(signPropertiesFile)) signingConfigs { release { storeFile new File(signPropertiesFile.getParent(), properties['keystore']) storePassword properties['storePassword'] keyAlias properties['keyAlias'] keyPassword properties['keyPassword'] } } buildTypes.release.signingConfig signingConfigs.release } GLog.d("${project.toString()} sign end...") } def configApkName() { project.android.applicationVariants.all { variant -> if (variant.buildType.name != "debug") { def artifact = variant.getPackageApplicationProvider().get() artifact.outputDirectory = new File("${rootDir.path}/apk") variant.outputs.each { it.outputFileName = "util" + suffix + (variant.flavorName == "" ? "" : ("_" + variant.flavorName)) + "_" + variant.versionName.replace(".", "_") + "_" + variant.buildType.name + ".apk" } } } } ================================================ FILE: buildCommon.gradle ================================================ apply { plugin "kotlin-android" plugin "kotlin-android-extensions" } android { compileSdkVersion Config.compileSdkVersion defaultConfig { minSdkVersion Config.minSdkVersion versionCode Config.versionCode versionName Config.versionName consumerProguardFiles 'proguard-rules.pro' } buildTypes { release { minifyEnabled true proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' } } compileOptions { sourceCompatibility JavaVersion.VERSION_1_8 targetCompatibility JavaVersion.VERSION_1_8 } lintOptions { abortOnError false } } ================================================ FILE: buildLib.gradle ================================================ apply plugin: "com.android.library" apply from: "${rootDir.path}/buildCommon.gradle" dependencies { if (project.name.endsWith("_pkg") || project.name.endsWith("_mock")) { // if module's name equals 'pkg', api all of export for (def entrySet : ConfigUtils.getApplyExports().entrySet()) { api entrySet.value.dep } } else if (project.name.endsWith("_export")) { api Config.modules.lib_common.dep } } ================================================ FILE: buildSrc/.gitignore ================================================ /build ================================================ FILE: buildSrc/build.gradle ================================================ repositories { google() jcenter() } apply { plugin 'groovy' plugin 'java-gradle-plugin' } gradlePlugin { plugins { readmeCore { id = 'readme-core' implementationClass = 'com.blankj.plugin.readme.ReadmeCorePlugin' } readmeSub { id = 'readme-sub' implementationClass = 'com.blankj.plugin.readme.ReadmeSubPlugin' } } } dependencies { implementation gradleApi() implementation localGroovy() implementation "commons-io:commons-io:2.6" } sourceSets { main { groovy { srcDirs += 'src/main/java' } } } ================================================ FILE: buildSrc/settings.gradle ================================================ //dependencyResolutionManagement { // repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS) // repositories { // google() // mavenCentral() // jcenter() // Warning: this repository is going to shut down soon // } //} ================================================ FILE: buildSrc/src/main/groovy/Config.groovy ================================================ class Config { static applicationId = 'com.blankj.androidutilcode' static appName = 'Util' static compileSdkVersion = 29 static minSdkVersion = 14 static targetSdkVersion = 29 static versionCode = 1_031_001 static versionName = '1.31.1'// E.g. 1.9.72 => 1,009,072 // lib version static gradlePluginVersion = '4.1.0' static kotlinVersion = '1.3.72' static androidxVersion = '1.0.0' static modules = [ /*Don't delete this line*/ /*Generated by "module_config.json"*/ plugin_api_gradle_plugin : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/api-gradle-plugin"), plugin_bus_gradle_plugin : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/bus-gradle-plugin"), plugin_lib_base_transform : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/lib/base-transform", remotePath: "com.blankj:base-transform:1.0"), plugin_buildSrc_plugin : new ModuleConfig(isApply: true , useLocal: true , localPath: "./plugin/buildSrc-plugin"), feature_mock : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/mock"), feature_launcher_app : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/launcher/app"), feature_main_app : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/main/app"), feature_main_pkg : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/main/pkg"), feature_subutil_app : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/subutil/app"), feature_subutil_pkg : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/subutil/pkg"), feature_subutil_export : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/subutil/export"), feature_utilcode_app : new ModuleConfig(isApply: false, useLocal: true , localPath: "./feature/utilcode/app"), feature_utilcode_pkg : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/utilcode/pkg"), feature_utilcode_export : new ModuleConfig(isApply: true , useLocal: true , localPath: "./feature/utilcode/export", remotePath: "com.blankj:utilcode-export:1.1"), lib_base : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/base"), lib_common : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/common"), lib_subutil : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/subutil"), lib_utilcode : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/utilcode", remotePath: "com.blankj:utilcodex:$Config.versionName"), lib_utildebug : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/utildebug"), lib_utildebug_no_op : new ModuleConfig(isApply: true , useLocal: true , localPath: "./lib/utildebug-no-op"), /*Don't delete this line*/ ] static plugins = [ plugin_gradle : new PluginConfig(path: "com.android.tools.build:gradle:$gradlePluginVersion"), plugin_kotlin : new PluginConfig(path: "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"), // 上传到 maven plugin_maven : new PluginConfig(path: "com.github.dcendents:android-maven-gradle-plugin:2.1", id: "com.github.dcendents.android-maven"), // 上传新版本插件更新 path 中的版本号,并设置 isApply = false // 通过 mavenLocal 上传本地版本,设置 isApply = true 即可应用插件来调试,最后通过 bintrayUpload 来发布插件 plugin_api : new PluginConfig(isApply: true, useLocal: false, path: "com.blankj:api-gradle-plugin:1.5", id: "com.blankj.api"), //./gradlew clean :plugin_api-gradle-plugin:mavenLocal // 上传到本地 mavenLocal //./gradlew clean :plugin_api-gradle-plugin:bintrayUpload // 上传到 jcenter plugin_bus : new PluginConfig(isApply: true, useLocal: false, path: "com.blankj:bus-gradle-plugin:2.6", id: "com.blankj.bus"), //./gradlew clean :plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal //./gradlew clean :plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter plugin_buildSrc: new PluginConfig(isApply: false, useLocal: false, path: "com.blankj:buildSrc-plugin:1.0", id: "com.blankj.buildSrc"), //./gradlew clean :plugin_bus-gradle-plugin:mavenLocal // 上传到本地 mavenLocal //./gradlew clean :plugin_bus-gradle-plugin:bintrayUpload // 上传到 jcenter ] static libs = [ androidx_appcompat : new LibConfig(path: "androidx.appcompat:appcompat:$androidxVersion"), androidx_material : new LibConfig(path: "com.google.android.material:material:$androidxVersion"), androidx_multidex : new LibConfig(path: "androidx.multidex:multidex:2.0.0"), androidx_constraint: new LibConfig(path: "androidx.constraintlayout:constraintlayout:1.1.3"), kotlin : new LibConfig(path: "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion"), leakcanary : new LibConfig(path: "com.squareup.leakcanary:leakcanary-android:2.1"), free_proguard : new LibConfig(path: "com.blankj:free-proguard:1.0.2"), swipe_panel : new LibConfig(path: "com.blankj:swipe-panel:1.2"), gson : new LibConfig(path: "com.google.code.gson:gson:2.8.5"), glide : new LibConfig(path: "com.github.bumptech.glide:glide:4.7.1"), retrofit : new LibConfig(path: "com.squareup.retrofit2:retrofit:2.4.0"), commons_io : new LibConfig(path: "commons-io:commons-io:2.6"), eventbus_lib : new LibConfig(path: "org.greenrobot:eventbus:3.1.1"), eventbus_processor : new LibConfig(path: "org.greenrobot:eventbus-annotation-processor:3.0.1"), photo_view : new LibConfig(path: "com.github.chrisbanes:PhotoView:2.0.0"), test_junit : new LibConfig(path: "junit:junit:4.12"), test_robolectric : new LibConfig(path: "org.robolectric:robolectric:4.3.1"), ] } //./gradlew clean :lib_utilcode:bintrayUpload ================================================ FILE: buildSrc/src/main/groovy/ConfigUtils.groovy ================================================ import org.gradle.api.Project import org.gradle.api.ProjectEvaluationListener import org.gradle.api.ProjectState import org.gradle.api.invocation.Gradle /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/13
 *     desc  :
 * 
*/ class ConfigUtils { static init(Gradle gradle) { generateDep(gradle) addCommonGradle(gradle) TaskDurationUtils.init(gradle) } /** * 根据 depConfig 生成 dep */ private static void generateDep(Gradle gradle) { def configs = [:] for (Map.Entry entry : Config.modules.entrySet()) { def (name, config) = [entry.key, entry.value] if (config.useLocal) { config.dep = gradle.rootProject.findProject(name) } else { config.dep = config.remotePath } configs.put(name, config) } GLog.l("generateDep = ${GLog.object2String(configs)}") } private static addCommonGradle(Gradle gradle) { gradle.addProjectEvaluationListener(new ProjectEvaluationListener() { @Override void beforeEvaluate(Project project) { // 在 project 的 build.gradle 前 do sth. if (project.name.contains("plugin")) { return } if (project.name.endsWith("_app")) { GLog.l(project.toString() + " applies buildApp.gradle") project.apply { from "${project.rootDir.path}/buildApp.gradle" } } else { GLog.l(project.toString() + " applies buildLib.gradle") project.apply { from "${project.rootDir.path}/buildLib.gradle" } } } @Override void afterEvaluate(Project project, ProjectState state) { // 在 project 的 build.gradle 末 do sth. } }) } static getApplyPlugins() { def plugins = [:] for (Map.Entry entry : Config.plugins.entrySet()) { if (entry.value.isApply) { plugins.put(entry.key, entry.value) } } GLog.d("getApplyPlugins = ${GLog.object2String(plugins)}") return plugins } static getApplyPkgs() { def pkgs = [:] for (Map.Entry entry : Config.modules.entrySet()) { if (entry.value.isApply && entry.key.endsWith("_pkg")) { pkgs.put(entry.key, entry.value) } } GLog.d("getApplyPkgs = ${GLog.object2String(pkgs)}") return pkgs } static getApplyExports() { def exports = [:] for (Map.Entry entry : Config.modules.entrySet()) { if (entry.value.isApply && entry.key.endsWith("_export")) { exports.put(entry.key, entry.value) } } GLog.d("getApplyExports = ${GLog.object2String(exports)}") return exports } } ================================================ FILE: buildSrc/src/main/groovy/GLog.groovy ================================================ /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/13
 *     desc  :
 * 
*/ class GLog { def static debugSwitch = true static d(Object... contents) { if (!debugSwitch) return contents return l(contents) } static l(Object... contents) { StringBuilder sb = new StringBuilder() sb.append(LogConst.BORDER_TOP) sb.append(borderMsg(processContents(contents))) sb.append(LogConst.BORDER_BTM) print sb.toString() return contents } private static borderMsg(String msg) { StringBuilder sb = new StringBuilder() object2String(msg).split(LogConst.LINE_SEP).each { line -> sb.append(LogConst.BORDER_LFT).append(line).append(LogConst.LINE_SEP) } return sb } private static processContents(final Object... contents) { String body = LogConst.NULL if (contents != null) { if (contents.length == 1) { body = object2String(contents[0]) } else { StringBuilder sb = new StringBuilder() int i = 0 for (int len = contents.length; i < len; ++i) { Object content = contents[i] sb.append("args[$i] = ") .append(object2String(content)) .append(LogConst.LINE_SEP) } body = sb.toString() } } return body.length() == 0 ? LogConst.NOTHING : body } static String object2String(Object object) { if (object == null) return "null"; if (object.getClass().isArray()) return LogFormatter.array2String(object); if (object instanceof List) return LogFormatter.list2String(object); if (object instanceof Map) return LogFormatter.map2String(object); if (object instanceof Throwable) return LogFormatter.throwable2String(object); return object.toString(); } static class LogFormatter { private static array2String(Object object) { if (object instanceof Object[]) { return Arrays.deepToString((Object[]) object); } else if (object instanceof boolean[]) { return Arrays.toString((boolean[]) object); } else if (object instanceof byte[]) { return Arrays.toString((byte[]) object); } else if (object instanceof char[]) { return Arrays.toString((char[]) object); } else if (object instanceof double[]) { return Arrays.toString((double[]) object); } else if (object instanceof float[]) { return Arrays.toString((float[]) object); } else if (object instanceof int[]) { return Arrays.toString((int[]) object); } else if (object instanceof long[]) { return Arrays.toString((long[]) object); } else if (object instanceof short[]) { return Arrays.toString((short[]) object); } throw new IllegalArgumentException("Array has incompatible type: " + object.getClass()); } private static list2String(List list) { StringBuilder sb = new StringBuilder() sb.append("[") list.each { v -> if (v instanceof Map || v instanceof List) { sb.append(String.format("$LogConst.LINE_SEP%${deep++ * 8}s${object2String(v)},", "")) deep-- } else { sb.append(String.format("$LogConst.LINE_SEP%${deep * 8}s$v,", "")) } } sb.deleteCharAt(sb.length() - 1) if (deep - 1 == 0) { sb.append("$LogConst.LINE_SEP]") } else { sb.append(String.format("$LogConst.LINE_SEP%${(deep - 1) * 8}s]", "")) } return sb.toString() } private static deep = 1; private static map2String(Map map) { StringBuilder sb = new StringBuilder() sb.append("[") map.each { k, v -> if (v instanceof Map || v instanceof List) { sb.append(String.format("$LogConst.LINE_SEP%${deep++ * 8}s%-26s: ${object2String(v)},", "", k)) deep-- } else { sb.append(String.format("$LogConst.LINE_SEP%${deep * 8}s%-26s: $v,", "", k)) } } sb.deleteCharAt(sb.length() - 1) if (deep - 1 == 0) { sb.append("$LogConst.LINE_SEP]") } else { sb.append(String.format("$LogConst.LINE_SEP%${(deep - 1) * 8}s]", "")) } return sb.toString() } private static throwable2String(Throwable throwable) { final List throwableList = new ArrayList<>(); while (throwable != null && !throwableList.contains(throwable)) { throwableList.add(throwable); throwable = throwable.getCause(); } final int size = throwableList.size(); final List frames = new ArrayList<>(); List nextTrace = getStackFrameList(throwableList.get(size - 1)); for (int i = size; --i >= 0;) { final List trace = nextTrace; if (i != 0) { nextTrace = getStackFrameList(throwableList.get(i - 1)); removeCommonFrames(trace, nextTrace); } if (i == size - 1) { frames.add(throwableList.get(i).toString()); } else { frames.add(" Caused by: " + throwableList.get(i).toString()); } frames.addAll(trace); } StringBuilder sb = new StringBuilder(); for (final String element : frames) { sb.append(element).append(LogConst.LINE_SEP); } return sb.toString(); } private static List getStackFrameList(final Throwable throwable) { final StringWriter sw = new StringWriter(); final PrintWriter pw = new PrintWriter(sw, true); throwable.printStackTrace(pw); final String stackTrace = sw.toString(); final StringTokenizer frames = new StringTokenizer(stackTrace, LogConst.LINE_SEP); final List list = new ArrayList<>(); boolean traceStarted = false; while (frames.hasMoreTokens()) { final String token = frames.nextToken(); // Determine if the line starts with at final int at = token.indexOf("at"); if (at != -1 && token.substring(0, at).trim().isEmpty()) { traceStarted = true; list.add(token); } else if (traceStarted) { break; } } return list; } private static void removeCommonFrames(final List causeFrames, final List wrapperFrames) { int causeFrameIndex = causeFrames.size() - 1; int wrapperFrameIndex = wrapperFrames.size() - 1; while (causeFrameIndex >= 0 && wrapperFrameIndex >= 0) { // Remove the frame from the cause trace if it is the same // as in the wrapper trace final String causeFrame = causeFrames.get(causeFrameIndex); final String wrapperFrame = wrapperFrames.get(wrapperFrameIndex); if (causeFrame.equals(wrapperFrame)) { causeFrames.remove(causeFrameIndex); } causeFrameIndex--; wrapperFrameIndex--; } } } static class LogConst { static LINE_SEP = System.getProperty("line.separator"); static BORDER_TOP = "┌────────────────────────────────────────────────────────────────────────────────────────────────────────────────" + LINE_SEP static BORDER_LFT = "│ "; static BORDER_BTM = "└────────────────────────────────────────────────────────────────────────────────────────────────────────────────" + LINE_SEP static final NOTHING = "log nothing"; static final NULL = "null"; } } ================================================ FILE: buildSrc/src/main/groovy/LibConfig.groovy ================================================ class LibConfig { String path String getGroupId() { String[] splits = path.split(":") return splits.length == 3 ? splits[0] : null } String getArtifactId() { String[] splits = path.split(":") return splits.length == 3 ? splits[1] : null } String getVersion() { String[] splits = path.split(":") return splits.length == 3 ? splits[2] : null } @Override String toString() { return "LibConfig { path = $path }" } static String getFlag(boolean b) { return b ? "✅" : "❌" } } ================================================ FILE: buildSrc/src/main/groovy/ModuleConfig.groovy ================================================ class ModuleConfig { boolean isApply // 是否应用 boolean useLocal // 是否使用本地的 String localPath // 本地路径 String remotePath // 远程路径 def dep // 根据条件生成项目最终的依赖项 String getGroupId() { String[] splits = remotePath.split(":") return splits.length == 3 ? splits[0] : null } String getArtifactId() { String[] splits = remotePath.split(":") return splits.length == 3 ? splits[1] : null } String getVersion() { String[] splits = remotePath.split(":") return splits.length == 3 ? splits[2] : null } @Override String toString() { return "ModuleConfig { isApply = ${getFlag(isApply)}" + ", dep = " + dep + " }" } static String getFlag(boolean b) { return b ? "✅" : "❌" } } ================================================ FILE: buildSrc/src/main/groovy/PluginConfig.groovy ================================================ final class PluginConfig { boolean isApply = true // 是否应用 boolean useLocal // 是否使用本地的 String path // 插件路径 String id // 插件 ID String getGroupId() { String[] splits = path.split(":") return splits.length == 3 ? splits[0] : null } String getArtifactId() { String[] splits = path.split(":") return splits.length == 3 ? splits[1] : null } String getVersion() { String[] splits = path.split(":") return splits.length == 3 ? splits[2] : null } @Override String toString() { return "PluginConfig { isApply = ${getFlag(isApply)}" + ", useLocal = ${getFlag(useLocal)}" + ", path = " + path + ", id = " + id + " }" } static String getFlag(boolean b) { return b ? "✅" : "❌" } } ================================================ FILE: buildSrc/src/main/groovy/TaskDurationUtils.groovy ================================================ import org.gradle.BuildListener import org.gradle.BuildResult import org.gradle.api.Task import org.gradle.api.execution.TaskExecutionListener import org.gradle.api.initialization.Settings import org.gradle.api.invocation.Gradle import org.gradle.api.tasks.TaskState import java.text.SimpleDateFormat /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/11/22
 *     desc  :
 * 
*/ class TaskDurationUtils { static List taskInfoList = [] static long startMillis static init(Gradle grd) { startMillis = System.currentTimeMillis() grd.addListener(new TaskExecutionListener() { @Override void beforeExecute(Task task) { task.ext.startTime = System.currentTimeMillis() } @Override void afterExecute(Task task, TaskState state) { def exeDuration = System.currentTimeMillis() - task.ext.startTime if (exeDuration >= 500) { taskInfoList.add(new TaskInfo(task: task, exeDuration: exeDuration)) } } }) grd.addBuildListener(new BuildListener() { @Override void beforeSettings(Settings settings) { super.beforeSettings(settings) } @Override void buildStarted(Gradle gradle) {} @Override void settingsEvaluated(Settings settings) {} @Override void projectsLoaded(Gradle gradle) {} @Override void projectsEvaluated(Gradle gradle) {} @Override void buildFinished(BuildResult buildResult) { if (!taskInfoList.isEmpty()) { Collections.sort(taskInfoList, new Comparator() { @Override int compare(TaskInfo t, TaskInfo t1) { return t1.exeDuration - t.exeDuration } }) StringBuilder sb = new StringBuilder() int buildSec = (System.currentTimeMillis() - startMillis) / 1000; int m = buildSec / 60; int s = buildSec % 60; def timeInfo = (m == 0 ? "${s}s" : "${m}m ${s}s (${buildSec}s)") sb.append("BUILD FINISHED in $timeInfo\n") taskInfoList.each { sb.append(String.format("%7sms %s\n", it.exeDuration, it.task.path)) } def content = sb.toString() GLog.d(content) File file = new File(grd.rootProject.buildDir.getAbsolutePath(), "build_time_records_" + new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss").format(new Date()) + ".txt") file.getParentFile().mkdirs() file.write(content) } } }) } private static class TaskInfo { Task task long exeDuration } } ================================================ FILE: buildSrc/src/main/java/com/blankj/plugin/readme/FormatUtils.groovy ================================================ package com.blankj.plugin.readme class FormatUtils { static def LINE_SEP = System.getProperty("line.separator") static def LONG_SPACE = " " static def format(File readmeCN) { def sb = new StringBuilder(), lines = readmeCN.readLines("UTF-8"), i = 0, size = lines.size() for (; i < size; ++i) { String line = lines.get(i) if (line.contains("* ###")) { sb.append(line).append(LINE_SEP) .append("```").append(LINE_SEP) def maxLen = 0 line = lines.get(i += 2) // get the max length of space for (def j = i; !line.equals("```"); line = lines.get(++j)) { maxLen = Math.max(maxLen, line.replace(" ", "").replace(",", ", ").indexOf(':')) } line = lines.get(i) for (; !line.equals("```"); line = lines.get(++i)) { def noSpaceLine = line.replace(" ", "") def spaceLen = maxLen - line.replace(" ", "").replace(",", ", ").indexOf(':') sb.append(noSpaceLine.substring(0, noSpaceLine.indexOf(':')).replace(",", ", ")) .append(LONG_SPACE.substring(0, spaceLen))// add the space .append(': ') .append(line.substring(line.indexOf(':') + 1).trim()) .append(LINE_SEP) } sb.append("```") } else { sb.append(line) } sb.append(LINE_SEP) } readmeCN.write(sb.toString(), "UTF-8") } } ================================================ FILE: buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeCorePlugin.groovy ================================================ package com.blankj.plugin.readme import org.gradle.api.Plugin import org.gradle.api.Project class ReadmeCorePlugin implements Plugin { @Override void apply(Project project) { project.extensions.create('readme', ReadmeExtension) project.task('readmeTask') { doLast { println "readmeTask start..." def ext = project['readme'] as ReadmeExtension def readmeCN = ext.readmeCnFile def readmeEng = ext.readmeFile readmeOfUtilCode2Eng(readmeCN, readmeEng) println "readmeTask finished." } } } static def readmeOfUtilCode2Eng(File readmeCN, File readmeEng) { FormatUtils.format(readmeCN) def lines = readmeCN.readLines("UTF-8") def sb = new StringBuilder() readmeCN.eachLine { line -> if (line.contains("* ###")) { if (line.contains("UtilsTransActivity")) { sb.append(line) } else { String utilsName = line.substring(line.indexOf("[") + 1, line.indexOf("Utils")) sb.append("* ### About ").append(utilsName).append(line.substring(line.indexOf(" -> "))) } } else if (line.contains(": ") && !line.contains("[")) { sb.append(line.substring(0, line.indexOf(':')).trim()) } else if (line.contains("打个小广告") || line.contains("基你太美")) { return } else { sb.append(line) } sb.append(FormatUtils.LINE_SEP) } readmeEng.write(sb.toString(), "UTF-8") } } ================================================ FILE: buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeExtension.groovy ================================================ package com.blankj.plugin.readme class ReadmeExtension { File readmeFile File readmeCnFile } ================================================ FILE: buildSrc/src/main/java/com/blankj/plugin/readme/ReadmeSubPlugin.groovy ================================================ package com.blankj.plugin.readme import org.gradle.api.Plugin import org.gradle.api.Project class ReadmeSubPlugin implements Plugin { @Override void apply(Project project) { project.extensions.create('readme', ReadmeExtension) project.task('readmeTask') { doLast { println "readmeTask start..." def ext = project['readme'] as ReadmeExtension def readmeCN = ext.readmeCnFile def readmeEng = ext.readmeFile readmeOfSubUtil2Eng(readmeCN, readmeEng) println "readmeTask finished." } } } static def readmeOfSubUtil2Eng(File readmeCN, File readmeEng) { FormatUtils.format(readmeCN) def lines = readmeCN.readLines("UTF-8"), sb = new StringBuilder("## How to use" + FormatUtils.LINE_SEP + FormatUtils.LINE_SEP + "You should copy the following classes which you want to use in your project." + FormatUtils.LINE_SEP), i = 3, size = lines.size() for (; i < size; ++i) { String line = lines.get(i) if (line.contains("* ###")) { String utilsName = line.substring(line.indexOf("[") + 1, line.indexOf("Utils")) sb.append("* ### About ").append(utilsName).append(line.substring(line.indexOf(" -> "))) } else if (line.contains(": ") && !line.contains("[")) { sb.append(line.substring(0, line.indexOf(':')).trim()) } else { sb.append(line) } sb.append(FormatUtils.LINE_SEP) } readmeEng.write(sb.toString(), "UTF-8") } } ================================================ FILE: config/flavor.gradle ================================================ android { flavorDimensions "env" productFlavors { dev { dimension "env" } production { dimension "env" } } variantFilter { variant -> def flavorNames = variant.flavors*.name def buildTypeName = variant.buildType.name // production 包不允许 debug 构建 if (flavorNames.contains("production") && buildTypeName.contains("debug")) { variant.setIgnore(true) } } } ================================================ FILE: config/publish.gradle ================================================ /* 1. add signing.keyId=xx signing.password=xx signing.secretKeyRingFile=/Users/xx/secring.gpg ossrhUsername=xx ossrhPassword=xx in root local.properties 2. copy the file to the directory of gradle, and apply the file in the module ext { groupId = Config.modules.lib_utilcode.groupId artifactId = Config.modules.lib_utilcode.artifactId version = Config.modules.lib_utilcode.version website = "https://github.com/Blankj/AndroidUtilCode" } apply from: "${rootDir.path}/config/publish.gradle" 3. execute following command to publish ./gradlew :xxmodule:publish2Local -> upload to mavenLocal ./gradlew :xxmodule:publish2Remote -> upload to mavenCentral */ apply plugin: 'maven-publish' apply plugin: 'signing' ext.multiPublishMode = true File localPropertiesFile = project.rootProject.file("local.properties"); if (!localPropertiesFile.exists()) { return } Properties properties = new Properties() properties.load(new FileInputStream(localPropertiesFile)) properties.each { name, value -> ext[name] = value } afterEvaluate { def ext = project.ext publishing { publications { release(MavenPublication) { groupId ext.groupId artifactId ext.artifactId version ext.version if (isAndroidEnv(project)) { if (project.ext.multiPublishMode) { artifact("$buildDir/outputs/aar/${project.getName()}-release.aar") artifact sourcesJar } else { from project.components.release } } else { from project.components.java } pom { name = ext.artifactId description = ext.artifactId url = ext.website licenses { license { name = 'The Apache Software License, Version 2.0' url = 'http://www.apache.org/licenses/LICENSE-2.0.txt' } } developers { developer { id = ext.ossrhUsername name = ext.ossrhUsername } } scm { url = ext.website connection = ext.website developerConnection = ext.website + ".git" } if (project.ext.multiPublishMode) { withXml { def dependenciesNode = asNode().getAt('dependencies')[0] ?: asNode().appendNode('dependencies') configurations.api.getDependencies().each { dep -> addDependency(project, dependenciesNode, dep, "compile") } configurations.implementation.getDependencies().each { dep -> addDependency(project, dependenciesNode, dep, "runtime") } } } } } } repositories { maven { // s01 is newest def releasesUrl = "https://s01.oss.sonatype.org/content/repositories/releases/" def snapshotUrl = "https://s01.oss.sonatype.org/content/repositories/snapshots/" url = version.toUpperCase().endsWith('SNAPSHOT') ? snapshotUrl : releasesUrl credentials { username ossrhUsername password ossrhPassword } } } } signing { sign publishing.publications } } private void addDependency(Project project, def dependenciesNode, Dependency dep, String scope) { if (dep.group == null || dep.version == null || dep.name == null || dep.name == "unspecified") { return } final dependencyNode = dependenciesNode.appendNode('dependency') dependencyNode.appendNode('scope', scope) if (dep.version == 'unspecified') { // 检测 module 中的 dependencies 是否有源码依赖 // 如果是源码依赖,而且没有在 config 中配置 remotePath, // 那么发布到仓库,其他地方依赖该库时会找不到源码的那个库 println "publish -> module(unspecified) <${dep.group}:${dep.name}:${dep.version}>" if (project.ext.groupId || project.ext.version) { throw new GradleException("The module of <" + dep.name + "> should set groupId & version.") } // 源码依赖,但配置了 remotePath,让 pom 中写入 remotePath println("publish -> module(wrapped) <${project.ext.groupId}:${name}:${project.ext.version}>") dependencyNode.appendNode('groupId', project.ext.pomGroupID) dependencyNode.appendNode('artifactId', dep.name) dependencyNode.appendNode('version', project.ext.pomVersion) } else { dependencyNode.appendNode('groupId', dep.group) dependencyNode.appendNode('artifactId', dep.name) dependencyNode.appendNode('version', dep.version) println("publish -> library <${dep.group}:${dep.name}:${dep.version}>") } if (!dep.transitive) { // In case of non transitive dependency, // all its dependencies should be force excluded from them POM file final exclusionNode = dependencyNode.appendNode('exclusions').appendNode('exclusion') exclusionNode.appendNode('groupId', '*') exclusionNode.appendNode('artifactId', '*') } else if (!dep.properties.excludeRules.empty) { // For transitive with exclusions, all exclude rules should be added to the POM file final exclusions = dependencyNode.appendNode('exclusions') dep.properties.excludeRules.each { ExcludeRule rule -> final exclusionNode = exclusions.appendNode('exclusion') exclusionNode.appendNode('groupId', rule.group ?: '*') exclusionNode.appendNode('artifactId', rule.module ?: '*') } } } if (isAndroidEnv(project)) { // This generates sources.jar task sourcesJar(type: Jar) { classifier = 'sources' from android.sourceSets.main.java.source } task javadoc(type: Javadoc) { source = android.sourceSets.main.java.source classpath += configurations.compile classpath += project.files(android.getBootClasspath().join(File.pathSeparator)) } task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir } } else { task sourcesJar(type: Jar, dependsOn: classes) { classifier = 'sources' from sourceSets.main.allSource } task javadocJar(type: Jar, dependsOn: javadoc) { classifier = 'javadoc' from javadoc.destinationDir } } if (project.hasProperty("kotlin")) { // Disable creating javadocs project.tasks.withType(Javadoc) { enabled = false } } javadoc { options { encoding "UTF-8" charSet 'UTF-8' author true version project.ext.version links "http://docs.oracle.com/javase/7/docs/api" title "${project.ext.artifactId} ${project.ext.version}" } } artifacts { archives javadocJar archives sourcesJar } static def isAndroidEnv(Project project) { return project.getPlugins().hasPlugin('com.android.application') || project.getPlugins().hasPlugin('com.android.library') } task publish2Local(type: GradleBuild) { tasks = ['assemble', 'publishReleasePublicationToMavenLocal'] } task publish2Remote(type: GradleBuild) { tasks = ['assemble', 'publishReleasePublicationToMavenRepository'] } ================================================ FILE: feature/launcher/app/.gitignore ================================================ /build ================================================ FILE: feature/launcher/app/build.gradle ================================================ apply plugin: 'kotlin-kapt' dependencies { kapt Config.libs.eventbus_processor.path } ================================================ FILE: feature/launcher/app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/launcher/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/launcher/app/src/main/java/com/blankj/launcher/app/LauncherApp.java ================================================ package com.blankj.launcher.app; import com.blankj.common.CommonApplication; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2016/10/12
 *     desc  :
 * 
*/ public class LauncherApp extends CommonApplication { private static LauncherApp sInstance; public static LauncherApp getInstance() { return sInstance; } @Override public void onCreate() { super.onCreate(); sInstance = this; } } ================================================ FILE: feature/main/app/.gitignore ================================================ /build ================================================ FILE: feature/main/app/build.gradle ================================================ ================================================ FILE: feature/main/app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/main/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/main/app/src/main/java/com/blankj/main/app/MainApp.java ================================================ package com.blankj.main.app; import android.content.Context; import com.blankj.common.CommonApplication; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2016/10/12
 *     desc  :
 * 
*/ public class MainApp extends CommonApplication { private static MainApp sInstance; public static MainApp getInstance() { return sInstance; } @Override protected void attachBaseContext(Context base) { super.attachBaseContext(base); } @Override public void onCreate() { super.onCreate(); sInstance = this; } } ================================================ FILE: feature/main/pkg/.gitignore ================================================ /build ================================================ FILE: feature/main/pkg/build.gradle ================================================ ================================================ FILE: feature/main/pkg/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/main/pkg/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/main/pkg/src/main/java/com/blankj/main/pkg/MainActivity.kt ================================================ package com.blankj.main.pkg import android.graphics.Color import android.os.Bundle import android.view.View import androidx.appcompat.app.ActionBarDrawerToggle import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.subutil.export.api.SubUtilApi import com.blankj.utilcode.export.api.UtilCodeApi import com.blankj.utilcode.util.ApiUtils import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.ClickUtils import com.blankj.utilcode.util.CollectionUtils import kotlinx.android.synthetic.main.activity_main.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : MainActivity * ``` */ class MainActivity : CommonActivity() { override fun isSwipeBack(): Boolean { return false } override fun bindDrawer(): Boolean { return true } override fun bindLayout(): Int { return R.layout.activity_main } override fun onCreate(savedInstanceState: Bundle?) { window.setBackgroundDrawable(null) super.onCreate(savedInstanceState) } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(mainRv, CollectionUtils.newArrayList>( CommonItemClick(R.string.core_util, true) { ApiUtils.getApi(UtilCodeApi::class.java)?.startUtilCodeActivity(this) }, CommonItemClick(R.string.sub_util, true) { ApiUtils.getApi(SubUtilApi::class.java)?.startSubUtilActivity(this) } )) launcherMainCtl.setExpandedTitleColor(Color.TRANSPARENT) setSupportActionBar(launcherMainToolbar) val toggle = ActionBarDrawerToggle(this, drawerView.mBaseDrawerRootLayout, launcherMainToolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close) drawerView.mBaseDrawerRootLayout.addDrawerListener(toggle) toggle.syncState() BarUtils.setStatusBarColor4Drawer(drawerView.mBaseDrawerRootLayout, launcherMainFakeStatusBar, Color.TRANSPARENT, false) BarUtils.addMarginTopEqualStatusBarHeight(launcherMainToolbar) } override fun onBackPressed() { ClickUtils.back2HomeFriendly("Press again to exit.") } } ================================================ FILE: feature/main/pkg/src/main/java/com/blankj/main/pkg/SplashActivity.kt ================================================ package com.blankj.main.pkg import com.blankj.common.activity.CommonActivity class SplashActivity : CommonActivity() { } ================================================ FILE: feature/main/pkg/src/main/res/layout/activity_main.xml ================================================ ================================================ FILE: feature/main/pkg/src/main/res/values/strings.xml ================================================ ================================================ FILE: feature/mock/.gitignore ================================================ /build ================================================ FILE: feature/mock/build.gradle ================================================ ================================================ FILE: feature/mock/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/mock/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/mock/src/main/java/com/blankj/mock/subutil/SubUtilApiMock.java ================================================ package com.blankj.mock.subutil; import android.content.Context; import com.blankj.subutil.export.api.SubUtilApi; import com.blankj.utilcode.util.ApiUtils; import com.blankj.utilcode.util.ToastUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/10
 *     desc  :
 * 
*/ @ApiUtils.Api(isMock = true) public class SubUtilApiMock extends SubUtilApi { @Override public void startSubUtilActivity(Context context) { ToastUtils.showShort("startSubUtilActivity"); } } ================================================ FILE: feature/mock/src/main/java/com/blankj/mock/utilcode/UtilCodeApiMock.java ================================================ package com.blankj.mock.utilcode; import android.content.Context; import com.blankj.utilcode.export.api.UtilCodeApi; import com.blankj.utilcode.util.ApiUtils; import com.blankj.utilcode.util.ToastUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/10
 *     desc  :
 * 
*/ @ApiUtils.Api(isMock = true) public class UtilCodeApiMock extends UtilCodeApi { @Override public void startUtilCodeActivity(Context context) { ToastUtils.showShort("startUtilCodeActivity"); } @Override public void testCallback(Callback callback) { if (callback != null) { callback.call(); } } } ================================================ FILE: feature/subutil/app/.gitignore ================================================ /build ================================================ FILE: feature/subutil/app/build.gradle ================================================ ================================================ FILE: feature/subutil/app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/subutil/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/subutil/app/src/main/java/com/blankj/subutil/app/SubUtilApp.kt ================================================ package com.blankj.subutil.app import android.content.Context import com.blankj.common.CommonApplication /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/12 * desc : app about utils * ``` */ class SubUtilApp : CommonApplication() { companion object { var instance: SubUtilApp? = null private set } override fun attachBaseContext(base: Context) { super.attachBaseContext(base) } override fun onCreate() { super.onCreate() instance = this } } ================================================ FILE: feature/subutil/export/.gitignore ================================================ /build ================================================ FILE: feature/subutil/export/build.gradle ================================================ ================================================ FILE: feature/subutil/export/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/subutil/export/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/subutil/export/src/main/java/com/blankj/subutil/export/api/SubUtilApi.java ================================================ package com.blankj.subutil.export.api; import android.content.Context; import com.blankj.utilcode.util.ApiUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/06/09
 *     desc  :
 * 
*/ public abstract class SubUtilApi extends ApiUtils.BaseApi { public abstract void startSubUtilActivity(Context context); } ================================================ FILE: feature/subutil/pkg/.gitignore ================================================ /build ================================================ FILE: feature/subutil/pkg/build.gradle ================================================ ================================================ FILE: feature/subutil/pkg/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/subutil/pkg/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/Config.kt ================================================ package com.blankj.subutil.pkg import android.os.Environment import com.blankj.utilcode.util.Utils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/10 * desc : config about constants * ``` */ object Config { val FILE_SEP = System.getProperty("file.separator") val LINE_SEP = System.getProperty("line.separator") const val TEST_PKG = "com.blankj.testinstall" private val CACHE_PATH: String val TEST_APK_PATH: String init { val cacheDir = Utils.getApp().externalCacheDir CACHE_PATH = if (cacheDir != null) { cacheDir.absolutePath } else { Environment.getExternalStorageDirectory().absolutePath } + FILE_SEP TEST_APK_PATH = CACHE_PATH + "test_install.apk" } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/SubUtilApiImpl.java ================================================ package com.blankj.subutil.pkg; import android.content.Context; import com.blankj.subutil.export.api.SubUtilApi; import com.blankj.subutil.pkg.feature.SubUtilActivity; import com.blankj.utilcode.util.ApiUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/02
 *     desc  :
 * 
*/ @ApiUtils.Api public class SubUtilApiImpl extends SubUtilApi { @Override public void startSubUtilActivity(Context context) { SubUtilActivity.Companion.start(context); } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/SubUtilActivity.kt ================================================ package com.blankj.subutil.pkg.feature import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.subutil.pkg.R import com.blankj.subutil.pkg.feature.appStore.AppStoreActivity import com.blankj.subutil.pkg.feature.battery.BatteryActivity import com.blankj.subutil.pkg.feature.country.CountryActivity import com.blankj.subutil.pkg.feature.dangerous.DangerousActivity import com.blankj.subutil.pkg.feature.location.LocationActivity import com.blankj.subutil.pkg.feature.pinyin.PinyinActivity import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : MainActivity * ``` */ class SubUtilActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, SubUtilActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.sub_util } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemClick(R.string.demo_app_store, true) { AppStoreActivity.start(this) }, CommonItemClick(R.string.demo_battery, true) { BatteryActivity.start(this) }, CommonItemClick(R.string.demo_country, true) { CountryActivity.start(this) }, CommonItemClick(R.string.demo_dangerous, true) { DangerousActivity.start(this) }, CommonItemClick(R.string.demo_location, true) { LocationActivity.start(this) }, CommonItemClick(R.string.demo_pinyin, true) { PinyinActivity.start(this) } ) } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/appStore/AppStoreActivity.kt ================================================ package com.blankj.subutil.pkg.feature.appStore import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.subutil.pkg.R import com.blankj.subutil.util.AppStoreUtils import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/01 * desc : demo about AppStore * ``` */ class AppStoreActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, AppStoreActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_app_store } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.app_store_system, true) { AppStoreUtils.getAppStoreIntent("com.tencent.mm").apply { ActivityUtils.startActivity(this) } } ) } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/battery/BatteryActivity.kt ================================================ package com.blankj.subutil.pkg.feature.battery import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.subutil.pkg.R import com.blankj.subutil.util.BatteryUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 20/03/31 * desc : demo about Battery * ``` */ class BatteryActivity : CommonActivity(), BatteryUtils.OnBatteryStatusChangedListener { private val titleItem: CommonItemTitle = CommonItemTitle("", true); companion object { fun start(context: Context) { val starter = Intent(context, BatteryActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_battery } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList(titleItem) } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) BatteryUtils.registerBatteryStatusChangedListener(this) } override fun onBatteryStatusChanged(status: BatteryUtils.Status) { titleItem.title = status.toString() ToastUtils.showShort(status.toString()) } override fun onDestroy() { super.onDestroy() BatteryUtils.unregisterBatteryStatusChangedListener(this) } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/country/CountryActivity.kt ================================================ package com.blankj.subutil.pkg.feature.country import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.subutil.pkg.R import com.blankj.subutil.util.CountryUtils import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/01 * desc : demo about Country * ``` */ class CountryActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, CountryActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_country } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("getCountryCodeBySim", CountryUtils.getCountryCodeBySim("Default")), CommonItemTitle("getCountryCodeByLanguage", CountryUtils.getCountryCodeByLanguage("Default")), CommonItemTitle("getCountryBySim", CountryUtils.getCountryBySim()), CommonItemTitle("getCountryByLanguage", CountryUtils.getCountryByLanguage()) ) } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/dangerous/DangerousActivity.kt ================================================ package com.blankj.subutil.pkg.feature.dangerous import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.subutil.pkg.Config import com.blankj.subutil.pkg.R import com.blankj.subutil.util.DangerousUtils import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/01 * desc : demo about dangerous * ``` */ class DangerousActivity : CommonActivity() { companion object { fun start(context: Context) { PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, DangerousActivity::class.java) context.startActivity(starter) } override fun onDenied() { } }, PermissionConstants.STORAGE, PermissionConstants.SMS) } } private val listener = object : OnReleasedListener { override fun onReleased() { if (DangerousUtils.installAppSilent(Config.TEST_APK_PATH)) { ToastUtils.showShort(R.string.dangerous_install_successfully) } else { ToastUtils.showShort(R.string.dangerous_install_unsuccessfully) } } } override fun bindTitleRes(): Int { return R.string.demo_dangerous } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.dangerous_install_silent) { if (AppUtils.isAppInstalled(Config.TEST_PKG)) { ToastUtils.showShort(R.string.dangerous_app_install_tips) } else { if (!FileUtils.isFileExists(Config.TEST_APK_PATH)) { ReleaseInstallApkTask(listener).execute() } else { listener.onReleased() } } }, CommonItemClick(R.string.dangerous_uninstall_silent) { if (AppUtils.isAppInstalled(Config.TEST_PKG)) { if (DangerousUtils.uninstallAppSilent(Config.TEST_PKG, false)) { ToastUtils.showShort(R.string.dangerous_uninstall_successfully) } else { ToastUtils.showShort(R.string.dangerous_uninstall_unsuccessfully) } } else { ToastUtils.showShort(R.string.dangerous_app_uninstall_tips) } }, CommonItemClick(R.string.dangerous_shutdown) { ToastUtils.showShort(DangerousUtils.shutdown().toString()) }, CommonItemClick(R.string.dangerous_reboot) { ToastUtils.showShort(DangerousUtils.reboot().toString()) }, CommonItemClick(R.string.dangerous_reboot_to_recovery) { ToastUtils.showShort(DangerousUtils.reboot2Recovery().toString()) }, CommonItemClick(R.string.dangerous_reboot_to_bootloader) { ToastUtils.showShort(DangerousUtils.reboot2Bootloader().toString()) }, CommonItemSwitch( R.string.dangerous_data_enabled, { NetworkUtils.getMobileDataEnabled() }, { if (AppUtils.isAppSystem()) { DangerousUtils.setMobileDataEnabled(it) } } ), CommonItemClick(R.string.dangerous_send_sms_silent) { DangerousUtils.sendSmsSilent("10000", "sendSmsSilent") } ) } } class ReleaseInstallApkTask(private val mListener: OnReleasedListener) : ThreadUtils.SimpleTask() { override fun doInBackground() { ResourceUtils.copyFileFromAssets("test_install", Config.TEST_APK_PATH) } override fun onSuccess(result: Unit) { mListener.onReleased() } fun execute() { ThreadUtils.executeByIo(this) } } interface OnReleasedListener { fun onReleased() } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/location/LocationActivity.kt ================================================ package com.blankj.subutil.pkg.feature.location import android.content.ComponentName import android.content.Context import android.content.Intent import android.content.ServiceConnection import android.os.IBinder import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.subutil.pkg.R import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.PermissionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about LocationUtils * ``` */ class LocationActivity : CommonActivity() { private var lastLatitude: String = "unknown" private var lastLongitude: String = "unknown" private var latitude: String = "unknown" private var longitude: String = "unknown" private var country: String = "unknown" private var locality: String = "unknown" private var street: String = "unknown" companion object { fun start(context: Context) { PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, LocationActivity::class.java) context.startActivity(starter) } override fun onDenied() { } }, PermissionConstants.LOCATION) } } private lateinit var mLocationService: LocationService private var conn: ServiceConnection = object : ServiceConnection { override fun onServiceDisconnected(name: ComponentName) {} override fun onServiceConnected(name: ComponentName, service: IBinder) { mLocationService = (service as LocationService.LocationBinder).service mLocationService.setOnGetLocationListener(object : LocationService.OnGetLocationListener { override fun getLocation(lastLatitude: String, lastLongitude: String, latitude: String, longitude: String, country: String, locality: String, street: String) { this@LocationActivity.apply { this.lastLatitude = lastLatitude this.lastLongitude = lastLongitude this.latitude = latitude this.longitude = longitude this.country = country this.locality = locality this.street = street } runOnUiThread { itemsView.updateItems(bindItems()) } } }) } } override fun bindTitleRes(): Int { return R.string.demo_location } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("lastLatitude", lastLatitude), CommonItemTitle("lastLongitude", lastLongitude), CommonItemTitle("latitude", latitude), CommonItemTitle("longitude", longitude), CommonItemTitle("getCountryName", country), CommonItemTitle("getLocality", locality), CommonItemTitle("getStreet", street) ) } override fun doBusiness() { bindService(Intent(this, LocationService::class.java), conn, Context.BIND_AUTO_CREATE) } override fun onDestroy() { unbindService(conn) super.onDestroy() } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/location/LocationService.kt ================================================ package com.blankj.subutil.pkg.feature.location import android.app.Service import android.content.Intent import android.location.Location import android.os.Binder import android.os.Bundle import android.os.IBinder import android.os.Looper import com.blankj.subutil.util.LocationUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/11/21 * desc : demo about LocationUtils * ``` */ class LocationService : Service() { private var isSuccess: Boolean = false private var lastLatitude = "loading..." private var lastLongitude = "loading..." private var latitude = "loading..." private var longitude = "loading..." private var country = "loading..." private var locality = "loading..." private var street = "loading..." private var mOnGetLocationListener: OnGetLocationListener? = null private val mOnLocationChangeListener = object : LocationUtils.OnLocationChangeListener { override fun getLastKnownLocation(location: Location) { lastLatitude = location.latitude.toString() lastLongitude = location.longitude.toString() mOnGetLocationListener?.getLocation(lastLatitude, lastLongitude, latitude, longitude, country, locality, street) } override fun onLocationChanged(location: Location) { latitude = location.latitude.toString() longitude = location.longitude.toString() mOnGetLocationListener?.getLocation(lastLatitude, lastLongitude, latitude, longitude, country, locality, street) country = LocationUtils.getCountryName(java.lang.Double.parseDouble(latitude), java.lang.Double.parseDouble(longitude)) locality = LocationUtils.getLocality(java.lang.Double.parseDouble(latitude), java.lang.Double.parseDouble(longitude)) street = LocationUtils.getStreet(java.lang.Double.parseDouble(latitude), java.lang.Double.parseDouble(longitude)) mOnGetLocationListener?.getLocation(lastLatitude, lastLongitude, latitude, longitude, country, locality, street) } override fun onStatusChanged(provider: String, status: Int, extras: Bundle) {} } fun setOnGetLocationListener(onGetLocationListener: OnGetLocationListener) { mOnGetLocationListener = onGetLocationListener } override fun onCreate() { super.onCreate() Thread(Runnable { Looper.prepare() isSuccess = LocationUtils.register(0, 0, mOnLocationChangeListener) if (isSuccess) ToastUtils.showShort("init success") Looper.loop() }).start() } override fun onBind(intent: Intent): IBinder? { return LocationBinder() } inner class LocationBinder : Binder() { val service: LocationService get() = this@LocationService } override fun onDestroy() { LocationUtils.unregister() // 一定要制空,否则内存泄漏 mOnGetLocationListener = null super.onDestroy() } /** * 获取位置监听器 */ interface OnGetLocationListener { fun getLocation( lastLatitude: String, lastLongitude: String, latitude: String, longitude: String, country: String, locality: String, street: String ) } } ================================================ FILE: feature/subutil/pkg/src/main/java/com/blankj/subutil/pkg/feature/pinyin/PinyinActivity.kt ================================================ package com.blankj.subutil.pkg.feature.pinyin import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.subutil.pkg.R import com.blankj.subutil.util.PinyinUtils import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/01 * desc : demo about PinyinUtils * ``` */ class PinyinActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, PinyinActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_pinyin } override fun bindItems(): MutableList> { val surnames = "乐乘乜仇会便区单参句召员宓弗折曾朴查洗盖祭种秘繁缪能蕃覃解谌适都阿难黑" val size = surnames.length val sb = StringBuilder("澹台: " + PinyinUtils.getSurnamePinyin("澹台") + "\n尉迟: " + PinyinUtils.getSurnamePinyin("尉迟") + "\n万俟: " + PinyinUtils.getSurnamePinyin("万俟") + "\n单于: " + PinyinUtils.getSurnamePinyin("单于")) for (i in 0 until size) { val surname = surnames[i].toString() sb.append(String.format( "\n%s 正确: %-8s 错误: %-8s", surname, PinyinUtils.getSurnamePinyin(surname), PinyinUtils.ccs2Pinyin(surname) )) } return CollectionUtils.newArrayList( CommonItemTitle("汉字转拼音", PinyinUtils.ccs2Pinyin("汉字转拼音", " ")), CommonItemTitle("获取首字母", PinyinUtils.getPinyinFirstLetters("获取首字母", " ")), CommonItemTitle("测试姓氏", sb.toString()) ) } } ================================================ FILE: feature/subutil/pkg/src/main/res/values/strings.xml ================================================ App Store Demo Battery Demo Country Demo Dangerous Demo LocationUtils Demo PinyinUtils Demo Go System App Store In WeChat Page Install Test App Silently Uninstall App Silently Test app have installed Install successfully Install unsuccessfully Please install test app first Uninstall successfully Uninstall unsuccessfully Shutdown Reboot Reboot To Recovery Reboot To Bootloader Send SMS Silent Mobile Data Enabled ================================================ FILE: feature/utilcode/app/.gitignore ================================================ /build ================================================ FILE: feature/utilcode/app/build.gradle ================================================ ================================================ FILE: feature/utilcode/app/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/utilcode/app/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/utilcode/app/src/main/java/com/blankj/utilcode/app/UtilCodeApp.kt ================================================ package com.blankj.utilcode.app import com.blankj.common.CommonApplication import com.blankj.utilcode.util.Utils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/12 * desc : app about utils * ``` */ class UtilCodeApp : CommonApplication() { companion object { lateinit var instance: UtilCodeApp private set } override fun onCreate() { Utils.init(this) super.onCreate() instance = this // BusUtils.register("com.blankj.androidutilcode") } } ================================================ FILE: feature/utilcode/export/.gitignore ================================================ /build ================================================ FILE: feature/utilcode/export/build.gradle ================================================ ext { groupId = Config.modules.feature_utilcode_export.groupId artifactId = Config.modules.feature_utilcode_export.artifactId version = Config.modules.feature_utilcode_export.version website = "https://github.com/Blankj/AndroidUtilCode" } //apply from: "${rootDir.path}/config/publish.gradle" //./gradlew :feature_utilcode_export:mavenLocal // 上传到本地 mavenLocal ================================================ FILE: feature/utilcode/export/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/utilcode/export/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/utilcode/export/src/main/java/com/blankj/utilcode/export/api/UtilCodeApi.java ================================================ package com.blankj.utilcode.export.api; import android.content.Context; import com.blankj.utilcode.util.ApiUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/01
 *     desc  :
 * 
*/ public abstract class UtilCodeApi extends ApiUtils.BaseApi { public abstract void startUtilCodeActivity(Context context); public abstract void testCallback(Callback callback); public interface Callback { void call(); } } ================================================ FILE: feature/utilcode/pkg/.gitignore ================================================ /build ================================================ FILE: feature/utilcode/pkg/build.gradle ================================================ ================================================ FILE: feature/utilcode/pkg/proguard-rules.pro ================================================ # Add project specific ProGuard rules here. # You can control the set of applied configuration files using the # proguardFiles setting in build.gradle. # # For more details, see # http://developer.android.com/guide/developing/tools/proguard.html # If your project uses WebView with JS, uncomment the following # and specify the fully qualified class name to the JavaScript interface # class: #-keepclassmembers class fqcn.of.javascript.interface.for.webview { # public *; #} # Uncomment this to preserve the line number information for # debugging stack traces. #-keepattributes SourceFile,LineNumberTable # If you keep the line number information, uncomment this to # hide the original source file name. #-renamesourcefileattribute SourceFile ================================================ FILE: feature/utilcode/pkg/src/main/AndroidManifest.xml ================================================ ================================================ FILE: feature/utilcode/pkg/src/main/assets/test/sub/test.txt ================================================ 1st line 2nd line ================================================ FILE: feature/utilcode/pkg/src/main/assets/test/test.txt ================================================ 1st line 2nd line ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/Config.kt ================================================ package com.blankj.utilcode.pkg import com.blankj.utilcode.util.PathUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/10 * desc : config about constants * ``` */ object Config { val FILE_SEP = System.getProperty("file.separator") val LINE_SEP = System.getProperty("line.separator") const val TEST_PKG = "com.blankj.testinstall" val CACHE_PATH = PathUtils.getCachePathExternalFirst() + FILE_SEP val TEST_APK_PATH: String = CACHE_PATH + "test_install.apk" } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/UtilCodeApiImpl.java ================================================ package com.blankj.utilcode.pkg; import android.content.Context; import com.blankj.utilcode.export.api.UtilCodeApi; import com.blankj.utilcode.pkg.feature.CoreUtilActivity; import com.blankj.utilcode.util.ApiUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/01
 *     desc  :
 * 
*/ @ApiUtils.Api public class UtilCodeApiImpl extends UtilCodeApi { @Override public void startUtilCodeActivity(Context context) { CoreUtilActivity.Companion.start(context); } @Override public void testCallback(Callback callback) { if (callback != null) { callback.call(); } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/CoreUtilActivity.kt ================================================ package com.blankj.utilcode.pkg.feature import android.content.Context import android.content.Intent import android.os.Bundle import android.widget.TextView import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.feature.activity.ActivityActivity import com.blankj.utilcode.pkg.feature.adaptScreen.AdaptScreenActivity import com.blankj.utilcode.pkg.feature.api.ApiActivity import com.blankj.utilcode.pkg.feature.app.AppActivity import com.blankj.utilcode.pkg.feature.bar.BarActivity import com.blankj.utilcode.pkg.feature.brightness.BrightnessActivity import com.blankj.utilcode.pkg.feature.bus.BusActivity import com.blankj.utilcode.pkg.feature.clean.CleanActivity import com.blankj.utilcode.pkg.feature.click.ClickActivity import com.blankj.utilcode.pkg.feature.clipboard.ClipboardActivity import com.blankj.utilcode.pkg.feature.device.DeviceActivity import com.blankj.utilcode.pkg.feature.file.FileActivity import com.blankj.utilcode.pkg.feature.flashlight.FlashlightActivity import com.blankj.utilcode.pkg.feature.fragment.FragmentActivity import com.blankj.utilcode.pkg.feature.image.ImageActivity import com.blankj.utilcode.pkg.feature.intent.IntentActivity import com.blankj.utilcode.pkg.feature.keyboard.KeyboardActivity import com.blankj.utilcode.pkg.feature.language.LanguageActivity import com.blankj.utilcode.pkg.feature.log.LogActivity import com.blankj.utilcode.pkg.feature.messenger.MessengerActivity import com.blankj.utilcode.pkg.feature.metaData.MetaDataActivity import com.blankj.utilcode.pkg.feature.mvp.MvpActivity import com.blankj.utilcode.pkg.feature.network.NetworkActivity import com.blankj.utilcode.pkg.feature.notification.NotificationActivity import com.blankj.utilcode.pkg.feature.path.PathActivity import com.blankj.utilcode.pkg.feature.permission.PermissionActivity import com.blankj.utilcode.pkg.feature.phone.PhoneActivity import com.blankj.utilcode.pkg.feature.process.ProcessActivity import com.blankj.utilcode.pkg.feature.reflect.ReflectActivity import com.blankj.utilcode.pkg.feature.resource.ResourceActivity import com.blankj.utilcode.pkg.feature.rom.RomActivity import com.blankj.utilcode.pkg.feature.screen.ScreenActivity import com.blankj.utilcode.pkg.feature.sdcard.SDCardActivity import com.blankj.utilcode.pkg.feature.shadow.ShadowActivity import com.blankj.utilcode.pkg.feature.snackbar.SnackbarActivity import com.blankj.utilcode.pkg.feature.spStatic.SPStaticActivity import com.blankj.utilcode.pkg.feature.span.SpanActivity import com.blankj.utilcode.pkg.feature.toast.ToastActivity import com.blankj.utilcode.pkg.feature.uiMessage.UiMessageActivity import com.blankj.utilcode.pkg.feature.vibrate.VibrateActivity import com.blankj.utilcode.pkg.feature.volume.VolumeActivity import com.blankj.utilcode.pkg.helper.DialogHelper import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.LogUtils import com.blankj.utilcode.util.ThreadUtils import com.blankj.utilcode.util.UtilsTransActivity /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : * ``` */ class CoreUtilActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, CoreUtilActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.core_util } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.demo_activity, true) { ActivityActivity.start(this) ThreadUtils.runOnUiThreadDelayed(Runnable { }, 2000) }, CommonItemClick(R.string.demo_adapt_screen, true) { AdaptScreenActivity.start(this) }, CommonItemClick(R.string.demo_api, true) { ApiActivity.start(this) }, CommonItemClick(R.string.demo_app, true) { AppActivity.start(this) }, CommonItemClick(R.string.demo_bar, true) { BarActivity.start(this) }, CommonItemClick(R.string.demo_brightness, true) { BrightnessActivity.start(this) }, CommonItemClick(R.string.demo_bus, true) { BusActivity.start(this) }, CommonItemClick(R.string.demo_clean, true) { CleanActivity.start(this) }, CommonItemClick(R.string.demo_click, true) { ClickActivity.start(this) }, CommonItemClick(R.string.demo_clipboard, true) { ClipboardActivity.start(this) }, CommonItemClick(R.string.demo_crash) { throw NullPointerException("crash test") }, CommonItemClick(R.string.demo_device, true) { DeviceActivity.start(this) }, CommonItemClick(R.string.demo_file, true) { FileActivity.start(this) }, CommonItemClick(R.string.demo_flashlight, true) { FlashlightActivity.start(this) }, CommonItemClick(R.string.demo_fragment, true) { FragmentActivity.start(this) }, CommonItemClick(R.string.demo_image, true) { ImageActivity.start(this) }, CommonItemClick(R.string.demo_intent, true) { IntentActivity.start(this) }, CommonItemClick(R.string.demo_keyboard, true) { KeyboardActivity.start(this) }, CommonItemClick(R.string.demo_language, true) { LanguageActivity.start(this) }, CommonItemClick(R.string.demo_log, true) { LogActivity.start(this) }, CommonItemClick(R.string.demo_messenger, true) { MessengerActivity.start(this) }, CommonItemClick(R.string.demo_meta_data, true) { MetaDataActivity.start(this) }, CommonItemClick(R.string.demo_mvp, true) { MvpActivity.start(this) }, CommonItemClick(R.string.demo_network, true) { NetworkActivity.start(this) }, CommonItemClick(R.string.demo_notification, true) { NotificationActivity.start(this) }, CommonItemClick(R.string.demo_path, true) { PathActivity.start(this) }, CommonItemClick(R.string.demo_permission, true) { PermissionActivity.start(this) }, CommonItemClick(R.string.demo_phone, true) { PhoneActivity.start(this) }, CommonItemClick(R.string.demo_process, true) { ProcessActivity.start(this) }, CommonItemClick(R.string.demo_reflect, true) { ReflectActivity.start(this) }, CommonItemClick(R.string.demo_resource, true) { ResourceActivity.start(this) }, CommonItemClick(R.string.demo_rom, true) { RomActivity.start(this) }, CommonItemClick(R.string.demo_screen, true) { ScreenActivity.start(this) }, CommonItemClick(R.string.demo_sdcard, true) { SDCardActivity.start(this) }, CommonItemClick(R.string.demo_shadow, true) { ShadowActivity.start(this) }, CommonItemClick(R.string.demo_snackbar, true) { SnackbarActivity.start(this) }, CommonItemClick(R.string.demo_spStatic, true) { SPStaticActivity.start(this) }, CommonItemClick(R.string.demo_span, true) { SpanActivity.start(this) }, CommonItemClick(R.string.demo_toast, true) { ToastActivity.start(this) }, CommonItemClick(R.string.demo_trans_activity, true) { UtilsTransActivity.start(this, object : UtilsTransActivity.TransActivityDelegate() { override fun onCreated(activity: UtilsTransActivity, savedInstanceState: Bundle?) { super.onCreated(activity, savedInstanceState) activity.setContentView(R.layout.common_dialog_loading) activity.findViewById(R.id.utilActionLoadingMsgTv).text = "Trans Activity is showing..." } }) }, CommonItemClick(R.string.demo_uiMessage, true) { UiMessageActivity.start(this) }, CommonItemClick(R.string.demo_vibrate, true) { VibrateActivity.start(this) }, CommonItemClick(R.string.demo_volume, true) { VolumeActivity.start(this) } ) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) LogUtils.e(requestCode, requestCode) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/ActivityActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.activity import android.content.Context import android.content.Intent import android.graphics.drawable.BitmapDrawable import android.os.Bundle import android.widget.ImageView import androidx.core.app.ActivityOptionsCompat import com.blankj.base.rv.ItemViewHolder import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemImage import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.feature.CoreUtilActivity import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.AppUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.StringUtils import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about ActivityUtils * ``` */ class ActivityActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ActivityActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_activity } override fun bindItems(): List> { val elementItem = ActivityItem() val intent = Intent(this, SubActivityActivity::class.java) val intents = arrayOfNulls(2) intents[0] = intent intents[1] = Intent(this, SubActivityActivity::class.java) return CollectionUtils.newArrayList( elementItem, CommonItemTitle("isActivityExists(${SubActivityActivity::class.java.name})", ActivityUtils.isActivityExists(AppUtils.getAppPackageName(), SubActivityActivity::class.java.name).toString()), CommonItemTitle("getLauncherActivity", ActivityUtils.getLauncherActivity(AppUtils.getAppPackageName())), CommonItemTitle("getMainActivities", ActivityUtils.getMainActivities().toString()), CommonItemTitle("getActivityList", CollectionUtils.collect(ActivityUtils.getActivityList()) { input -> input.javaClass.simpleName }.toString()), CommonItemTitle("getTopActivity", ActivityUtils.getTopActivity().toString()), CommonItemTitle("isActivityExistsInStack", ActivityUtils.isActivityExistsInStack(CoreUtilActivity::class.java).toString()), CommonItemImage("getActivityIcon") { it.setImageDrawable(ActivityUtils.getActivityIcon(ActivityActivity::class.java)) }, CommonItemImage("getActivityLogo") { it.setImageDrawable(ActivityUtils.getActivityLogo(ActivityActivity::class.java)) }, CommonItemClick(R.string.activity_clz, true) { ActivityUtils.startActivity(SubActivityActivity::class.java) }, CommonItemClick(R.string.activity_clz_opt, true) { ActivityUtils.startActivity(SubActivityActivity::class.java, getOption(elementItem)) }, CommonItemClick(R.string.activity_clz_anim, true) { ActivityUtils.startActivity(SubActivityActivity::class.java, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_act_clz, true) { ActivityUtils.startActivity(this, SubActivityActivity::class.java) }, CommonItemClick(R.string.activity_act_clz_shared_element, true) { ActivityUtils.startActivity(this, SubActivityActivity::class.java, elementItem.element) }, CommonItemClick(R.string.activity_act_clz_anim, true) { ActivityUtils.startActivity(this, SubActivityActivity::class.java, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_pkg_cls, true) { ActivityUtils.startActivity(this.packageName, SubActivityActivity::class.java.name) }, CommonItemClick(R.string.activity_pkg_cls_opt, true) { ActivityUtils.startActivity(this.packageName, SubActivityActivity::class.java.name, getOption(elementItem)) }, CommonItemClick(R.string.activity_pkg_cls_anim, true) { ActivityUtils.startActivity(this.packageName, SubActivityActivity::class.java.name, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_act_pkg_cls, true) { ActivityUtils.startActivity(this, this.packageName, SubActivityActivity::class.java.name) }, CommonItemClick(R.string.activity_act_pkg_cls_opt, true) { ActivityUtils.startActivity(this, this.packageName, SubActivityActivity::class.java.name, getOption(elementItem)) }, CommonItemClick(R.string.activity_act_pkg_cls_shared_element, true) { ActivityUtils.startActivity(this, this.packageName, SubActivityActivity::class.java.name, elementItem.element) }, CommonItemClick(R.string.activity_act_pkg_cls_anim, true) { ActivityUtils.startActivity(this, this.packageName, SubActivityActivity::class.java.name, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_intent, true) { ActivityUtils.startActivity(this, intent) }, CommonItemClick(R.string.activity_intent_opt, true) { ActivityUtils.startActivity(this, intent, getOption(elementItem)) }, CommonItemClick(R.string.activity_intent_shared_element, true) { ActivityUtils.startActivity(this, intent, elementItem.element) }, CommonItemClick(R.string.activity_intent_anim, true) { ActivityUtils.startActivity(this, intent, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_intents, true) { ActivityUtils.startActivities(intents) }, CommonItemClick(R.string.activity_intents_opt, true) { ActivityUtils.startActivities(intents, getOption(elementItem)) }, CommonItemClick(R.string.activity_intents_anim, true) { ActivityUtils.startActivities(intents, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_act_intents, true) { ActivityUtils.startActivities(this, intents, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_act_intents_opt, true) { ActivityUtils.startActivities(this, intents, getOption(elementItem)) }, CommonItemClick(R.string.activity_act_intents_anim, true) { ActivityUtils.startActivities(this, intents, R.anim.fade_in_1000, R.anim.fade_out_1000) }, CommonItemClick(R.string.activity_start_home_activity, true) { ActivityUtils.startHomeActivity() }, CommonItemClick(R.string.activity_start_launcher_activity, true) { ActivityUtils.startLauncherActivity() }, CommonItemClick(R.string.activity_finish_activity, false) { ActivityUtils.finishActivity(CoreUtilActivity::class.java) }, CommonItemClick(R.string.activity_finish_to_activity, true) { ActivityUtils.finishToActivity(CoreUtilActivity::class.java, false, true) }, CommonItemClick(R.string.activity_finish_all_activities_except_newest, true) { ActivityUtils.finishAllActivitiesExceptNewest() }, CommonItemClick(R.string.activity_finish_all_activities, true) { ActivityUtils.finishAllActivities() } ) } private fun getOption(activityItem: ActivityItem): Bundle? { when (Random().nextInt(5)) { 0 -> return ActivityOptionsCompat.makeCustomAnimation(this, R.anim.slide_right_in_1000, R.anim.slide_left_out_1000) .toBundle() 1 -> return ActivityOptionsCompat.makeScaleUpAnimation(activityItem.element, activityItem.element.width / 2, activityItem.element.height / 2, 0, 0) .toBundle() 2 -> return ActivityOptionsCompat.makeThumbnailScaleUpAnimation(activityItem.element, (activityItem.element.drawable as BitmapDrawable).bitmap, 0, 0) .toBundle() 3 -> return ActivityOptionsCompat.makeSceneTransitionAnimation(this, activityItem.element, StringUtils.getString(R.string.activity_shared_element)) .toBundle() else -> return ActivityOptionsCompat.makeClipRevealAnimation(activityItem.element, activityItem.element.width / 2, activityItem.element.height / 2, 0, 0) .toBundle() } } } class ActivityItem : CommonItem { lateinit var element: ImageView; constructor() : super(R.layout.activity_item_shared_element_activity) override fun bind(holder: ItemViewHolder, position: Int) { super.bind(holder, position) element = holder.findViewById(R.id.activityViewSharedElement) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/activity/SubActivityActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.activity import android.app.Activity import android.content.Intent import android.os.Bundle import androidx.core.app.ActivityCompat import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.ColorUtils import kotlinx.android.synthetic.main.activity_sub_activity.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about ActivityUtils * ``` */ class SubActivityActivity : CommonActivity() { override fun bindLayout(): Int { return R.layout.activity_sub_activity } override fun bindTitleRes(): Int { return R.string.demo_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) contentView?.setBackgroundColor(ColorUtils.getRandomColor(false)) activityViewSharedElement.setOnClickListener { val result = Intent() result.putExtra("data", "data") this@SubActivityActivity.setResult(Activity.RESULT_OK, result) this@SubActivityActivity.finish() } } override fun onBackPressed() { super.onBackPressed() ActivityCompat.finishAfterTransition(this) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/adaptScreen/AdaptCloseActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.adaptScreen import android.content.Context import android.content.Intent import android.content.res.Resources import android.os.Bundle import android.view.View import android.view.WindowManager import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.AdaptScreenUtils class AdaptCloseActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, AdaptCloseActivity::class.java) context.startActivity(starter) } } override fun bindLayout(): Int { return R.layout.adaptscreen_close_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) } override fun getResources(): Resources { return AdaptScreenUtils.closeAdapt(super.getResources()) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/adaptScreen/AdaptHeightActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.adaptScreen import android.content.Context import android.content.Intent import android.content.res.Resources import android.os.Bundle import android.view.View import android.view.WindowManager import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.AdaptScreenUtils import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.LogUtils class AdaptHeightActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, AdaptHeightActivity::class.java) context.startActivity(starter) } } override fun bindLayout(): Int { return R.layout.adaptscreen_height_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) } override fun onResume() { super.onResume() LogUtils.e(BarUtils.getStatusBarHeight()) } override fun getResources(): Resources { return AdaptScreenUtils.adaptHeight(super.getResources(), 1920) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/adaptScreen/AdaptScreenActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.adaptScreen import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils class AdaptScreenActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, AdaptScreenActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_adapt_screen } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemClick(R.string.adaptScreen_adapt_width, true) { AdaptWidthActivity.start(this) }, CommonItemClick(R.string.adaptScreen_adapt_height, true) { AdaptHeightActivity.start(this) }, CommonItemClick(R.string.adaptScreen_adapt_close, true) { AdaptCloseActivity.start(this) } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/adaptScreen/AdaptWidthActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.adaptScreen import android.content.Context import android.content.Intent import android.content.res.Resources import android.graphics.Color import android.os.Bundle import android.view.View import android.view.WindowManager import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.AdaptScreenUtils import kotlinx.android.synthetic.main.adaptscreen_width_activity.* class AdaptWidthActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, AdaptWidthActivity::class.java) context.startActivity(starter) } } override fun bindLayout(): Int { return R.layout.adaptscreen_width_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) window.addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN) adaptScreenWidthWebView.setBackgroundColor(Color.parseColor("#f0d26d")) } override fun getResources(): Resources { return AdaptScreenUtils.adaptWidth(super.getResources(), 1080) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/api/ApiActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.api import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.feature.api.other.export.OtherModuleApi import com.blankj.utilcode.util.ApiUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/03/12 * desc : demo about ApiUtils * ``` */ class ApiActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ApiActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_api } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.api_invoke_with_params) { ApiUtils.getApi(OtherModuleApi::class.java)?.invokeWithParams(OtherModuleApi.ApiBean("params")) }, CommonItemClick(R.string.api_invoke_with_return_value) { ToastUtils.showShort(ApiUtils.getApi(OtherModuleApi::class.java)?.invokeWithReturnValue()?.name) } ); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/api/other/export/OtherModuleApi.java ================================================ package com.blankj.utilcode.pkg.feature.api.other.export; import com.blankj.utilcode.util.ApiUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/10
 *     desc  : demo about ApiUtils
 * 
*/ public abstract class OtherModuleApi extends ApiUtils.BaseApi { public abstract void invokeWithParams(ApiBean bean); public abstract ApiBean invokeWithReturnValue(); public static class ApiBean { public String name; public ApiBean(String name) { this.name = name; } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/api/other/pkg/OtherPkgApiImpl.java ================================================ package com.blankj.utilcode.pkg.feature.api.other.pkg; import com.blankj.utilcode.pkg.feature.api.other.export.OtherModuleApi; import com.blankj.utilcode.util.ApiUtils; import com.blankj.utilcode.util.ToastUtils; /** *
 *     author: Blankj
 *     blog  : http://blankj.com
 *     time  : 2019/07/10
 *     desc  : demo about ApiUtils
 * 
*/ @ApiUtils.Api public class OtherPkgApiImpl extends OtherModuleApi { @Override public void invokeWithParams(ApiBean bean) { ToastUtils.showShort(bean.name); } @Override public ApiBean invokeWithReturnValue() { String value = "value"; return new ApiBean(value); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/app/AppActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.app import android.app.Activity import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.* import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.pkg.Config import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about AppUtils * ``` */ class AppActivity : CommonActivity(), Utils.OnAppStatusChangedListener { var isRegisterAppStatusChangedListener: Boolean = false companion object { fun start(context: Context) { PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, AppActivity::class.java) context.startActivity(starter) } override fun onDenied() { } }, PermissionConstants.STORAGE) } } private val listener = object : OnReleasedListener { override fun onReleased() { return AppUtils.installApp(Config.TEST_APK_PATH) } } override fun bindTitleRes(): Int { return R.string.demo_app } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) LogUtils.e(requestCode, resultCode) } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemSwitch( "registerAppStatusChangedListener", { isRegisterAppStatusChangedListener }, { isRegisterAppStatusChangedListener = it if (it) { AppUtils.registerAppStatusChangedListener(this) } else { AppUtils.unregisterAppStatusChangedListener(this) } }), CommonItemTitle("isAppRoot", AppUtils.isAppRoot().toString()), CommonItemTitle("isAppDebug", AppUtils.isAppDebug().toString()), CommonItemTitle("isAppSystem", AppUtils.isAppSystem().toString()), CommonItemTitle( "isAppForeground", AppUtils.isAppForeground(AppUtils.getAppPackageName()).toString() ), CommonItemTitle( "isAppRunning", AppUtils.isAppRunning(AppUtils.getAppPackageName()).toString() ), CommonItemImage("getAppIcon") { it.setImageDrawable(AppUtils.getAppIcon()) }, CommonItemTitle("getAppPackageName", AppUtils.getAppPackageName()), CommonItemTitle("getAppName", AppUtils.getAppName()), CommonItemTitle("getAppPath", AppUtils.getAppPath()), CommonItemTitle("getAppVersionName", AppUtils.getAppVersionName()), CommonItemTitle("getAppVersionCode", AppUtils.getAppVersionCode().toString()), CommonItemTitle("getAppMinSdkVersion", AppUtils.getAppMinSdkVersion().toString()), CommonItemTitle("getAppTargetSdkVersion", AppUtils.getAppTargetSdkVersion().toString()), CommonItemTitle("getAppSignaturesSHA1", AppUtils.getAppSignaturesSHA1().toString()), CommonItemTitle("getAppSignaturesSHA256", AppUtils.getAppSignaturesSHA256().toString()), CommonItemTitle("getAppSignaturesMD5", AppUtils.getAppSignaturesMD5().toString()), CommonItemTitle("getAppUid", AppUtils.getAppUid().toString()), CommonItemTitle("getApkInfo", AppUtils.getApkInfo(AppUtils.getAppPath()).toString()), CommonItemClick(R.string.app_install) { if (AppUtils.isAppInstalled(Config.TEST_PKG)) { ToastUtils.showShort(R.string.app_install_tips) } else { if (!FileUtils.isFileExists(Config.TEST_APK_PATH)) { ReleaseInstallApkTask(listener).execute() } else { listener.onReleased() } } }, CommonItemClick(R.string.app_uninstall) { if (AppUtils.isAppInstalled(Config.TEST_PKG)) { AppUtils.uninstallApp(Config.TEST_PKG) } else { ToastUtils.showShort(R.string.app_uninstall_tips) } }, CommonItemClick(R.string.app_launch) { AppUtils.launchApp(this.packageName) }, CommonItemClick(R.string.app_relaunch) { AppUtils.relaunchApp() }, CommonItemClick(R.string.app_launch_details_settings, true) { AppUtils.launchAppDetailsSettings() }, CommonItemClick(R.string.app_exit) { AppUtils.exitApp() } ) } override fun onForeground(activity: Activity) { ToastUtils.showShort("onForeground\n${activity.javaClass.simpleName}") } override fun onBackground(activity: Activity) { ToastUtils.showShort("onBackground\n${activity.javaClass.simpleName}") } override fun onDestroy() { super.onDestroy() if (isRegisterAppStatusChangedListener) { AppUtils.unregisterAppStatusChangedListener(this) } } } class ReleaseInstallApkTask(private val mListener: OnReleasedListener) : ThreadUtils.SimpleTask() { override fun doInBackground() { ResourceUtils.copyFileFromAssets("test_install", Config.TEST_APK_PATH) } override fun onSuccess(result: Unit) { mListener.onReleased() } fun execute() { ThreadUtils.executeByIo(this) } } interface OnReleasedListener { fun onReleased() } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/BarActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bar import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.feature.bar.nav.BarNavActivity import com.blankj.utilcode.pkg.feature.bar.notification.BarNotificationActivity import com.blankj.utilcode.pkg.feature.bar.status.* import com.blankj.utilcode.pkg.feature.bar.status.fragment.BarStatusFragmentActivity import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/27 * desc : demo about BarUtils * ``` */ class BarActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_bar } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemTitle(R.string.bar_about_status_bar, true), CommonItemClick(R.string.bar_status_about, true) { BarStatusActivity.start(this) }, CommonItemClick(R.string.bar_status_set_color, true) { BarStatusActivityColor.start(this) }, CommonItemClick(R.string.bar_status_set_alpha, true) { BarStatusActivityAlpha.start(this) }, CommonItemClick(R.string.bar_status_set_image_view, true) { BarStatusActivityImageView.start(this) }, CommonItemClick(R.string.bar_status_set_custom, true) { BarStatusActivityCustom.start(this) }, CommonItemClick(R.string.bar_status_set_fragment, true) { BarStatusFragmentActivity.start(this) }, CommonItemClick(R.string.bar_status_set_drawer, true) { BarStatusActivityDrawer.start(this) }, CommonItemTitle(R.string.bar_about_notification_bar, true), CommonItemClick(R.string.bar_notification_about, true) { BarNotificationActivity.start(this) }, CommonItemTitle(R.string.bar_about_nav_bar, true), CommonItemClick(R.string.bar_nav_about, true) { BarNavActivity.start(this) } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/nav/BarNavActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.nav import android.content.Context import android.content.Intent import android.os.Build import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about BarUtils * ``` */ class BarNavActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarNavActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_bar } override fun bindItems(): List> { return CollectionUtils.newArrayList>().apply { add(CommonItemTitle("navHeight", BarUtils.getNavBarHeight().toString())) add(CommonItemTitle("isSupportNavBar", BarUtils.isSupportNavBar().toString())) if (BarUtils.isSupportNavBar()) { add(CommonItemSwitch( R.string.bar_nav_visibility, { BarUtils.isNavBarVisible(this@BarNavActivity) }, { BarUtils.setNavBarVisibility(this@BarNavActivity, it) } )) add(CommonItemSwitch( R.string.bar_nav_light_mode, { BarUtils.isNavBarLightMode(this@BarNavActivity) }, { BarUtils.setNavBarLightMode(this@BarNavActivity, it) } )) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { add( CommonItemClick( "getNavBarColor: ${ ColorUtils.int2ArgbString( BarUtils.getNavBarColor( this@BarNavActivity ) ) }" ).setOnItemClickListener() { _, item, _ -> BarUtils.setNavBarColor( this@BarNavActivity, ColorUtils.getRandomColor() ) itemsView.updateItems(bindItems()) item.title = "getNavBarColor: ${ ColorUtils.int2ArgbString( BarUtils.getNavBarColor(this@BarNavActivity) ) }" }) } add(CommonItemClick("transparentNavBar").setOnItemClickListener() { _, item, _ -> BarUtils.transparentNavBar(this@BarNavActivity) }) } } } override fun onWindowFocusChanged(hasFocus: Boolean) { super.onWindowFocusChanged(hasFocus) itemsView.updateItems(bindItems()) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/notification/BarNotificationActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.notification import android.content.Context import android.content.Intent import android.os.Handler import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about BarUtils * ``` */ class BarNotificationActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarNotificationActivity::class.java) context.startActivity(starter) } } private val mHandler = Handler() override fun bindTitleRes(): Int { return R.string.demo_bar } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemClick(R.string.bar_notification_show) { BarUtils.setNotificationBarVisibility(true) mHandler.postDelayed({ BarUtils.setNotificationBarVisibility(false) }, 2000) } ) } override fun onDestroy() { super.onDestroy() mHandler.removeCallbacksAndMessages(null) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/BarStatusActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.Utils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about BarUtils * ``` */ class BarStatusActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_bar } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("getStatusBarHeight", BarUtils.getStatusBarHeight().toString()), CommonItemSwitch( R.string.bar_status_visibility, { BarUtils.isStatusBarVisible(this) }, { BarUtils.setStatusBarVisibility(this, it) } ), CommonItemSwitch( R.string.bar_status_light_mode, { BarUtils.isStatusBarLightMode(this) }, { BarUtils.setStatusBarLightMode(this, it) } ) ) } override fun onResume() { super.onResume() itemsView.updateItems(bindItems()) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/BarStatusActivityAlpha.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Bundle import android.view.View import android.widget.SeekBar import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSeekBar import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/27 * desc : demo about BarUtils * ``` */ class BarStatusActivityAlpha : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusActivityAlpha::class.java) context.startActivity(starter) } } private var mAlpha: Int = 112 override fun bindLayout(): Int { return R.layout.bar_status_alpha_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(findViewById(R.id.commonItemRv), getItems()) updateStatusBar() } private fun getItems(): List> { return CollectionUtils.newArrayList>( CommonItemSeekBar("Status Bar Alpha", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return mAlpha } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { mAlpha = progress updateStatusBar() } }).apply { backgroundColor = ColorUtils.setAlphaComponent(backgroundColor, 0.5f) } ) } private fun updateStatusBar() { BarUtils.setStatusBarColor(this, Color.argb(mAlpha, 0, 0, 0)) BarUtils.addMarginTopEqualStatusBarHeight(findViewById(R.id.commonItemRv))// 其实这个只需要调用一次即可 } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/BarStatusActivityColor.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/27 * desc : demo about BarUtils * ``` */ class BarStatusActivityColor : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusActivityColor::class.java) context.startActivity(starter) } } private var mColor: Int = ColorUtils.getColor(R.color.colorPrimary) override fun bindItems(): List> { return CollectionUtils.newArrayList>( CommonItemClick(R.string.bar_status_random_color, ColorUtils.int2ArgbString(mColor)).setOnClickUpdateContentListener { mColor = ColorUtils.getRandomColor() updateStatusBar() return@setOnClickUpdateContentListener ColorUtils.int2ArgbString(mColor) } ) } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) updateStatusBar() } private fun updateStatusBar() { BarUtils.setStatusBarColor(this, mColor) BarUtils.addMarginTopEqualStatusBarHeight(findViewById(R.id.commonItemRv))// 其实这个只需要调用一次即可 } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/BarStatusActivityCustom.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/01/14 * desc : demo about BarUtils * ``` */ class BarStatusActivityCustom : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusActivityCustom::class.java) context.startActivity(starter) } } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) BarUtils.setStatusBarColor(this, Color.TRANSPARENT).setBackgroundResource(R.drawable.bar_status_custom) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/BarStatusActivityDrawer.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Bundle import android.view.View import android.widget.SeekBar import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSeekBar import com.blankj.common.item.CommonItemSwitch import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils import kotlinx.android.synthetic.main.bar_status_drawer_activity.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/27 * desc : demo about BarUtils * ``` */ class BarStatusActivityDrawer : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusActivityDrawer::class.java) context.startActivity(starter) } } private var mColor: Int = ColorUtils.getColor(R.color.colorPrimary) private var mAlpha: Int = 112 private var mAlphaStatus: Boolean = false private var mFrontStatus: Boolean = false override fun isSwipeBack(): Boolean { return false } override fun bindDrawer(): Boolean { return true } override fun bindLayout(): Int { return R.layout.bar_status_drawer_activity } private fun getItems(): MutableList> { val randomColorItem = CommonItemClick(R.string.bar_status_random_color, ColorUtils.int2ArgbString(mColor)).setOnClickUpdateContentListener { mColor = ColorUtils.getRandomColor() updateStatusBar() return@setOnClickUpdateContentListener ColorUtils.int2ArgbString(mColor) } val alphaItem: CommonItem<*> = CommonItemSeekBar("Status Bar Alpha", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return mAlpha } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { mAlpha = progress updateStatusBar() } }) return CollectionUtils.newArrayList( CommonItemSwitch( R.string.bar_status_title_alpha, { updateStatusBar() mAlphaStatus }, { mAlphaStatus = it if (mAlphaStatus) { barStatusDrawerRootLl.setBackgroundResource(R.drawable.image_lena) commonItemAdapter.replaceItem(2, alphaItem, true) } else { barStatusDrawerRootLl.setBackgroundColor(Color.TRANSPARENT) commonItemAdapter.replaceItem(2, randomColorItem, true) } } ), CommonItemSwitch( R.string.bar_status_is_front, { mFrontStatus }, { mFrontStatus = it updateStatusBar() } ), randomColorItem ) } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(findViewById(R.id.commonItemRv), getItems()) } private fun updateStatusBar() { if (mAlphaStatus) { BarUtils.setStatusBarColor4Drawer(drawerView.mBaseDrawerRootLayout, barStatusDrawerFakeStatusBar, Color.argb(mAlpha, 0, 0, 0), mFrontStatus) } else { BarUtils.setStatusBarColor4Drawer(drawerView.mBaseDrawerRootLayout, barStatusDrawerFakeStatusBar, mColor, mFrontStatus) } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/BarStatusActivityImageView.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Bundle import android.view.View import android.widget.SeekBar import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSeekBar import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/27 * desc : demo about BarUtils * ``` */ class BarStatusActivityImageView : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusActivityImageView::class.java) context.startActivity(starter) } } private var mAlpha: Int = 112 override fun bindLayout(): Int { return R.layout.bar_status_image_view_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(findViewById(R.id.commonItemRv), getItems()) updateStatusBar() } private fun getItems(): List> { return CollectionUtils.newArrayList>( CommonItemSeekBar("Status Bar Alpha", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return mAlpha } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { mAlpha = progress updateStatusBar() } }) ) } private fun updateStatusBar() { BarUtils.setStatusBarColor(this, Color.argb(mAlpha, 0, 0, 0), true) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/fragment/BarStatusFragmentActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status.fragment import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View import androidx.fragment.app.Fragment import androidx.fragment.app.FragmentPagerAdapter import androidx.viewpager.widget.ViewPager import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.google.android.material.bottomnavigation.BottomNavigationView import kotlinx.android.synthetic.main.bar_status_fragment_activity.* import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/05/27 * desc : demo about BarUtils * ``` */ class BarStatusFragmentActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, BarStatusFragmentActivity::class.java) context.startActivity(starter) } } private val itemIds = intArrayOf( R.id.barStatusFragmentNavigationColor, R.id.barStatusFragmentNavigationAlpha, R.id.barStatusFragmentNavigationImageView, R.id.barStatusFragmentNavigationCustom ) private val mFragmentList = ArrayList() private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener l@{ item -> when (item.itemId) { R.id.barStatusFragmentNavigationColor -> { barStatusFragmentVp.currentItem = 0 return@l true } R.id.barStatusFragmentNavigationAlpha -> { barStatusFragmentVp.currentItem = 1 return@l true } R.id.barStatusFragmentNavigationImageView -> { barStatusFragmentVp.currentItem = 2 return@l true } R.id.barStatusFragmentNavigationCustom -> { barStatusFragmentVp.currentItem = 3 return@l true } else -> false } } override fun isSwipeBack(): Boolean { return false } override fun bindLayout(): Int { return R.layout.bar_status_fragment_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) mFragmentList.add(BarStatusFragmentColor.newInstance()) mFragmentList.add(BarStatusFragmentAlpha.newInstance()) mFragmentList.add(BarStatusFragmentImageView.newInstance()) mFragmentList.add(BarStatusFragmentCustom.newInstance()) barStatusFragmentVp.offscreenPageLimit = mFragmentList.size - 1 barStatusFragmentVp.adapter = object : FragmentPagerAdapter(supportFragmentManager) { override fun getItem(position: Int): Fragment { return mFragmentList[position] } override fun getCount(): Int { return mFragmentList.size } } barStatusFragmentVp.addOnPageChangeListener(object : ViewPager.OnPageChangeListener { override fun onPageScrolled(position: Int, positionOffset: Float, positionOffsetPixels: Int) {} override fun onPageSelected(position: Int) { barStatusFragmentNav.selectedItemId = itemIds[position] } override fun onPageScrollStateChanged(state: Int) {} }) barStatusFragmentNav.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/fragment/BarStatusFragmentAlpha.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status.fragment import android.graphics.Color import android.os.Bundle import android.view.View import android.widget.SeekBar import com.blankj.common.fragment.CommonFragment import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSeekBar import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils import kotlinx.android.synthetic.main.bar_status_alpha_fragment.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/07/01 * desc : demo about BarUtils * ``` */ class BarStatusFragmentAlpha : CommonFragment() { companion object { fun newInstance(): BarStatusFragmentAlpha { return BarStatusFragmentAlpha() } } override fun isLazy(): Boolean { return true } private var mAlpha: Int = 112 override fun bindLayout(): Int { return R.layout.bar_status_alpha_fragment } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(findViewById(R.id.commonItemRv), getItems()) updateFakeStatusBar() } private fun getItems(): List> { return CollectionUtils.newArrayList>( CommonItemSeekBar("Status Bar Alpha", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return mAlpha } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { mAlpha = progress updateFakeStatusBar() } }).apply { backgroundColor = ColorUtils.setAlphaComponent(backgroundColor, 0.5f) } ) } fun updateFakeStatusBar() { BarUtils.setStatusBarColor(barStatusAlphaFragmentFakeStatusBar, Color.argb(mAlpha, 0, 0, 0)) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/fragment/BarStatusFragmentColor.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status.fragment import android.os.Bundle import android.view.View import com.blankj.common.fragment.CommonFragment import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils import kotlinx.android.synthetic.main.bar_status_color_fragment.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/07/01 * desc : demo about BarUtils * ``` */ class BarStatusFragmentColor : CommonFragment() { companion object { fun newInstance(): BarStatusFragmentColor { return BarStatusFragmentColor() } } private var mColor: Int = ColorUtils.getColor(R.color.colorPrimary) override fun isLazy(): Boolean { return true } override fun bindLayout(): Int { return R.layout.bar_status_color_fragment } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(findViewById(R.id.commonItemRv), getItems()) updateFakeStatusBar() } private fun getItems(): List> { return CollectionUtils.newArrayList>( CommonItemClick(R.string.bar_status_random_color, ColorUtils.int2ArgbString(mColor)).setOnClickUpdateContentListener { mColor = ColorUtils.getRandomColor() updateFakeStatusBar() return@setOnClickUpdateContentListener ColorUtils.int2ArgbString(mColor) } ) } private fun updateFakeStatusBar() { BarUtils.setStatusBarColor(barStatusColorFragmentFakeStatusBar, mColor) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/fragment/BarStatusFragmentCustom.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status.fragment import android.os.Bundle import android.view.View import com.blankj.common.fragment.CommonFragment import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import kotlinx.android.synthetic.main.bar_status_custom_fragment.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/07/01 * desc : demo about BarUtils * ``` */ class BarStatusFragmentCustom : CommonFragment() { companion object { fun newInstance(): BarStatusFragmentCustom { return BarStatusFragmentCustom() } } override fun isLazy(): Boolean { return true } override fun bindLayout(): Int { return R.layout.bar_status_custom_fragment } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) BarUtils.setStatusBarCustom(barStatusCustomFragmentFakeStatusBar) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bar/status/fragment/BarStatusFragmentImageView.kt ================================================ package com.blankj.utilcode.pkg.feature.bar.status.fragment import android.graphics.Color import android.os.Bundle import android.view.View import android.widget.SeekBar import com.blankj.common.fragment.CommonFragment import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSeekBar import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.CollectionUtils import kotlinx.android.synthetic.main.bar_status_image_view_fragment.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/07/01 * desc : demo about BarUtils * ``` */ class BarStatusFragmentImageView : CommonFragment() { companion object { fun newInstance(): BarStatusFragmentImageView { return BarStatusFragmentImageView() } } private var mAlpha: Int = 112 override fun isLazy(): Boolean { return true } override fun bindLayout(): Int { return R.layout.bar_status_image_view_fragment } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) setCommonItems(findViewById(R.id.commonItemRv), getItems()) updateFakeStatusBar() } private fun getItems(): List> { return CollectionUtils.newArrayList>( CommonItemSeekBar("Status Bar Alpha", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return mAlpha } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { mAlpha = progress updateFakeStatusBar() } }) ) } fun updateFakeStatusBar() { BarUtils.setStatusBarColor(barStatusImageViewFragmentFakeStatusBar, Color.argb(mAlpha, 0, 0, 0)) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/brightness/BrightnessActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.brightness import android.content.Context import android.content.Intent import android.os.Build import android.widget.SeekBar import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSeekBar import com.blankj.common.item.CommonItemSwitch import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/02/08 * desc : demo about BrightnessUtils * ``` */ class BrightnessActivity : CommonActivity() { companion object { fun start(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PermissionUtils.requestWriteSettings(object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, BrightnessActivity::class.java) context.startActivity(starter) } override fun onDenied() { ToastUtils.showLong("No permission of write settings.") } }) } else { val starter = Intent(context, BrightnessActivity::class.java) context.startActivity(starter) } } } override fun bindTitleRes(): Int { return R.string.demo_brightness } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemSeekBar("getBrightness", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return BrightnessUtils.getBrightness() } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { BrightnessUtils.setBrightness(progress) } }), CommonItemSeekBar("getWindowBrightness", 255, object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return BrightnessUtils.getWindowBrightness(window) } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { BrightnessUtils.setWindowBrightness(window, progress) } }), CommonItemSwitch( R.string.brightness_auto_brightness, { BrightnessUtils.isAutoBrightnessEnabled() }, { BrightnessUtils.setAutoBrightnessEnabled(it) } ) ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bus/BusActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bus import android.content.Context import android.content.Intent import androidx.annotation.Keep import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BusUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ThreadUtils import kotlin.random.Random /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/03/12 * desc : demo about BusUtils * ``` */ class BusActivity : CommonActivity() { private val titleItem: CommonItemTitle = CommonItemTitle("", true); @BusUtils.Bus(tag = TAG_BASIC_TYPE) fun test(param: Int) { titleItem.title = param.toString() } @BusUtils.Bus(tag = TAG_BUS, priority = 5) fun test(param: String) { titleItem.title = param } @BusUtils.Bus(tag = TAG_BUS, priority = 1) fun testSameTag(param: String) { if (titleItem.title.toString() == TAG_BUS) { titleItem.title = "${titleItem.title} * 2" } } @BusUtils.Bus(tag = TAG_STICKY_BUS, sticky = true) fun testSticky(callback: Callback) { titleItem.title = callback.call() } @BusUtils.Bus(tag = TAG_IO, threadMode = BusUtils.ThreadMode.IO) fun testIo() { val currentThread = Thread.currentThread().toString() ThreadUtils.runOnUiThread(Runnable { titleItem.title = currentThread }) } companion object { const val TAG_BASIC_TYPE = "tag_basic_type" const val TAG_BUS = "tag_bus" const val TAG_STICKY_BUS = "tag_sticky_bus" const val TAG_IO = "tag_io" fun start(context: Context) { val starter = Intent(context, BusActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_bus } override fun bindItems(): List> { return CollectionUtils.newArrayList( titleItem, CommonItemClick(R.string.bus_register) { BusUtils.register(this) }, CommonItemClick(R.string.bus_unregister) { BusUtils.unregister(this) }, CommonItemClick(R.string.bus_post) { BusUtils.post(TAG_BUS, TAG_BUS) }, CommonItemClick(R.string.bus_post_basic_type) { BusUtils.post(TAG_BASIC_TYPE, Random(System.currentTimeMillis()).nextInt()) }, CommonItemClick(R.string.bus_post_sticky) { BusUtils.postSticky(TAG_STICKY_BUS, object : Callback { override fun call(): String { return TAG_STICKY_BUS } }) }, CommonItemClick(R.string.bus_post_to_io_thread) { BusUtils.post(TAG_IO) }, CommonItemClick(R.string.bus_remove_sticky) { BusUtils.removeSticky(TAG_STICKY_BUS) }, CommonItemClick(R.string.bus_start_compare, true) { BusCompareActivity.start(this) } ) } override fun onDestroy() { super.onDestroy() BusUtils.removeSticky(TAG_STICKY_BUS) BusUtils.unregister(this) } } @Keep interface Callback { fun call(): String } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/bus/BusCompareActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.bus import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BusUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ThreadUtils import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.Subscribe import java.util.* import java.util.concurrent.CopyOnWriteArrayList /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/07/14 * desc : demo about BusUtils * ``` */ class BusCompareActivity : CommonActivity() { private val titleItem: CommonItemTitle = CommonItemTitle("", true) companion object { fun start(context: Context) { val starter = Intent(context, BusCompareActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_bus } override fun bindItems(): List> { return CollectionUtils.newArrayList( titleItem, CommonItemClick(R.string.bus_compare_register_10000_times) { compareRegister10000Times() }, CommonItemClick(R.string.bus_compare_post_to_1_subscriber_1000000_times) { comparePostTo1Subscriber1000000Times() }, CommonItemClick(R.string.bus_compare_post_to_100_subscriber_100000_times) { comparePostTo100Subscribers100000Times() }, CommonItemClick(R.string.bus_compare_unregister_10000_times) { compareUnregister10000Times() } ) } override fun onDestroy() { super.onDestroy() ThreadUtils.cancel(ThreadUtils.getCpuPool()) } /** * 注册 10000 个订阅者,共执行 10 次取平均值 */ private fun compareRegister10000Times() { val eventBusTests = CopyOnWriteArrayList() val busUtilsTests = CopyOnWriteArrayList() compareWithEventBus("Register 10000 times.", 10, 10000, object : CompareCallback { override fun runEventBus() { val test = BusEvent() EventBus.getDefault().register(test) eventBusTests.add(test) } override fun runBusUtils() { val test = BusEvent() BusUtils.register(test) busUtilsTests.add(test) } override fun restState() { for (test in eventBusTests) { EventBus.getDefault().unregister(test) } eventBusTests.clear() for (test in busUtilsTests) { BusUtils.unregister(test) } busUtilsTests.clear() } }, object : OnFinishCallback { override fun onFinish() { for (test in eventBusTests) { EventBus.getDefault().unregister(test) } eventBusTests.clear() for (test in busUtilsTests) { BusUtils.unregister(test) } busUtilsTests.clear() } }) } /** * 向 1 个订阅者发送 * 1000000 次,共执行 10 次取平均值 */ private fun comparePostTo1Subscriber1000000Times() { comparePostTemplate("Post to 1 subscriber 1000000 times.", 1, 1000000) } /** * 向 100 个订阅者发送 * 100000 次,共执行 10 次取平均值 */ private fun comparePostTo100Subscribers100000Times() { comparePostTemplate("Post to 100 subscribers 100000 times.", 100, 100000) } private fun comparePostTemplate(name: String, subscribeNum: Int, postTimes: Int) { val tests = java.util.ArrayList() for (i in 0 until subscribeNum) { val test = BusEvent() EventBus.getDefault().register(test) BusUtils.register(test) tests.add(test) } compareWithEventBus(name, 10, postTimes, object : CompareCallback { override fun runEventBus() { EventBus.getDefault().post("EventBus") } override fun runBusUtils() { BusUtils.post("busUtilsFun", "BusUtils") } override fun restState() { } }, object : OnFinishCallback { override fun onFinish() { for (test in tests) { EventBus.getDefault().unregister(test) BusUtils.unregister(test) } } }) } /** * 注销 10000 个订阅者,共执行 10 次取平均值 */ private fun compareUnregister10000Times() { showLoading() ThreadUtils.executeBySingle(object : ThreadUtils.SimpleTask>() { override fun doInBackground(): List { val tests = ArrayList() for (i in 0..9999) { val test = BusEvent() EventBus.getDefault().register(test) BusUtils.register(test) tests.add(test) } return tests } override fun onSuccess(tests: List) { compareWithEventBus("Unregister 10000 times.", 10, 1, object : CompareCallback { override fun runEventBus() { for (test in tests) { EventBus.getDefault().unregister(test) } } override fun runBusUtils() { for (test in tests) { BusUtils.unregister(test) } } override fun restState() { for (test in tests) { EventBus.getDefault().register(test) BusUtils.register(test) } } }, object : OnFinishCallback { override fun onFinish() { for (test in tests) { EventBus.getDefault().unregister(test) BusUtils.unregister(test) } } }) } }) } /** * @param name 传入的测试函数名 * @param sampleSize 样本数 * @param times 每次执行的次数 * @param callback 比较的回调函数 * @param onFinishCallback 执行结束的回调 */ private fun compareWithEventBus(name: String, sampleSize: Int, times: Int, callback: CompareCallback, onFinishCallback: OnFinishCallback) { showLoading() ThreadUtils.executeByCpu(object : ThreadUtils.Task() { override fun doInBackground(): String { val dur = Array(2) { LongArray(sampleSize) } for (i in 0 until sampleSize) { var cur = System.currentTimeMillis() for (j in 0 until times) { callback.runEventBus() } dur[0][i] = System.currentTimeMillis() - cur cur = System.currentTimeMillis() for (j in 0 until times) { callback.runBusUtils() } dur[1][i] = System.currentTimeMillis() - cur callback.restState() } var eventBusAverageTime: Long = 0 var busUtilsAverageTime: Long = 0 for (i in 0 until sampleSize) { eventBusAverageTime += dur[0][i] busUtilsAverageTime += dur[1][i] } return name + "\nEventBusCostTime: " + eventBusAverageTime / sampleSize + "\nBusUtilsCostTime: " + busUtilsAverageTime / sampleSize; } override fun onSuccess(result: String?) { onFinishCallback.onFinish() dismissLoading() titleItem?.title = result } override fun onCancel() { onFinishCallback.onFinish() dismissLoading() } override fun onFail(t: Throwable?) { onFinishCallback.onFinish() dismissLoading() } }) } } interface CompareCallback { fun runEventBus() fun runBusUtils() fun restState() } interface OnFinishCallback { fun onFinish() } class BusEvent { @Subscribe fun eventBusFun(param: String) { } @BusUtils.Bus(tag = "busUtilsFun") fun busUtilsFun(param: String) { } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/clean/CleanActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.clean import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CleanUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.SDCardUtils import com.blankj.utilcode.util.SnackbarUtils import java.io.File /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : demo about CleanUtils * ``` */ class CleanActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, CleanActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_clean } override fun bindItems(): List> { return CollectionUtils.newArrayList>().apply { add(CommonItemClick(R.string.clean_internal_cache) { showSnackbar(CleanUtils.cleanInternalCache(), cacheDir.path) }) add(CommonItemClick(R.string.clean_internal_files) { showSnackbar(CleanUtils.cleanInternalFiles(), filesDir.path) }) add(CommonItemClick(R.string.clean_internal_databases) { showSnackbar(CleanUtils.cleanInternalDbs(), filesDir.parent + File.separator + "databases") }) add(CommonItemClick(R.string.clean_internal_sp) { showSnackbar(CleanUtils.cleanInternalSp(), filesDir.parent + File.separator + "shared_prefs") }) if (SDCardUtils.isSDCardEnableByEnvironment()) { add(CommonItemClick(R.string.clean_external_cache) { showSnackbar(CleanUtils.cleanExternalCache(), externalCacheDir?.absolutePath) }) } if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.KITKAT) { add(CommonItemClick(R.string.clean_app_user_data) { CleanUtils.cleanAppUserData() }) } } } private fun showSnackbar(isSuccess: Boolean, path: String?) { SnackbarUtils.with(mContentView) .setDuration(SnackbarUtils.LENGTH_LONG) .apply { if (isSuccess) { setMessage("clean \"$path\" dir successful.") showSuccess() } else { setMessage("clean \"$path\" dir failed.") showError() } } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/click/ClickActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.click import android.content.Context import android.content.Intent import android.view.View import android.widget.TextView import androidx.annotation.StringRes import com.blankj.base.rv.ItemViewHolder import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : demo about ClickUtils * ``` */ class ClickActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ClickActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_click } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( ClickItem(R.string.click_view_scale_default, Utils.Consumer { ClickUtils.applyPressedViewScale(it) }), ClickItem(R.string.click_view_scale_half, Utils.Consumer { ClickUtils.applyPressedViewScale(it, -0.5f) }), ClickItem(R.string.click_view_alpha_default, Utils.Consumer { ClickUtils.applyPressedViewAlpha(it) }), ClickItem(R.string.click_bg_alpha_default, Utils.Consumer { ClickUtils.applyPressedBgAlpha(it, 0.6f) }), ClickItem(R.string.click_bg_dark_default, Utils.Consumer { ClickUtils.applyPressedBgDark(it) }), ClickItem(R.string.click_single_debouncing, Utils.Consumer { ClickUtils.applyPressedBgDark(it) ClickUtils.applySingleDebouncing(it, 5000) { SnackbarUtils.with(mContentView) .setMessage(StringUtils.getString(R.string.click_single_tip)) .setBgColor(ColorUtils.getRandomColor(false)) .setDuration(SnackbarUtils.LENGTH_LONG) .show() } }), ClickItem(R.string.click_global_debouncing, Utils.Consumer { ClickUtils.applyPressedBgDark(it) ClickUtils.applySingleDebouncing(it, 5000) { SnackbarUtils.with(mContentView) .setMessage(StringUtils.getString(R.string.click_global_tip)) .setBgColor(ColorUtils.getRandomColor(false)) .setDuration(SnackbarUtils.LENGTH_LONG) .show() } }), ClickItem(R.string.click_multi, Utils.Consumer { ClickUtils.applyPressedBgDark(it) it.setOnClickListener(object : ClickUtils.OnMultiClickListener(5) { override fun onTriggerClick(v: View) { ToastUtils.showShort("onTriggerClick") } override fun onBeforeTriggerClick(v: View, count: Int) { ToastUtils.showShort(count) } }) }) ) } override fun onDestroy() { super.onDestroy() SnackbarUtils.dismiss() } } class ClickItem : CommonItem { private val mConsumer: Utils.Consumer; private val mTitle: String constructor(@StringRes title: Int, consumer: Utils.Consumer) : super(R.layout.common_item_title_click) { mConsumer = consumer mTitle = StringUtils.getString(title) } override fun bind(holder: ItemViewHolder, position: Int) { super.bind(holder, position) holder.findViewById(R.id.commonItemTitleTv).text = mTitle holder.itemView.setOnClickListener() { SnackbarUtils.with(it) .setMessage(mTitle) .setBgColor(ColorUtils.getRandomColor(false)) .setDuration(SnackbarUtils.LENGTH_LONG) .show() } mConsumer.accept(holder.itemView) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/clipboard/ClipboardActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.clipboard import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.ClipboardUtils import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2020/09/11 * desc : demo about ClipboardUtils * ``` */ class ClipboardActivity : CommonActivity() { private var index: Int = 0 private var isAddListener: Boolean = false private var listener = { ToastUtils.showShort(ClipboardUtils.getText()) } companion object { fun start(context: Context) { val starter = Intent(context, ClipboardActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_clipboard } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("getText", ClipboardUtils.getText()), CommonItemTitle("getLabel", ClipboardUtils.getLabel()), CommonItemClick("copyText: value{$index}").setOnItemClickListener { _, _, _ -> ClipboardUtils.copyText("value{${index++}}") itemsView.updateItems(bindItems()) }, CommonItemClick("clear").setOnItemClickListener { _, _, _ -> ClipboardUtils.clear() itemsView.updateItems(bindItems()) }, CommonItemSwitch("clipChangeListener", { isAddListener }, { isAddListener = it if (isAddListener) { ClipboardUtils.addChangedListener(listener) } else { ClipboardUtils.removeChangedListener(listener) } }) ) } override fun onResume() { super.onResume() itemsView.updateItems(bindItems()) } override fun onDestroy() { super.onDestroy() if (isAddListener) { ClipboardUtils.removeChangedListener(listener) } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/device/DeviceActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.device import android.content.Context import android.content.Intent import android.os.Build import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.DeviceUtils import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/27 * desc : demo about DeviceUtils * ``` */ class DeviceActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, DeviceActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_device } override fun bindItems(): List> { return arrayListOf>().apply { add(CommonItemTitle("isRoot", DeviceUtils.isDeviceRooted().toString())) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { add(CommonItemTitle("isAdbEnabled", DeviceUtils.isAdbEnabled().toString())) } add(CommonItemTitle("getSDKVersionName", DeviceUtils.getSDKVersionName())) add(CommonItemTitle("getSDKVersionCode", DeviceUtils.getSDKVersionCode().toString())) add(CommonItemTitle("getAndroidID", DeviceUtils.getAndroidID())) add(CommonItemTitle("getMacAddress", DeviceUtils.getMacAddress())) add(CommonItemTitle("getManufacturer", DeviceUtils.getManufacturer())) add(CommonItemTitle("getModel", DeviceUtils.getModel())) add(CommonItemTitle("getABIs", Arrays.asList(*DeviceUtils.getABIs()).toString())) add(CommonItemTitle("isTablet", DeviceUtils.isTablet().toString())) add(CommonItemTitle("isEmulator", DeviceUtils.isEmulator().toString())) if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.JELLY_BEAN_MR1) { add(CommonItemTitle("isDevelopmentSettingsEnabled", DeviceUtils.isDevelopmentSettingsEnabled().toString())) } add(CommonItemTitle("getUniqueDeviceId", DeviceUtils.getUniqueDeviceId("util"))) add(CommonItemTitle("isSameDevice", DeviceUtils.isSameDevice(DeviceUtils.getUniqueDeviceId()).toString())) } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/file/FileActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.file import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.Config.CACHE_PATH import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.FileUtils import com.blankj.utilcode.util.PathUtils import com.blankj.utilcode.util.SnackbarUtils import java.io.File /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : demo about FileUtils * ``` */ class FileActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, FileActivity::class.java) context.startActivity(starter) } val TEST_FILE_PATH: String = CACHE_PATH + "test_file.txt" } override fun bindTitleRes(): Int { return R.string.demo_file } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("isFileExists: " + PathUtils.getInternalAppFilesPath(), "" + FileUtils.isFileExists(PathUtils.getInternalAppFilesPath())), CommonItemTitle("isFileExists: " + PathUtils.getExternalAppFilesPath(), "" + FileUtils.isFileExists(PathUtils.getExternalAppFilesPath())), CommonItemTitle("isFileExists: " + PathUtils.getExternalStoragePath(), "" + FileUtils.isFileExists(PathUtils.getExternalStoragePath())), CommonItemTitle("isFileExists: " + PathUtils.getDownloadCachePath(), "" + FileUtils.isFileExists(PathUtils.getDownloadCachePath())), CommonItemTitle("isFileExists: " + PathUtils.getExternalDownloadsPath(), "" + FileUtils.isFileExists(PathUtils.getExternalDownloadsPath())), CommonItemTitle("isFileExists: " + PathUtils.getInternalAppFilesPath(), "" + FileUtils.isFileExists(File(PathUtils.getInternalAppFilesPath()))), CommonItemTitle("isFileExists: " + PathUtils.getExternalAppFilesPath(), "" + FileUtils.isFileExists(File(PathUtils.getExternalAppFilesPath()))), CommonItemTitle("isFileExists: " + PathUtils.getExternalStoragePath(), "" + FileUtils.isFileExists(File(PathUtils.getExternalStoragePath()))), CommonItemTitle("isFileExists: " + PathUtils.getDownloadCachePath(), "" + FileUtils.isFileExists(File(PathUtils.getDownloadCachePath()))), CommonItemTitle("isFileExists: " + PathUtils.getExternalDownloadsPath(), "" + FileUtils.isFileExists(File(PathUtils.getExternalDownloadsPath()))) ) } override fun onDestroy() { super.onDestroy() SnackbarUtils.dismiss() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/flashlight/FlashlightActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.flashlight import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/04/27 * desc : demo about FlashlightUtils * ``` */ class FlashlightActivity : CommonActivity() { companion object { fun start(context: Context) { if (!FlashlightUtils.isFlashlightEnable()) { ToastUtils.showLong("Didn't support flashlight.") return } PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, FlashlightActivity::class.java) context.startActivity(starter) } override fun onDenied() { LogUtils.e("permission denied") } }, PermissionConstants.CAMERA) } } override fun bindTitleRes(): Int { return R.string.demo_flashlight } override fun bindItems(): List> { return CollectionUtils.newArrayList>().apply { add(CommonItemTitle("isFlashlightEnable", FlashlightUtils.isFlashlightEnable().toString())) if (FlashlightUtils.isFlashlightEnable()) { add(CommonItemSwitch( R.string.flashlight_status, { FlashlightUtils.isFlashlightOn() }, { FlashlightUtils.setFlashlightStatus(it) } )) } } } override fun onDestroy() { FlashlightUtils.destroy() super.onDestroy() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ChildFragment.kt ================================================ package com.blankj.utilcode.pkg.feature.fragment import android.os.Bundle import android.view.View import androidx.fragment.app.FragmentManager import com.blankj.common.fragment.CommonFragment import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.helper.DialogHelper import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils import com.blankj.utilcode.util.FragmentUtils import com.blankj.utilcode.util.SpanUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/02 * desc : demo about FragmentUtils * ``` */ class ChildFragment : CommonFragment() { companion object { fun newInstance(): ChildFragment { val args = Bundle() val fragment = ChildFragment() fragment.arguments = args return fragment } } private lateinit var fm: FragmentManager private val mBgColor = ColorUtils.getRandomColor(false) override fun bindLayout(): Int { return R.layout.fragment_child } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) FragmentUtils.setBackgroundColor(this, mBgColor) fm = fragmentManager!! setCommonItems(findViewById(R.id.commonItemRv), getItems()) } private fun getItems(): MutableList> { return CollectionUtils.newArrayList>( CommonItemClick(R.string.fragment_show_stack) { DialogHelper.showFragmentDialog( SpanUtils().appendLine("top: " + FragmentUtils.getSimpleName(FragmentUtils.getTop(fm))) .appendLine("topInStack: " + FragmentUtils.getSimpleName(FragmentUtils.getTopInStack(fm))) .appendLine("topShow: " + FragmentUtils.getSimpleName(FragmentUtils.getTopShow(fm))) .appendLine("topShowInStack: " + FragmentUtils.getSimpleName(FragmentUtils.getTopShowInStack(fm))) .appendLine() .appendLine("---all of fragments---") .appendLine(FragmentUtils.getAllFragments(fm).toString()) .appendLine("----------------------") .appendLine() .appendLine("---stack top---") .appendLine(FragmentUtils.getAllFragmentsInStack(fm).toString()) .appendLine("---stack bottom---") .create() ) }, CommonItemClick(R.string.fragment_pop) { FragmentUtils.pop(fm) }, CommonItemClick(R.string.fragment_remove) { FragmentUtils.remove(this) }, SharedElementItem() ).apply { for (ci: CommonItem<*> in this) { ci.backgroundColor = mBgColor } } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/ContainerFragment.kt ================================================ package com.blankj.utilcode.pkg.feature.fragment import android.os.Build import android.os.Bundle import android.transition.* import android.view.View import android.widget.ImageView import androidx.annotation.RequiresApi import androidx.fragment.app.FragmentManager import com.blankj.base.rv.ItemViewHolder import com.blankj.common.fragment.CommonFragment import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.helper.DialogHelper import com.blankj.utilcode.util.* import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/02 * desc : demo about FragmentUtils * ``` */ class ContainerFragment : CommonFragment(), FragmentUtils.OnBackClickListener { companion object { fun newInstance(): ContainerFragment { val args = Bundle() val fragment = ContainerFragment() fragment.arguments = args return fragment } } private lateinit var fm: FragmentManager private val mBgColor = ColorUtils.getRandomColor(false) override fun bindLayout(): Int { return R.layout.fragment_container } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) mContentView.setBackgroundColor(mBgColor) fm = fragmentManager!! setCommonItems(findViewById(R.id.commonItemRv), getItems()) } private fun getItems(): ArrayList>? { val item = SharedElementItem() return CollectionUtils.newArrayList>( CommonItemClick(R.string.fragment_show_stack) { DialogHelper.showFragmentDialog( SpanUtils().appendLine("top: " + FragmentUtils.getSimpleName(FragmentUtils.getTop(fm))) .appendLine("topInStack: " + FragmentUtils.getSimpleName(FragmentUtils.getTopInStack(fm))) .appendLine("topShow: " + FragmentUtils.getSimpleName(FragmentUtils.getTopShow(fm))) .appendLine("topShowInStack: " + FragmentUtils.getSimpleName(FragmentUtils.getTopShowInStack(fm))) .appendLine() .appendLine("---all of fragments---") .appendLine(FragmentUtils.getAllFragments(fm).toString()) .appendLine("----------------------") .appendLine() .appendLine("---stack top---") .appendLine(FragmentUtils.getAllFragmentsInStack(fm).toString()) .appendLine("---stack bottom---") .create() ) }, CommonItemClick(R.string.fragment_add_child) { FragmentUtils.add( fm, ChildFragment.newInstance(), id ) }, CommonItemClick(R.string.fragment_add_child_stack) { FragmentUtils.add( fm, ChildFragment.newInstance(), id, false, true ) }, CommonItemClick(R.string.fragment_add_hide) { FragmentUtils.add( fm, ChildFragment.newInstance(), id, true ) }, CommonItemClick(R.string.fragment_add_hide_stack) { FragmentUtils.add( fm, ChildFragment.newInstance(), id, true, true ) }, CommonItemClick(R.string.fragment_add_demo1_show) { FragmentUtils.add( fm, addSharedElement(ChildFragment.newInstance()), id, false, false ) }, CommonItemClick(R.string.fragment_pop_to_root) { FragmentUtils.popTo( fm, ChildFragment::class.java, true ) }, CommonItemClick(R.string.fragment_hide_demo0_show_demo1) { val fragment1 = FragmentUtils.findFragment(fm, ChildFragment::class.java) if (fragment1 != null) { FragmentUtils.showHide(this, fragment1) } else { ToastUtils.showLong("please add demo1 first!") } }, CommonItemClick(R.string.fragment_replace) { FragmentUtils.replace( fm, addSharedElement(ChildFragment.newInstance()), id, true, item.element ) }, item ).apply { for (ci: CommonItem<*> in this) { ci.backgroundColor = mBgColor } } } private fun addSharedElement(fragment: androidx.fragment.app.Fragment): androidx.fragment.app.Fragment { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) { fragment.sharedElementEnterTransition = DetailTransition() fragment.enterTransition = Fade() fragment.sharedElementReturnTransition = DetailTransition() } return fragment } override fun onBackClick(): Boolean { return false } } class SharedElementItem : CommonItem { lateinit var element: ImageView; constructor() : super(R.layout.fragment_item_shared_element) override fun bind(holder: ItemViewHolder, position: Int) { super.bind(holder, position) element = holder.findViewById(R.id.fragmentRootSharedElementIv) } } @RequiresApi(Build.VERSION_CODES.LOLLIPOP) class DetailTransition() : TransitionSet() { init { ordering = ORDERING_TOGETHER addTransition(ChangeBounds()).addTransition(ChangeTransform()).addTransition(ChangeImageTransform()) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/FragmentActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.fragment import android.content.Context import android.content.Intent import android.os.Bundle import android.os.PersistableBundle import com.google.android.material.bottomnavigation.BottomNavigationView import androidx.fragment.app.Fragment import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.FragmentUtils import kotlinx.android.synthetic.main.fragment_activity.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/01 * desc : demo about FragmentUtils * ``` */ class FragmentActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, FragmentActivity::class.java) context.startActivity(starter) } } private val mFragments = arrayListOf() private var curIndex: Int = 0 private val mOnNavigationItemSelectedListener = BottomNavigationView.OnNavigationItemSelectedListener { item -> when (item.itemId) { R.id.fragmentNavigation0 -> { showCurrentFragment(0) return@OnNavigationItemSelectedListener true } R.id.fragmentNavigation1 -> { showCurrentFragment(1) return@OnNavigationItemSelectedListener true } R.id.fragmentNavigation2 -> { showCurrentFragment(2) return@OnNavigationItemSelectedListener true } else -> false } } override fun bindLayout(): Int { return R.layout.fragment_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) if (savedInstanceState != null) { curIndex = savedInstanceState.getInt("curIndex") } fragmentNav.setOnNavigationItemSelectedListener(mOnNavigationItemSelectedListener) mFragments.add(RootFragment.newInstance()) mFragments.add(RootFragment.newInstance()) mFragments.add(RootFragment.newInstance()) FragmentUtils.add( supportFragmentManager, mFragments, R.id.fragmentContainer, arrayOf("RootFragment0", "RootFragment1", "RootFragment2"), curIndex ) } override fun onBackPressed() { if (!FragmentUtils.dispatchBackPress(mFragments[curIndex])) { super.onBackPressed() } } private fun showCurrentFragment(index: Int) { curIndex = index FragmentUtils.showHide(index, mFragments) } override fun onSaveInstanceState(outState: Bundle, outPersistentState: PersistableBundle) { super.onSaveInstanceState(outState, outPersistentState) outState.putInt("curIndex", curIndex) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/fragment/RootFragment.kt ================================================ package com.blankj.utilcode.pkg.feature.fragment import android.os.Bundle import android.view.View import com.blankj.common.fragment.CommonFragment import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.BarUtils import com.blankj.utilcode.util.ColorUtils import com.blankj.utilcode.util.FragmentUtils import kotlinx.android.synthetic.main.fragment_root.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 17/02/02 * desc : demo about FragmentUtils * ``` */ class RootFragment : CommonFragment(), FragmentUtils.OnBackClickListener { companion object { fun newInstance(): RootFragment { val args = Bundle() val fragment = RootFragment() fragment.arguments = args return fragment } } override fun bindLayout(): Int { return R.layout.fragment_root } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) BarUtils.setStatusBarColor(rootFragmentFakeStatusBar, ColorUtils.getColor(R.color.colorPrimary)) FragmentUtils.add( childFragmentManager, ContainerFragment.newInstance(), R.id.rootFragmentContainer ) } override fun onBackClick(): Boolean { if (FragmentUtils.dispatchBackPress(childFragmentManager)) return true return if (childFragmentManager.backStackEntryCount == 0) { false } else { childFragmentManager.popBackStack() true } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/image/ImageActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.image import android.content.Context import android.content.Intent import android.graphics.Bitmap import android.graphics.Color import android.os.Build import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemImage import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.pkg.Config import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* import java.io.File import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/26 * desc : demo about ImageUtils * ``` */ class ImageActivity : CommonActivity() { private val savePath = Config.CACHE_PATH + "lena.jpg" private val titleItem: CommonItemTitle = CommonItemTitle("isImage: $savePath", ""); companion object { fun start(context: Context) { PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, ImageActivity::class.java) context.startActivity(starter) } override fun onDenied() { } }, PermissionConstants.STORAGE) } } private val bgTask: ThreadUtils.SimpleTask>> = object : ThreadUtils.SimpleTask>>() { override fun doInBackground(): List> { return bindItems() } override fun onSuccess(result: List>) { dismissLoading() itemsView.updateItems(result) } } override fun bindTitleRes(): Int { return R.string.demo_image } override fun bindItems(): ArrayList> { if (ThreadUtils.isMainThread()) return arrayListOf() val src = ImageUtils.getBitmap(R.drawable.image_lena) val round = ImageUtils.getBitmap(R.drawable.common_avatar_round) val watermark = ImageUtils.getBitmap(R.mipmap.ic_launcher) val width = src.width val height = src.height titleItem.setContent(ImageUtils.isImage(savePath).toString()) return CollectionUtils.newArrayList>().apply { add(titleItem) add(CommonItemClick("Save to $savePath") { ThreadUtils.executeBySingle(object : ThreadUtils.SimpleTask() { override fun doInBackground(): Boolean { return ImageUtils.save(src, savePath, Bitmap.CompressFormat.JPEG) } override fun onSuccess(result: Boolean) { titleItem.setContent(ImageUtils.isImage(savePath).toString()) titleItem.update() SnackbarUtils.with(mContentView) .setDuration(SnackbarUtils.LENGTH_LONG) .apply { if (result) { setMessage("save successful.") .showSuccess(true) } else { setMessage("save failed.") .showError(true) } } } }) }) add(CommonItemClick("Save to Album") { ThreadUtils.executeBySingle(object : ThreadUtils.SimpleTask() { override fun doInBackground(): File? { return ImageUtils.save2Album(src, Bitmap.CompressFormat.JPEG) } override fun onSuccess(result: File?) { SnackbarUtils.with(mContentView) .setDuration(SnackbarUtils.LENGTH_LONG) .apply { if (result != null) { setMessage("save successful.") .showSuccess(true) } else { setMessage("save failed.") .showError(true) } } } }) }) add(CommonItemImage(R.string.image_src) { it.setImageBitmap(src) }) add(CommonItemImage(R.string.image_add_color) { it.setImageBitmap(ImageUtils.drawColor(src, Color.parseColor("#8000FF00"))) }) add(CommonItemImage(R.string.image_scale) { it.setImageBitmap(ImageUtils.scale(src, width / 2, height / 2)) }) add(CommonItemImage(R.string.image_clip) { it.setImageBitmap(ImageUtils.clip(src, 0, 0, width / 2, height / 2)) }) add(CommonItemImage(R.string.image_skew) { it.setImageBitmap(ImageUtils.skew(src, 0.2f, 0.1f)) }) add(CommonItemImage(R.string.image_rotate) { it.setImageBitmap(ImageUtils.rotate(src, 90, (width / 2).toFloat(), (height / 2).toFloat())) }) add(CommonItemImage(R.string.image_to_round) { it.setImageBitmap(ImageUtils.toRound(src)) }) add(CommonItemImage(R.string.image_to_round_border) { it.setImageBitmap(ImageUtils.toRound(src, 16, Color.GREEN)) }) add(CommonItemImage(R.string.image_to_round_corner) { it.setImageBitmap(ImageUtils.toRoundCorner(src, 80f)) }) add(CommonItemImage(R.string.image_to_round_corner_border) { it.setImageBitmap(ImageUtils.toRoundCorner(src, 80f, 16f, Color.GREEN)) }) add(CommonItemImage(R.string.image_to_round_corner_border) { it.setImageBitmap(ImageUtils.toRoundCorner(src, floatArrayOf(0f, 0f, 80f, 80f, 0f, 0f, 80f, 80f), 16f, Color.GREEN)) }) add(CommonItemImage(R.string.image_add_corner_border) { it.setImageBitmap(ImageUtils.addCornerBorder(src, 16f, Color.GREEN, 80f)) }) add(CommonItemImage(R.string.image_add_corner_border) { it.setImageBitmap(ImageUtils.addCornerBorder(src, 16f, Color.GREEN, floatArrayOf(0f, 0f, 80f, 80f, 0f, 0f, 80f, 80f))) }) add(CommonItemImage(R.string.image_add_circle_border) { it.setImageBitmap(ImageUtils.addCircleBorder(src, 16f, Color.GREEN)) }) add(CommonItemImage(R.string.image_add_reflection) { it.setImageBitmap(ImageUtils.addReflection(src, 80)) }) add(CommonItemImage(R.string.image_add_text_watermark) { it.setImageBitmap(ImageUtils.addTextWatermark(src, "blankj", 40, Color.GREEN, 0f, 0f)) }) add(CommonItemImage(R.string.image_add_image_watermark) { it.setImageBitmap(ImageUtils.addImageWatermark(src, watermark, 0, 0, 0x88)) }) add(CommonItemImage(R.string.image_to_gray) { it.setImageBitmap(ImageUtils.toGray(src)) }) add(CommonItemImage(R.string.image_fast_blur) { it.setImageBitmap(ImageUtils.fastBlur(src, 0.1f, 5f)) }) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) { add(CommonItemImage(R.string.image_render_script_blur) { it.setImageBitmap(ImageUtils.renderScriptBlur(src, 10f)) }) } add(CommonItemImage(R.string.image_stack_blur) { it.setImageBitmap(ImageUtils.stackBlur(src, 10)) }) add(CommonItemImage(R.string.image_compress_by_scale) { it.setImageBitmap(ImageUtils.compressByScale(src, 0.5f, 0.5f)) }) add(CommonItemImage(R.string.image_compress_by_sample_size) { it.setImageBitmap(ImageUtils.compressBySampleSize(src, 2)) }) } } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) showLoading() ThreadUtils.executeByIo(bgTask) } override fun onDestroy() { super.onDestroy() ThreadUtils.cancel(bgTask) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/intent/IntentActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.intent import android.content.Context import android.content.Intent import android.graphics.Bitmap import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.Config import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2020/05/29 * desc : demo about IntentUtils * ``` */ class IntentActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, IntentActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_intent } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick("LaunchApp") { startActivity(IntentUtils.getLaunchAppIntent(packageName)) }, CommonItemClick("LaunchAppDetailsSettings") { startActivityForResult(IntentUtils.getLaunchAppDetailsSettingsIntent(packageName), 1) }, CommonItemClick("ShareText") { startActivity(IntentUtils.getShareTextIntent("share content")) }, CommonItemClick("ShareImage") { startActivity(IntentUtils.getShareImageIntent(getShareImagePath()[0])); }, CommonItemClick("ShareTextImage") { startActivity(IntentUtils.getShareTextImageIntent("share content", getShareImagePath()[0])); }, CommonItemClick("ShareImages") { startActivity(IntentUtils.getShareImageIntent(getShareImagePath())); }, CommonItemClick("ShareTextImages") { startActivity(IntentUtils.getShareTextImageIntent("share content", getShareImagePath())); } ) } private fun getShareImagePath(): LinkedList { val shareImagePath0 = Config.CACHE_PATH + "share.jpg" if (!FileUtils.isFile(shareImagePath0)) { ImageUtils.save(ImageUtils.getBitmap(R.drawable.image_lena), shareImagePath0, Bitmap.CompressFormat.JPEG) } val shareImagePath1 = Config.CACHE_PATH + "cheetah.jpg" if (!FileUtils.isFile(shareImagePath1)) { ImageUtils.save(ImageUtils.getBitmap(R.drawable.span_cheetah), shareImagePath1, Bitmap.CompressFormat.JPEG) } return CollectionUtils.newLinkedList(shareImagePath0, shareImagePath1) } override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) { super.onActivityResult(requestCode, resultCode, data) LogUtils.d("onActivityResult() called with: requestCode = $requestCode, resultCode = $resultCode, data = $data") } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/keyboard/KeyboardActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.keyboard import android.content.Context import android.content.Intent import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.helper.DialogHelper import com.blankj.utilcode.util.* import kotlinx.android.synthetic.main.keyboard_activity.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/27 * desc : demo about KeyboardUtils * ``` */ class KeyboardActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, KeyboardActivity::class.java) context.startActivity(starter) } } private var titleItem: CommonItemTitle = CommonItemTitle("", true) override fun bindTitleRes(): Int { return R.string.demo_keyboard } override fun bindLayout(): Int { return R.layout.keyboard_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) KeyboardUtils.fixAndroidBug5497(this) setCommonItems(findViewById(R.id.commonItemRv), getItems()) KeyboardUtils.registerSoftInputChangedListener(this) { height -> titleItem.title = "isSoftInputVisible: " + KeyboardUtils.isSoftInputVisible(this@KeyboardActivity) + "\nkeyboardHeight: $height" if (height > 0) { keyboardEt.requestFocus() } } } private fun getItems(): MutableList> { return CollectionUtils.newArrayList( titleItem, CommonItemClick(R.string.keyboard_hide_soft_input) { KeyboardUtils.hideSoftInput(this) }, CommonItemClick(R.string.keyboard_show_soft_input) { KeyboardUtils.showSoftInput(this) }, CommonItemClick(R.string.keyboard_toggle_soft_input) { KeyboardUtils.toggleSoftInput() }, CommonItemClick(R.string.keyboard_show_dialog) { keyboardEt.clearFocus() DialogHelper.showKeyboardDialog(this) } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/language/LanguageActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.language import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.LanguageUtils import com.blankj.utilcode.util.SPStaticUtils import com.blankj.utilcode.util.StringUtils import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/12/29 * desc : demo about VibrateUtils * ``` */ class LanguageActivity : CommonActivity() { companion object { const val SP_KEY_IS_RELAUNCH_APP = "SP_KEY_IS_RELAUNCH_APP" fun start(context: Context) { val starter = Intent(context, LanguageActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_language } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemTitle("isAppliedLanguage", LanguageUtils.isAppliedLanguage().toString()), CommonItemTitle("isAppliedLanguage(SIMPLIFIED_CHINESE)", LanguageUtils.isAppliedLanguage(Locale.SIMPLIFIED_CHINESE).toString()), CommonItemTitle("getAppliedLanguage", (LanguageUtils.getAppliedLanguage() ?: "null").toString()), CommonItemTitle("getActivityContextLanguage", LanguageUtils.getContextLanguage(this).toString()), CommonItemTitle("getAppContextLanguage", LanguageUtils.getAppContextLanguage().toString()), CommonItemTitle("getSystemLanguage", LanguageUtils.getSystemLanguage().toString()), CommonItemSwitch( StringUtils.getString(R.string.language_relaunch_app), { isRelaunchApp() }, { SPStaticUtils.put(SP_KEY_IS_RELAUNCH_APP, it) } ), CommonItemClick(R.string.language_apply_simple_chinese) { LanguageUtils.applyLanguage(Locale.SIMPLIFIED_CHINESE, isRelaunchApp()) }, CommonItemClick(R.string.language_apply_american) { LanguageUtils.applyLanguage(Locale.US, isRelaunchApp()) }, CommonItemClick(R.string.language_apply_english) { LanguageUtils.applyLanguage(Locale.ENGLISH, isRelaunchApp()) }, CommonItemClick(R.string.language_apply_arabic) { LanguageUtils.applyLanguage(Locale("ar"), isRelaunchApp()) }, CommonItemClick(R.string.language_apply_system) { LanguageUtils.applySystemLanguage(isRelaunchApp()) } ) } private fun isRelaunchApp() = SPStaticUtils.getBoolean(SP_KEY_IS_RELAUNCH_APP) } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/log/LogActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.log import android.content.ComponentName import android.content.Context import android.content.Intent import android.net.Uri import android.os.Bundle import android.util.Log import com.blankj.base.BaseApplication import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* import java.io.File import java.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/03/22 * desc : demo about LogUtils * ``` */ class LogActivity : CommonActivity() { companion object { private const val TAG = "CMJ" private const val JSON = "{\"tools\": [{ \"name\":\"css format\" , \"site\":\"http://tools.w3cschool.cn/code/css\" },{ \"name\":\"JSON format\" , \"site\":\"http://tools.w3cschool.cn/code/JSON\" },{ \"name\":\"pwd check\" , \"site\":\"http://tools.w3cschool.cn/password/my_password_safe\" }]}" private const val XML = "Jack HerringtonPHP HacksO'ReillyJack HerringtonPodcasting HacksO'Reilly" private val ONE_D_ARRAY = intArrayOf(1, 2, 3) private val TWO_D_ARRAY = arrayOf(intArrayOf(1, 2, 3), intArrayOf(4, 5, 6), intArrayOf(7, 8, 9)) private val THROWABLE = NullPointerException() private val BUNDLE = Bundle() private val INTENT = Intent() private val LIST = ArrayList() private val MAP = HashMap() private val LONG_STR: String init { val sb = StringBuilder() sb.append("len = 10400\ncontent = \"") for (i in 0..1024) { sb.append("Hello world. ") } sb.append("\"") LONG_STR = sb.toString() BUNDLE.putByte("byte", (-1).toByte()) BUNDLE.putChar("char", 'c') BUNDLE.putCharArray("charArray", charArrayOf('c', 'h', 'a', 'r', 'A', 'r', 'r', 'a', 'y')) BUNDLE.putCharSequence("charSequence", "charSequence") BUNDLE.putCharSequenceArray("charSequenceArray", arrayOf("char", "Sequence", "Array")) BUNDLE.putBundle("bundle", BUNDLE) BUNDLE.putBoolean("boolean", true) BUNDLE.putInt("int", 1) BUNDLE.putFloat("float", 1f) BUNDLE.putLong("long", 1L) BUNDLE.putShort("short", 1.toShort()) INTENT.action = "LogUtils action" INTENT.addCategory("LogUtils category") INTENT.data = Uri.parse("intent data") INTENT.type = "intent type" INTENT.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) INTENT.setPackage(AppUtils.getAppPackageName()) INTENT.component = ComponentName(AppUtils.getAppPackageName(), LogActivity::class.java.toString()) INTENT.putExtra("int", 1) INTENT.putExtra("float", 1f) INTENT.putExtra("char", 'c') INTENT.putExtra("string", "string") INTENT.putExtra("intArray", ONE_D_ARRAY) val list = ArrayList() list.add("ArrayList") list.add("is") list.add("serializable") INTENT.putExtra("serializable", list) INTENT.putExtra("bundle", BUNDLE) LIST.add("hello") LIST.add("log") LIST.add("utils") MAP["name"] = "AndroidUtilCode" MAP["class"] = "LogUtils" } fun start(context: Context) { val starter = Intent(context, LogActivity::class.java) context.startActivity(starter) } } private val mConfig = LogUtils.getConfig() private val mRunnable = Runnable { LogUtils.v("verbose") LogUtils.d("debug") LogUtils.i("info") LogUtils.w("warn") LogUtils.e("error") LogUtils.a("assert") } override fun bindTitleRes(): Int { return R.string.demo_log } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemTitle("getLogFiles", LogUtils.getLogFiles().toString()), CommonItemSwitch( R.string.log_switch, { mConfig.isLogSwitch }, { mConfig.isLogSwitch = it } ), CommonItemSwitch( R.string.log_console_switch, { mConfig.isLog2ConsoleSwitch }, { mConfig.setConsoleSwitch(it) } ), CommonItemSwitch( R.string.log_console_listener_switch, { mConfig.haveSetOnConsoleOutputListener() }, { mConfig.setOnConsoleOutputListener { type, tag, content -> Log.println(type, tag, content) } } ), CommonItemClick("Global Tag", if (mConfig.globalTag == "") "null" else mConfig.globalTag).setOnClickUpdateContentListener { if (StringUtils.isSpace(mConfig.globalTag)) { mConfig.globalTag = TAG } else { mConfig.globalTag = "" } return@setOnClickUpdateContentListener if (mConfig.globalTag == "") "\"\"" else mConfig.globalTag }, CommonItemSwitch( R.string.log_head_switch, { mConfig.isLogHeadSwitch }, { mConfig.isLogHeadSwitch = it } ), CommonItemSwitch( R.string.log_file_switch, { mConfig.isLog2FileSwitch }, { mConfig.isLog2FileSwitch = it } ), CommonItemSwitch( R.string.log_file_listener_switch, { mConfig.haveSetOnFileOutputListener() }, { mConfig.setOnFileOutputListener { filePath, content -> Log.d("LogActivity", filePath + "\n" + content) } } ), CommonItemClick("Dir", mConfig.dir).setOnClickUpdateContentListener { if (mConfig.dir != mConfig.defaultDir) { mConfig.dir = mConfig.defaultDir } else { mConfig.setDir(File(PathUtils.getExternalAppFilesPath(), "log")) } return@setOnClickUpdateContentListener mConfig.dir }, CommonItemSwitch( R.string.log_border_switch, { mConfig.isLogBorderSwitch }, { mConfig.setBorderSwitch(it) } ), CommonItemSwitch( R.string.log_single_tag_switch, { mConfig.isSingleTagSwitch }, { mConfig.setSingleTagSwitch(it) } ), CommonItemSwitch( R.string.log_single_tag_switch, { mConfig.isSingleTagSwitch }, { mConfig.setSingleTagSwitch(it) } ), CommonItemClick("ConsoleFilter", mConfig.consoleFilter.toString()).setOnClickUpdateContentListener { mConfig.setConsoleFilter(if (mConfig.consoleFilter == 'V') LogUtils.W else LogUtils.V) return@setOnClickUpdateContentListener mConfig.consoleFilter.toString() }, CommonItemClick("FileFilter", mConfig.fileFilter.toString()).setOnClickUpdateContentListener { mConfig.setFileFilter(if (mConfig.fileFilter == 'V') LogUtils.W else LogUtils.V) return@setOnClickUpdateContentListener mConfig.fileFilter.toString() }, CommonItemClick(R.string.log_with_no_tag) { LogUtils.v("verbose") LogUtils.d("debug") LogUtils.i("info") LogUtils.w("warn") LogUtils.e("error") LogUtils.a("assert") }, CommonItemClick(R.string.log_with_tag) { LogUtils.vTag("customTag", "verbose") LogUtils.dTag("customTag", "debug") LogUtils.iTag("customTag", "info") LogUtils.wTag("customTag", "warn") LogUtils.eTag("customTag", "error") LogUtils.aTag("customTag", "assert") }, CommonItemClick(R.string.log_in_new_thread) { val thread = Thread(mRunnable) thread.start() }, CommonItemClick(R.string.log_null) { LogUtils.v(null) LogUtils.d(null) LogUtils.i(null) LogUtils.w(null) LogUtils.e(null) LogUtils.a(null) }, CommonItemClick(R.string.log_many_params) { LogUtils.v("verbose0", "verbose1") LogUtils.vTag("customTag", "verbose0", "verbose1") LogUtils.d("debug0", "debug1") LogUtils.dTag("customTag", "debug0", "debug1") LogUtils.i("info0", "info1") LogUtils.iTag("customTag", "info0", "info1") LogUtils.w("warn0", "warn1") LogUtils.wTag("customTag", "warn0", "warn1") LogUtils.e("error0", "error1") LogUtils.eTag("customTag", "error0", "error1") LogUtils.a("assert0", "assert1") LogUtils.aTag("customTag", "assert0", "assert1") }, CommonItemClick(R.string.log_long_string) { LogUtils.d(LONG_STR) }, CommonItemClick(R.string.log_to_file) { LogUtils.file("test0 log to file") LogUtils.file(LogUtils.I, "test0 log to file") }, CommonItemClick(R.string.log_json) { LogUtils.json(JSON) LogUtils.json(LogUtils.I, JSON) }, CommonItemClick(R.string.log_xml) { LogUtils.xml(XML) LogUtils.xml(LogUtils.I, XML) }, CommonItemClick(R.string.log_array) { LogUtils.e(ONE_D_ARRAY) LogUtils.e(TWO_D_ARRAY) }, CommonItemClick(R.string.log_throwable) { LogUtils.e(THROWABLE) }, CommonItemClick(R.string.log_bundle) { LogUtils.e(BUNDLE) }, CommonItemClick(R.string.log_intent) { LogUtils.e(INTENT) }, CommonItemClick(R.string.log_array_list) { LogUtils.e(LIST) }, CommonItemClick(R.string.log_map) { LogUtils.e(MAP) } ) } override fun onDestroy() { BaseApplication.getInstance().initLog() super.onDestroy() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/messenger/MessengerActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.messenger import android.content.Context import android.content.Intent import android.os.Bundle import com.blankj.common.activity.CommonActivity import com.blankj.common.activity.CommonActivityItemsView import com.blankj.common.activity.CommonActivityTitleView import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.MessengerUtils import com.blankj.utilcode.util.SnackbarUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/03/12 * desc : demo about MessengerUtils * ``` */ class MessengerActivity : CommonActivity() { companion object { const val MESSENGER_KEY = "MessengerActivity" fun start(context: Context) { val starter = Intent(context, MessengerActivity::class.java) context.startActivity(starter) MessengerUtils.register() } val BUNDLE = Bundle() init { BUNDLE.putString(MESSENGER_KEY, "MessengerActivity") } } override fun bindTitleRes(): Int { return R.string.demo_messenger } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemClick(R.string.messenger_post_to_main_server) { MessengerUtils.post(MESSENGER_KEY, BUNDLE) }, CommonItemClick(R.string.messenger_start_remote) { MessengerRemoteActivity.start(this) } ) } override fun doBusiness() { MessengerUtils.subscribe(MESSENGER_KEY) { data -> SnackbarUtils.with(mContentView) .setMessage(data.getString(MESSENGER_KEY) ?: "") .setDuration(SnackbarUtils.LENGTH_INDEFINITE) .show() } } override fun onDestroy() { super.onDestroy() MessengerUtils.unregister() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/messenger/MessengerRemoteActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.messenger import android.content.Context import android.content.Intent import android.os.Bundle import com.blankj.common.activity.CommonActivity import com.blankj.common.activity.CommonActivityItemsView import com.blankj.common.activity.CommonActivityTitleView import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.MessengerUtils import com.blankj.utilcode.util.SnackbarUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/03/12 * desc : demo about MessengerUtils * ``` */ class MessengerRemoteActivity : CommonActivity() { companion object { const val MESSENGER_KEY = "MessengerRemoteActivity" fun start(context: Context) { val starter = Intent(context, MessengerRemoteActivity::class.java) context.startActivity(starter) } val BUNDLE = Bundle() init { BUNDLE.putString(MESSENGER_KEY, "MessengerRemoteActivity") } } override fun bindTitleRes(): Int { return R.string.demo_messenger } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemClick(R.string.messenger_register_remote_client) { MessengerUtils.register() }, CommonItemClick(R.string.messenger_unregister_remote_client) { MessengerUtils.unregister() }, CommonItemClick(R.string.messenger_post_to_self_client) { MessengerUtils.post(MESSENGER_KEY, BUNDLE) }, CommonItemClick(R.string.messenger_post_to_main_server) { MessengerUtils.post(MessengerActivity.MESSENGER_KEY, MessengerActivity.BUNDLE) } ) } override fun doBusiness() { MessengerUtils.subscribe(MESSENGER_KEY) { data -> SnackbarUtils.with(mContentView) .setMessage(data.getString(MESSENGER_KEY) ?: "") .setDuration(SnackbarUtils.LENGTH_INDEFINITE) .show() } } override fun onDestroy() { super.onDestroy() MessengerUtils.unsubscribe(MESSENGER_KEY) MessengerUtils.unregister() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/metaData/MetaDataActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.metaData import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.MetaDataUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/05/15 * desc : demo about MetaDataUtils * ``` */ class MetaDataActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, MetaDataActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_meta_data } override fun bindItems(): List> { return CollectionUtils.newArrayList( CommonItemTitle("getMetaDataInApp", MetaDataUtils.getMetaDataInApp("app_meta_data")), CommonItemTitle("getMetaDataInActivity", MetaDataUtils.getMetaDataInActivity(this, "activity_meta_data").substring(1)) ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpActivity.java ================================================ package com.blankj.utilcode.pkg.feature.mvp; import android.content.Context; import android.content.Intent; import android.os.Bundle; import android.view.View; import com.blankj.common.activity.CommonActivity; import com.blankj.utilcode.pkg.R; import androidx.annotation.Nullable; /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/11/09
 *     desc  :
 * 
*/ public class MvpActivity extends CommonActivity { public static void start(Context context) { Intent starter = new Intent(context, MvpActivity.class); context.startActivity(starter); } @Override public int bindTitleRes() { return R.string.demo_mvp; } @Override public int bindLayout() { return R.layout.mvp_activity; } @Override public void initView(@Nullable Bundle savedInstanceState, @Nullable View contentView) { super.initView(savedInstanceState, contentView); new MvpView(this).addPresenter(new MvpPresenter()); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpModel.java ================================================ package com.blankj.utilcode.pkg.feature.mvp; import com.blankj.base.mvp.BaseModel; import com.blankj.utilcode.util.ThreadUtils; import com.blankj.utilcode.util.Utils; /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/11/26
 *     desc  :
 * 
*/ public class MvpModel extends BaseModel implements MvpMvp.Model { private int index; @Override public void onCreate() { index = 0; } @Override public void requestUpdateMsg(final Utils.Consumer consumer) { ThreadUtils.executeByCached(new ThreadUtils.SimpleTask() { @Override public String doInBackground() throws Throwable { Thread.sleep(2000); return "msg: " + index++; } @Override public void onSuccess(String result) { consumer.accept(result); } }); } @Override public void onDestroy() { super.onDestroy(); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpMvp.java ================================================ package com.blankj.utilcode.pkg.feature.mvp; import com.blankj.utilcode.util.Utils; /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/11/26
 *     desc  :
 * 
*/ public interface MvpMvp { interface View { void setLoadingVisible(boolean visible); void showMsg(CharSequence msg); } interface Presenter { void updateMsg(); } interface Model { void requestUpdateMsg(final Utils.Consumer consumer); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpPresenter.java ================================================ package com.blankj.utilcode.pkg.feature.mvp; import com.blankj.base.mvp.BasePresenter; import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.Utils; /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/11/26
 *     desc  :
 * 
*/ public class MvpPresenter extends BasePresenter implements MvpMvp.Presenter { @Override public void onBindView() { } @Override public void updateMsg() { getView().setLoadingVisible(true); getModel(MvpModel.class).requestUpdateMsg(new Utils.Consumer() { @Override public void accept(String s) { if (isAlive()) { getView().showMsg(s); getView().setLoadingVisible(false); } else { LogUtils.iTag(MvpView.TAG, "destroyed"); } } }); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/mvp/MvpView.java ================================================ package com.blankj.utilcode.pkg.feature.mvp; import android.text.Layout; import android.view.View; import android.widget.TextView; import com.blankj.base.mvp.BaseView; import com.blankj.utilcode.pkg.R; import com.blankj.utilcode.util.ClickUtils; import com.blankj.utilcode.util.LogUtils; import com.blankj.utilcode.util.SizeUtils; import com.blankj.utilcode.util.ThreadUtils; import com.blankj.utilcode.util.ToastUtils; /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/11/26
 *     desc  :
 * 
*/ public class MvpView extends BaseView implements MvpMvp.View { private TextView mvpTv; private TextView mvpMeasureWidthTv; private int i = 0; public MvpView(MvpActivity activity) { super(activity); mvpTv = activity.findViewById(R.id.mvpUpdateTv); ClickUtils.applyPressedBgDark(mvpTv); mvpTv.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { getPresenter(MvpPresenter.class).updateMsg(); } }); mvpMeasureWidthTv = activity.findViewById(R.id.mvpMeasureWidthTv); measure(); } private void measure() { ThreadUtils.runOnUiThreadDelayed(new Runnable() { @Override public void run() { float textWidth = Layout.getDesiredWidth(mvpMeasureWidthTv.getText(), mvpMeasureWidthTv.getPaint()) + SizeUtils.dp2px(16); float textWidth2 = mvpMeasureWidthTv.getPaint().measureText(mvpMeasureWidthTv.getText().toString()) + SizeUtils.dp2px(16); LogUtils.i(mvpMeasureWidthTv.getWidth(), textWidth, textWidth2); mvpMeasureWidthTv.setText(mvpMeasureWidthTv.getText().toString() + i); measure(); } }, 1000); } @Override public void setLoadingVisible(boolean visible) { final MvpActivity activity = getActivity(); if (visible) { activity.showLoading(new Runnable() { @Override public void run() { activity.finish(); } }); } else { activity.dismissLoading(); } } @Override public void showMsg(CharSequence msg) { ToastUtils.showLong(msg); } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/network/NetworkActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.network import android.content.Context import android.content.Intent import android.net.wifi.ScanResult import android.net.wifi.WifiManager import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about NetworkUtils * ``` */ class NetworkActivity : CommonActivity(), NetworkUtils.OnNetworkStatusChangedListener { companion object { fun start(context: Context) { PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, NetworkActivity::class.java) context.startActivity(starter) } override fun onDenied() { } }, PermissionConstants.LOCATION) } } private lateinit var itemsTask: ThreadUtils.SimpleTask>> private lateinit var wifiScanResultItem: CommonItemTitle private val consumer = Utils.Consumer { t -> wifiScanResultItem.setContent(scanResults2String(t.filterResults)) wifiScanResultItem.update() } override fun bindTitleRes(): Int { return R.string.demo_network } private fun getItemsTask(): ThreadUtils.SimpleTask>> { itemsTask = object : ThreadUtils.SimpleTask>>() { override fun doInBackground(): List> { return bindItems() } override fun onSuccess(result: List>) { dismissLoading() itemsView.updateItems(result) } } return itemsTask } override fun bindItems(): List> { if (ThreadUtils.isMainThread()) return arrayListOf() wifiScanResultItem = CommonItemTitle("getWifiScanResult", scanResults2String(NetworkUtils.getWifiScanResult().filterResults)) return CollectionUtils.newArrayList( CommonItemTitle("isConnected", NetworkUtils.isConnected().toString()), CommonItemTitle("getMobileDataEnabled", NetworkUtils.getMobileDataEnabled().toString()), CommonItemTitle("isMobileData", NetworkUtils.isMobileData().toString()), CommonItemTitle("is4G", NetworkUtils.is4G().toString()), CommonItemTitle("is5G", NetworkUtils.is5G().toString()), CommonItemTitle("isWifiConnected", NetworkUtils.isWifiConnected().toString()), CommonItemTitle("getNetworkOperatorName", NetworkUtils.getNetworkOperatorName()), CommonItemTitle("getNetworkTypeName", NetworkUtils.getNetworkType().toString()), CommonItemTitle("getBroadcastIpAddress", NetworkUtils.getBroadcastIpAddress()), CommonItemTitle("getIpAddressByWifi", NetworkUtils.getIpAddressByWifi()), CommonItemTitle("getGatewayByWifi", NetworkUtils.getGatewayByWifi()), CommonItemTitle("getNetMaskByWifi", NetworkUtils.getNetMaskByWifi()), CommonItemTitle("getServerAddressByWifi", NetworkUtils.getServerAddressByWifi()), CommonItemTitle("getSSID", NetworkUtils.getSSID()), CommonItemTitle("getIPv4Address", NetworkUtils.getIPAddress(true)), CommonItemTitle("getIPv6Address", NetworkUtils.getIPAddress(false)), CommonItemTitle("isWifiAvailable", NetworkUtils.isWifiAvailable().toString()), CommonItemTitle("isAvailable", NetworkUtils.isAvailable().toString()), CommonItemTitle("getBaiduDomainAddress", NetworkUtils.getDomainAddress("baidu.com")), wifiScanResultItem, CommonItemSwitch( R.string.network_wifi_enabled, { val wifiEnabled = NetworkUtils.getWifiEnabled() if (wifiEnabled) { NetworkUtils.addOnWifiChangedConsumer(consumer) } else { NetworkUtils.removeOnWifiChangedConsumer(consumer) } wifiEnabled }, { NetworkUtils.setWifiEnabled(it) ThreadUtils.executeByIo(getItemsTask()) } ), CommonItemClick(R.string.network_open_wireless_settings) { NetworkUtils.openWirelessSettings() } ) } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) NetworkUtils.registerNetworkStatusChangedListener(this) updateItems() } override fun onDisconnected() { ToastUtils.showLong("onDisconnected") updateItems() } override fun onConnected(networkType: NetworkUtils.NetworkType) { ToastUtils.showLong("onConnected: ${networkType.name}") updateItems() } private fun updateItems() { showLoading() ThreadUtils.executeByIo(getItemsTask()) } override fun onDestroy() { super.onDestroy() ThreadUtils.cancel(itemsTask) NetworkUtils.unregisterNetworkStatusChangedListener(this) NetworkUtils.removeOnWifiChangedConsumer(consumer) } private fun scanResults2String(results: List): String { val sb: StringBuilder = StringBuilder() for (result in results) { sb.append(String.format("${result.SSID}, Level: ${WifiManager.calculateSignalLevel(result.level, 4)}\n")) } return sb.toString() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/notification/NotificationActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.notification import android.app.PendingIntent import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.NotificationUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/10/22 * desc : demo about NotificationUtils * ``` */ class NotificationActivity : CommonActivity() { private var id: Int = 0 private var cancelId: Int = 0 companion object { fun start(context: Context) { val starter = Intent(context, NotificationActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_notification } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("areNotificationsEnabled", NotificationUtils.areNotificationsEnabled().toString()), CommonItemClick(R.string.notification_notify) { NotificationUtils.notify(id++) { param -> intent.putExtra("id", id); param.setSmallIcon(R.mipmap.ic_launcher) .setContentTitle("title") .setContentText("content text: $id") .setContentIntent(PendingIntent.getActivity(mActivity, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT)) .setAutoCancel(true) null } }, CommonItemClick(R.string.notification_cancel) { if (cancelId < id) { NotificationUtils.cancel(cancelId++) } else { ToastUtils.showShort("No notification.") } }, CommonItemClick(R.string.notification_cancel_all) { NotificationUtils.cancelAll() cancelId = id; }, CommonItemClick(R.string.notification_show) { NotificationUtils.setNotificationBarVisibility(true) } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/path/PathActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.path import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.PathUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about PathUtils * ``` */ class PathActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, PathActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_path } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("getRootPath", PathUtils.getRootPath()), CommonItemTitle("getDataPath", PathUtils.getDataPath()), CommonItemTitle("getDownloadCachePath", PathUtils.getDownloadCachePath()), CommonItemTitle("getInternalAppDataPath", PathUtils.getInternalAppDataPath()), CommonItemTitle("getInternalAppCodeCacheDir", PathUtils.getInternalAppCodeCacheDir()), CommonItemTitle("getInternalAppCachePath", PathUtils.getInternalAppCachePath()), CommonItemTitle("getInternalAppDbsPath", PathUtils.getInternalAppDbsPath()), CommonItemTitle("getInternalAppDbPath", PathUtils.getInternalAppDbPath("demo")), CommonItemTitle("getInternalAppFilesPath", PathUtils.getInternalAppFilesPath()), CommonItemTitle("getInternalAppSpPath", PathUtils.getInternalAppSpPath()), CommonItemTitle("getInternalAppNoBackupFilesPath", PathUtils.getInternalAppNoBackupFilesPath()), CommonItemTitle("getExternalStoragePath", PathUtils.getExternalStoragePath()), CommonItemTitle("getExternalMusicPath", PathUtils.getExternalMusicPath()), CommonItemTitle("getExternalPodcastsPath", PathUtils.getExternalPodcastsPath()), CommonItemTitle("getExternalRingtonesPath", PathUtils.getExternalRingtonesPath()), CommonItemTitle("getExternalAlarmsPath", PathUtils.getExternalAlarmsPath()), CommonItemTitle("getExternalNotificationsPath", PathUtils.getExternalNotificationsPath()), CommonItemTitle("getExternalPicturesPath", PathUtils.getExternalPicturesPath()), CommonItemTitle("getExternalMoviesPath", PathUtils.getExternalMoviesPath()), CommonItemTitle("getExternalDownloadsPath", PathUtils.getExternalDownloadsPath()), CommonItemTitle("getExternalDcimPath", PathUtils.getExternalDcimPath()), CommonItemTitle("getExternalDocumentsPath", PathUtils.getExternalDocumentsPath()), CommonItemTitle("getExternalAppDataPath", PathUtils.getExternalAppDataPath()), CommonItemTitle("getExternalAppCachePath", PathUtils.getExternalAppCachePath()), CommonItemTitle("getExternalAppFilesPath", PathUtils.getExternalAppFilesPath()), CommonItemTitle("getExternalAppMusicPath", PathUtils.getExternalAppMusicPath()), CommonItemTitle("getExternalAppPodcastsPath", PathUtils.getExternalAppPodcastsPath()), CommonItemTitle("getExternalAppRingtonesPath", PathUtils.getExternalAppRingtonesPath()), CommonItemTitle("getExternalAppAlarmsPath", PathUtils.getExternalAppAlarmsPath()), CommonItemTitle("getExternalAppNotificationsPath", PathUtils.getExternalAppNotificationsPath()), CommonItemTitle("getExternalAppPicturesPath", PathUtils.getExternalAppPicturesPath()), CommonItemTitle("getExternalAppMoviesPath", PathUtils.getExternalAppMoviesPath()), CommonItemTitle("getExternalAppDownloadPath", PathUtils.getExternalAppDownloadPath()), CommonItemTitle("getExternalAppDcimPath", PathUtils.getExternalAppDcimPath()), CommonItemTitle("getExternalAppDocumentsPath", PathUtils.getExternalAppDocumentsPath()), CommonItemTitle("getExternalAppObbPath", PathUtils.getExternalAppObbPath()) ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/permission/PermissionActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.permission import android.Manifest.permission import android.content.Context import android.content.Intent import android.os.Build import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/01/01 * desc : demo about PermissionUtils * ``` */ class PermissionActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, PermissionActivity::class.java) context.startActivity(starter) } } private val permissions: String init { val permissionList = PermissionUtils.getPermissions() if (permissionList.isEmpty()) { permissions = "" } else { val sb = StringBuilder() for (permission in permissionList) { sb.append("\n").append(permission.substring(permission.lastIndexOf('.') + 1)) } permissions = sb.deleteCharAt(0).toString() } } override fun bindTitleRes(): Int { return R.string.demo_permission } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList>().apply { add(CommonItemTitle("Permissions", permissions)) add(CommonItemClick(R.string.permission_open_app_settings, true) { PermissionUtils.launchAppDetailsSettings() }) add(CommonItemSwitch( R.string.permission_calendar_status, { PermissionUtils.isGranted(PermissionConstants.CALENDAR) }, { requestCalendar() } )) add(CommonItemSwitch( R.string.permission_record_audio_status, { PermissionUtils.isGranted(PermissionConstants.MICROPHONE) }, { requestRecordAudio() } )) add(CommonItemSwitch( R.string.permission_calendar_and_record_audio_status, { PermissionUtils.isGranted(PermissionConstants.CALENDAR, PermissionConstants.MICROPHONE) }, { requestCalendarAndRecordAudio() } )) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { add(CommonItemSwitch( R.string.permission_write_settings_status, { PermissionUtils.isGrantedWriteSettings() }, { requestWriteSettings() } )) add(CommonItemSwitch( R.string.permission_write_settings_status, { PermissionUtils.isGrantedDrawOverlays() }, { requestDrawOverlays() } )) } } } private fun requestCalendar() { PermissionUtils.permissionGroup(PermissionConstants.CALENDAR) .rationale { activity, shouldRequest -> PermissionHelper.showRationaleDialog(activity, shouldRequest) } .callback(object : PermissionUtils.FullCallback { override fun onGranted(permissionsGranted: List) { LogUtils.d(permissionsGranted) showSnackbar(true, "Calendar is granted") itemsView.updateItems(bindItems()) } override fun onDenied(permissionsDeniedForever: List, permissionsDenied: List) { LogUtils.d(permissionsDeniedForever, permissionsDenied) if (permissionsDeniedForever.isNotEmpty()) { showSnackbar(false, "Calendar is denied forever") } else { showSnackbar(false, "Calendar is denied") } itemsView.updateItems(bindItems()) } }) .theme { activity -> ScreenUtils.setFullScreen(activity) } .request() } private fun requestRecordAudio() { PermissionUtils.permissionGroup(PermissionConstants.MICROPHONE) .rationale { activity, shouldRequest -> PermissionHelper.showRationaleDialog(activity, shouldRequest) } .callback(object : PermissionUtils.FullCallback { override fun onGranted(permissionsGranted: List) { LogUtils.d(permissionsGranted) showSnackbar(true, "Microphone is granted") itemsView.updateItems(bindItems()) } override fun onDenied(permissionsDeniedForever: List, permissionsDenied: List) { LogUtils.d(permissionsDeniedForever, permissionsDenied) if (permissionsDeniedForever.isNotEmpty()) { showSnackbar(false, "Microphone is denied forever") } else { showSnackbar(false, "Microphone is denied") } itemsView.updateItems(bindItems()) } }) .request() } private fun requestCalendarAndRecordAudio() { PermissionUtils.permission(permission.READ_CALENDAR, permission.RECORD_AUDIO) .explain { activity, denied, shouldRequest -> PermissionHelper.showExplainDialog(activity, denied, shouldRequest) } .callback { isAllGranted, granted, deniedForever, denied -> LogUtils.d(granted, deniedForever, denied) itemsView.updateItems(bindItems()) if (isAllGranted) { showSnackbar(true, "Calendar and Microphone are granted") return@callback } if (deniedForever.isNotEmpty()) { showSnackbar(false, "Calendar or Microphone is denied forever") } else { showSnackbar(false, "Calendar or Microphone is denied") } } .request() } private fun requestWriteSettings() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PermissionUtils.requestWriteSettings(object : PermissionUtils.SimpleCallback { override fun onGranted() { showSnackbar(true, "Write Settings is granted") itemsView.updateItems(bindItems()) } override fun onDenied() { showSnackbar(false, "Write Settings is denied") itemsView.updateItems(bindItems()) } }) } } private fun requestDrawOverlays() { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PermissionUtils.requestDrawOverlays(object : PermissionUtils.SimpleCallback { override fun onGranted() { showSnackbar(true, "Draw Overlays is granted") itemsView.updateItems(bindItems()) } override fun onDenied() { showSnackbar(false, "Draw Overlays is denied") itemsView.updateItems(bindItems()) } }) } } private fun showSnackbar(isSuccess: Boolean, msg: String) { SnackbarUtils.with(mContentView) .setDuration(SnackbarUtils.LENGTH_LONG) .setMessage(msg) .apply { if (isSuccess) { showSuccess() } else { showError() } } } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/phone/PhoneActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.phone import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.helper.PermissionHelper import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.constant.PermissionConstants import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.PermissionUtils import com.blankj.utilcode.util.PhoneUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about PhoneUtils * ``` */ class PhoneActivity : CommonActivity() { companion object { fun start(context: Context) { PermissionHelper.request(context, object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, PhoneActivity::class.java) context.startActivity(starter) } override fun onDenied() { } }, PermissionConstants.PHONE) } } override fun bindTitleRes(): Int { return R.string.demo_phone } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("isPhone", PhoneUtils.isPhone().toString()), CommonItemTitle("getDeviceId", PhoneUtils.getDeviceId()), CommonItemTitle("getSerial", PhoneUtils.getSerial()), CommonItemTitle("getIMEI", PhoneUtils.getIMEI()), CommonItemTitle("getMEID", PhoneUtils.getMEID()), CommonItemTitle("getIMSI", PhoneUtils.getIMSI()), CommonItemTitle("getPhoneType", PhoneUtils.getPhoneType().toString()), CommonItemTitle("isSimCardReady", PhoneUtils.isSimCardReady().toString()), CommonItemTitle("getSimOperatorName", PhoneUtils.getSimOperatorName()), CommonItemTitle("getSimOperatorByMnc", PhoneUtils.getSimOperatorByMnc()), CommonItemClick(R.string.phone_dial) { PhoneUtils.dial("*10000#haha") }, CommonItemClick(R.string.phone_call) { PhoneUtils.call("*10000#haha") }, CommonItemClick(R.string.phone_send_sms) { PhoneUtils.sendSms("10000", "sendSms") } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/process/ProcessActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.process import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ProcessUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/13 * desc : demo about ProcessUtils * ``` */ class ProcessActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ProcessActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_process } override fun bindItems(): MutableList> { val set = ProcessUtils.getAllBackgroundProcesses() return CollectionUtils.newArrayList( CommonItemTitle("getForegroundProcessName", ProcessUtils.getForegroundProcessName()!!), CommonItemTitle("getAllBackgroundProcesses -> ${set.size}", getSetItems(set)), CommonItemTitle("isMainProcess", ProcessUtils.isMainProcess().toString()), CommonItemTitle("getCurrentProcessName", ProcessUtils.getCurrentProcessName()), CommonItemClick(R.string.process_kill_all_background).setOnItemClickListener { _, item, _ -> val bgSet = ProcessUtils.getAllBackgroundProcesses() val killedSet = ProcessUtils.killAllBackgroundProcesses() itemsView.updateItems( CollectionUtils.newArrayList( CommonItemTitle("getForegroundProcessName", ProcessUtils.getForegroundProcessName()), CommonItemTitle("getAllBackgroundProcesses -> ${bgSet.size}", getSetItems(bgSet)), CommonItemTitle("killAllBackgroundProcesses -> ${killedSet.size}", getSetItems(killedSet)), CommonItemTitle("isMainProcess", ProcessUtils.isMainProcess().toString()), CommonItemTitle("getCurrentProcessName", ProcessUtils.getCurrentProcessName()), item ) ) } ) } private fun getSetItems(set: Set): String { val iterator = set.iterator() val sb = StringBuilder() while (iterator.hasNext()) { sb.append("\n").append(iterator.next()) } return if (sb.isNotEmpty()) sb.deleteCharAt(0).toString() else "" } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/reflect/ReflectActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.reflect import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ReflectUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/01/29 * desc : demo about ReflectUtils * ``` */ class ReflectActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ReflectActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_reflect } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("source value", TestPrivateStaticFinal.STR), CommonItemTitle("reflect get", ReflectUtils.reflect(TestPrivateStaticFinal::class.java).field("STR").get()), CommonItemTitle("after reflect get", ReflectUtils.reflect(TestPrivateStaticFinal::class.java).field("STR", "reflect success").field("STR").get()), CommonItemTitle("source value", TestPrivateStaticFinal.STR) ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/reflect/TestPrivateStaticFinal.java ================================================ package com.blankj.utilcode.pkg.feature.reflect; import androidx.annotation.Keep; /** *
 *     author: blankj
 *     blog  : http://blankj.com
 *     time  : 2019/09/09
 *     desc  :
 * 
*/ @Keep public class TestPrivateStaticFinal { public static final String STR = "str"; } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/resource/ResourceActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.resource import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.Config import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ResourceUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/05/07 * desc : demo about ResourceUtils * ``` */ class ResourceActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ResourceActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_resource } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("readAssets2String", ResourceUtils.readAssets2String("test/test.txt")), CommonItemTitle("readAssets2List", ResourceUtils.readAssets2List("test/test.txt").toString()), CommonItemTitle("readRaw2List", ResourceUtils.readRaw2List(R.raw.test).toString()), CommonItemClick(R.string.resource_copy_file_from_assets_2_cache) { ResourceUtils.copyFileFromAssets("test", Config.CACHE_PATH + "assets/test") }, CommonItemClick(R.string.resource_copy_file_from_raw_2_cache) { ResourceUtils.copyFileFromRaw(R.raw.test, Config.CACHE_PATH + "raw/test.txt") } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/rom/RomActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.rom import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.RomUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/01/29 * desc : demo about RomUtils * ``` */ class RomActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, RomActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_rom } override fun bindItems(): MutableList> { val romInfo = RomUtils.getRomInfo() return CollectionUtils.newArrayList( CommonItemTitle("Rom Name", romInfo.name), CommonItemTitle("Rom Version", romInfo.version) ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/screen/ScreenActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.screen import android.content.Context import android.content.Intent import android.os.Build import android.widget.ImageView import android.widget.TextView import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemSwitch import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.helper.DialogHelper import com.blankj.utilcode.util.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/01/29 * desc : demo about RomUtils * ``` */ class ScreenActivity : CommonActivity() { companion object { fun start(context: Context) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { PermissionUtils.requestWriteSettings(object : PermissionUtils.SimpleCallback { override fun onGranted() { val starter = Intent(context, ScreenActivity::class.java) context.startActivity(starter) } override fun onDenied() { ToastUtils.showLong("No permission of write settings.") } }) } else { val starter = Intent(context, ScreenActivity::class.java) context.startActivity(starter) } } } override fun bindTitleRes(): Int { return R.string.demo_screen } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("getScreenWidth", ScreenUtils.getScreenWidth().toString()), CommonItemTitle("getScreenHeight", ScreenUtils.getScreenHeight().toString()), CommonItemTitle("getAppScreenWidth", ScreenUtils.getAppScreenWidth().toString()), CommonItemTitle("getAppScreenHeight", ScreenUtils.getAppScreenHeight().toString()), CommonItemTitle("getScreenDensity", ScreenUtils.getScreenDensity().toString()), CommonItemTitle("getScreenDensityDpi", ScreenUtils.getScreenDensityDpi().toString()), CommonItemTitle("getScreenRotation", ScreenUtils.getScreenRotation(this).toString()), CommonItemTitle("isScreenLock", ScreenUtils.isScreenLock().toString()), CommonItemTitle("getSleepDuration", ScreenUtils.getSleepDuration().toString()), CommonItemSwitch( "isFullScreen", { ScreenUtils.isFullScreen(this) }, { if (it) { ScreenUtils.setFullScreen(this) BarUtils.setStatusBarVisibility(this, false) } else { ScreenUtils.setNonFullScreen(this) BarUtils.setStatusBarVisibility(this, true) } } ), CommonItemSwitch( "isLandscape", { ScreenUtils.isLandscape() }, { if (it) { ScreenUtils.setLandscape(this) } else { ScreenUtils.setPortrait(this) } } ), CommonItemClick(R.string.screen_screenshot) { val iv :ImageView = ImageView(this) iv.setImageResource(R.mipmap.ic_launcher) val tv: TextView = TextView(this) tv.setText("wowowowwowo") DialogHelper.showScreenshotDialog(ImageUtils.view2Bitmap(tv)) // DialogHelper.showScreenshotDialog(ScreenUtils.screenShot(this)) } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/sdcard/SDCardActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.sdcard import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ConvertUtils import com.blankj.utilcode.util.SDCardUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/27 * desc : demo about SDCardUtils * ``` */ class SDCardActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, SDCardActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_sdcard } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemTitle("isSDCardEnableByEnvironment", SDCardUtils.isSDCardEnableByEnvironment().toString()), CommonItemTitle("getSDCardPathByEnvironment", SDCardUtils.getSDCardPathByEnvironment()), CommonItemTitle("getSDCardInfo", SDCardUtils.getSDCardInfo().toString()), CommonItemTitle("getMountedSDCardPath", SDCardUtils.getMountedSDCardPath().toString()), CommonItemTitle("getExternalTotalSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getExternalTotalSize(), 2)), CommonItemTitle("getExternalAvailableSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getExternalAvailableSize(), 2)), CommonItemTitle("getInternalTotalSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getInternalTotalSize(), 2)), CommonItemTitle("getInternalAvailableSize", ConvertUtils.byte2FitMemorySize(SDCardUtils.getInternalAvailableSize(), 2)) ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/shadow/ShadowActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.shadow import android.content.Context import android.content.Intent import android.graphics.Color import android.os.Bundle import android.view.View import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.ShadowUtils import com.blankj.utilcode.util.ShadowUtils.Config import com.blankj.utilcode.util.SizeUtils import kotlinx.android.synthetic.main.shadow_activity.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2019/10/22 * desc : demo about ShadowUtils * ``` */ class ShadowActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ShadowActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_shadow } override fun bindLayout(): Int { return R.layout.shadow_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) ShadowUtils.apply(shadowRectView, Config().setShadowColor(0x44000000, 0x55000000)) ShadowUtils.apply(shadowRoundRectView, Config().setShadowColor(0x44000000, 0x55000000).setShadowRadius( SizeUtils.dp2px(16f).toFloat())) ShadowUtils.apply(shadowCircleView, Config().setCircle().setShadowColor(0x44000000, 0x55000000)) ShadowUtils.apply(shadowRectView1, Config().setShadowColor(0x44000000, 0x55000000)) ShadowUtils.apply(shadowRoundRectView1, Config().setShadowColor(0x44000000, 0x55000000).setShadowRadius( SizeUtils.dp2px(16f).toFloat())) ShadowUtils.apply(shadowCircleView1, Config().setCircle().setShadowColor(0x44000000, 0x55000000)) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/snackbar/SnackbarActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.snackbar import android.content.Context import android.content.Intent import android.graphics.Color import android.text.SpannableStringBuilder import android.view.ViewGroup import android.widget.TextView import androidx.annotation.StringRes import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.SnackbarUtils import com.blankj.utilcode.util.SpanUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/10/17 * desc : demo about SnackbarUtils * ``` */ class SnackbarActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, SnackbarActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_snackbar } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.snackbar_short) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_short)) .setMessageColor(Color.WHITE) .setBgResource(R.drawable.snackbar_custom_bg) .show() }, CommonItemClick(R.string.snackbar_short_top) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_short_top)) .setMessageColor(Color.WHITE) .setBgResource(R.drawable.snackbar_custom_bg) .show(true) }, CommonItemClick(R.string.snackbar_short_with_action) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_short_with_action)) .setMessageColor(Color.WHITE) .setBgResource(R.drawable.snackbar_custom_bg) .setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) } .show() }, CommonItemClick(R.string.snackbar_short_with_action_top) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_short_with_action_top)) .setMessageColor(Color.WHITE) .setBgResource(R.drawable.snackbar_custom_bg) .setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) } .show(true) }, CommonItemClick(R.string.snackbar_long) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_long)) .setMessageColor(Color.WHITE) .setDuration(SnackbarUtils.LENGTH_LONG) .setBgResource(R.drawable.snackbar_custom_bg) .show() }, CommonItemClick(R.string.snackbar_long_with_action) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_long_with_action)) .setMessageColor(Color.WHITE) .setBgResource(R.drawable.snackbar_custom_bg) .setDuration(SnackbarUtils.LENGTH_LONG) .setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) } .show() }, CommonItemClick(R.string.snackbar_indefinite) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_indefinite)) .setMessageColor(Color.WHITE) .setDuration(SnackbarUtils.LENGTH_INDEFINITE) .setBgResource(R.drawable.snackbar_custom_bg) .show() }, CommonItemClick(R.string.snackbar_indefinite_with_action) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_indefinite_with_action)) .setMessageColor(Color.WHITE) .setDuration(SnackbarUtils.LENGTH_INDEFINITE) .setBgResource(R.drawable.snackbar_custom_bg) .setAction(getString(R.string.snackbar_click), Color.YELLOW) { ToastUtils.showShort(getString(R.string.snackbar_click)) } .show() }, CommonItemClick(R.string.snackbar_add_view) { val params = ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT) SnackbarUtils.with(mContentView) .setBgColor(Color.TRANSPARENT) .setDuration(SnackbarUtils.LENGTH_INDEFINITE) .show() SnackbarUtils.addView(R.layout.snackbar_custom, params) }, CommonItemClick(R.string.snackbar_add_view_with_action) { val params: ViewGroup.LayoutParams = ViewGroup.LayoutParams( ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT ) SnackbarUtils.with(mContentView) .setBgColor(Color.TRANSPARENT) .setDuration(SnackbarUtils.LENGTH_INDEFINITE) .show() SnackbarUtils.addView(R.layout.snackbar_custom, params) val snackbarView = SnackbarUtils.getView() if (snackbarView != null) { val tvSnackbarCustom = snackbarView.findViewById(R.id.snackbarCustomTv) tvSnackbarCustom.setText(R.string.snackbar_click_to_dismiss) snackbarView.setOnClickListener { SnackbarUtils.dismiss() } } }, CommonItemClick(R.string.snackbar_success) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_success)) .showSuccess() }, CommonItemClick(R.string.snackbar_warning) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_warning)) .showWarning() }, CommonItemClick(R.string.snackbar_error) { SnackbarUtils.with(mContentView) .setMessage(getMsg(R.string.snackbar_error)) .showError() }, CommonItemClick(R.string.snackbar_dismiss) { SnackbarUtils.dismiss() } ) } private fun getMsg(@StringRes resId: Int): SpannableStringBuilder { return SpanUtils() .appendImage(R.mipmap.ic_launcher, SpanUtils.ALIGN_CENTER) .appendSpace(32) .append(getString(resId)).setFontSize(24, true) .create() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/spStatic/SPStaticActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.spStatic import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.SPStaticUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/01/08 * desc : demo about SPUtils * ``` */ class SPStaticActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, SPStaticActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_spStatic } override fun bindItems(): MutableList> { val itemTitle = CommonItemTitle(sp2String(), true) return CollectionUtils.newArrayList( itemTitle, CommonItemClick(R.string.sp_put_string) { SPStaticUtils.put("STRING", "string") itemTitle.title = sp2String() }, CommonItemClick(R.string.sp_put_int) { SPStaticUtils.put("INT", 21) itemTitle.title = sp2String() }, CommonItemClick(R.string.sp_put_long) { SPStaticUtils.put("LONG", java.lang.Long.MAX_VALUE) itemTitle.title = sp2String() }, CommonItemClick(R.string.sp_put_float) { SPStaticUtils.put("FLOAT", Math.PI.toFloat()) itemTitle.title = sp2String() }, CommonItemClick(R.string.sp_put_boolean) { SPStaticUtils.put("BOOLEAN", true) itemTitle.title = sp2String() }, CommonItemClick(R.string.sp_put_string_set) { SPStaticUtils.put("SET", setOf("1", "2")) itemTitle.title = sp2String() }, CommonItemClick(R.string.sp_clear) { SPStaticUtils.clear() itemTitle.title = sp2String() } ) } private fun sp2String(): String { val sb = StringBuilder() val map = SPStaticUtils.getAll() if (map.isEmpty()) return "" for ((key, value) in map) { sb.append("\n") .append(key) .append(": ") .append(value) } return sb.deleteCharAt(0).toString() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/span/SpanActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.span import android.animation.ValueAnimator import android.content.Context import android.content.Intent import android.graphics.* import android.os.Bundle import android.text.Layout import android.text.SpannableStringBuilder import android.text.TextPaint import android.text.style.CharacterStyle import android.text.style.ClickableSpan import android.text.style.UpdateAppearance import android.view.View import android.view.animation.LinearInterpolator import androidx.annotation.ColorInt import com.blankj.common.activity.CommonActivity import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.SpanUtils import com.blankj.utilcode.util.ToastUtils import kotlinx.android.synthetic.main.span_activity.* /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/27 * desc : demo about SpanUtils * ``` */ class SpanActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, SpanActivity::class.java) context.startActivity(starter) } } private lateinit var mSpanUtils: SpanUtils private lateinit var animSsb: SpannableStringBuilder private var lineHeight: Int = 0 private var textSize: Float = 0f private lateinit var valueAnimator: ValueAnimator private lateinit var mShader: Shader private var mShaderWidth: Float = 0f private lateinit var matrix: Matrix private lateinit var mBlurMaskFilterSpan: BlurMaskFilterSpan private lateinit var mShadowSpan: ShadowSpan private lateinit var mForegroundAlphaColorSpan: ForegroundAlphaColorSpan private lateinit var mForegroundAlphaColorSpanGroup: ForegroundAlphaColorSpanGroup private lateinit var mPrinterString: String private var density: Float = 0f override fun bindTitleRes(): Int { return R.string.demo_span } override fun bindLayout(): Int { return R.layout.span_activity } override fun initView(savedInstanceState: Bundle?, contentView: View?) { super.initView(savedInstanceState, contentView) val clickableSpan = object : ClickableSpan() { override fun onClick(widget: View) { ToastUtils.showShort("事件触发了") } override fun updateDrawState(ds: TextPaint) { ds.color = Color.BLUE ds.isUnderlineText = false } } lineHeight = spanAboutTv.lineHeight textSize = spanAboutTv.textSize density = resources.displayMetrics.density SpanUtils.with(spanAboutTv) .appendLine("SpanUtils").setBackgroundColor(Color.LTGRAY).setBold().setForegroundColor(Color.YELLOW).setHorizontalAlign(Layout.Alignment.ALIGN_CENTER) .appendLine("前景色").setForegroundColor(Color.GREEN) // .appendLine("测试哈哈").setForegroundColor(Color.RED).setBackgroundColor(Color.LTGRAY).setFontSize(10).setLineHeight(280, SpanUtils.ALIGN_BOTTOM) .appendLine("背景色").setBackgroundColor(Color.LTGRAY) .appendLine("行高居中对齐").setLineHeight(2 * lineHeight, SpanUtils.ALIGN_CENTER).setBackgroundColor(Color.LTGRAY) .appendLine("行高底部对齐").setLineHeight(2 * lineHeight, SpanUtils.ALIGN_BOTTOM).setBackgroundColor(Color.GREEN) .appendLine("测试段落缩,首行缩进两字,其他行不缩进").setLeadingMargin(textSize.toInt() * 2, 10).setBackgroundColor(Color.GREEN) .appendLine("测试引用,后面的字是为了凑到两行的效果").setQuoteColor(Color.GREEN, 10, 10).setBackgroundColor(Color.LTGRAY) .appendLine("测试列表项,后面的字是为了凑到两行的效果").setBullet(Color.GREEN, 20, 10).setBackgroundColor(Color.LTGRAY).setBackgroundColor(Color.GREEN) .appendLine("32dp 字体").setFontSize(32, true) .appendLine("2 倍字体").setFontProportion(2f) .appendLine("横向 2 倍字体").setFontXProportion(1.5f) .appendLine("删除线").setStrikethrough() .appendLine("下划线").setUnderline() .append("测试").appendLine("上标").setSuperscript() .append("测试").appendLine("下标").setSubscript() .appendLine("粗体").setBold() .appendLine("斜体").setItalic() .appendLine("粗斜体").setBoldItalic() .appendLine("monospace 字体").setFontFamily("monospace") .appendLine("自定义字体").setTypeface(Typeface.createFromAsset(assets, "fonts/dnmbhs.ttf")) .appendLine("相反对齐").setHorizontalAlign(Layout.Alignment.ALIGN_OPPOSITE) .appendLine("居中对齐").setHorizontalAlign(Layout.Alignment.ALIGN_CENTER) .appendLine("正常对齐").setHorizontalAlign(Layout.Alignment.ALIGN_NORMAL) .append("测试").appendLine("点击事件").setClickSpan(clickableSpan) .append("测试").appendLine("Url").setUrl("https://github.com/Blankj/AndroidUtilCode") .append("测试").appendLine("模糊").setBlur(3f, BlurMaskFilter.Blur.NORMAL) .appendLine("颜色渐变").setShader(LinearGradient(0f, 0f, 64f * density * 4f, 0f, resources.getIntArray(R.array.rainbow), null, Shader.TileMode.REPEAT)).setFontSize(64, true) .appendLine("图片着色").setFontSize(64, true).setShader(BitmapShader(BitmapFactory.decodeResource(resources, R.drawable.span_cheetah), Shader.TileMode.REPEAT, Shader.TileMode.REPEAT)) .appendLine("阴影效果").setFontSize(64, true).setBackgroundColor(Color.BLACK).setShadow(24f, 8f, 8f, Color.WHITE) .append("小图").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_TOP) .append("顶部").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_CENTER) .append("居中").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_BASELINE) .append("底部").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_low, SpanUtils.ALIGN_BOTTOM) .appendLine("对齐").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_TOP) .append("大图").setBackgroundColor(Color.LTGRAY) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_TOP) .append("顶部").setBackgroundColor(Color.LTGRAY) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_TOP) .appendLine("对齐").setBackgroundColor(Color.LTGRAY) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_CENTER) .append("大图").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_CENTER) .append("居中").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_CENTER) .appendLine("对齐").setBackgroundColor(Color.GREEN) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_BOTTOM) .append("大图").setBackgroundColor(Color.LTGRAY) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_BOTTOM) .append("底部").setBackgroundColor(Color.LTGRAY) .appendImage(R.drawable.span_block_high, SpanUtils.ALIGN_BOTTOM) .appendLine("对齐").setBackgroundColor(Color.LTGRAY) .append("测试空格").appendSpace(30, Color.LTGRAY).appendSpace(50, Color.GREEN).appendSpace(100).appendSpace(30, Color.LTGRAY).appendSpace(50, Color.GREEN) .create() // initAnimSpan(); // startAnim(); } private fun initAnimSpan() { mShaderWidth = 64f * density * 4f mShader = LinearGradient(0f, 0f, mShaderWidth, 0f, resources.getIntArray(R.array.rainbow), null, Shader.TileMode.REPEAT) matrix = Matrix() mBlurMaskFilterSpan = BlurMaskFilterSpan(25f) mShadowSpan = ShadowSpan(8f, 8f, 8f, Color.WHITE) mForegroundAlphaColorSpan = ForegroundAlphaColorSpan(Color.TRANSPARENT) mForegroundAlphaColorSpanGroup = ForegroundAlphaColorSpanGroup(0f) mPrinterString = "打印动画,后面的文字是为了测试打印效果..." mSpanUtils = SpanUtils() .appendLine("彩虹动画").setFontSize(64, true).setShader(mShader) .appendLine("模糊动画").setFontSize(64, true).setSpans(mBlurMaskFilterSpan) .appendLine("阴影动画").setFontSize(64, true).setBackgroundColor(Color.BLACK).setSpans(mShadowSpan) .appendLine("透明动画").setFontSize(64, true).setSpans(mForegroundAlphaColorSpan) var i = 0 val len = mPrinterString.length while (i < len) { val span = ForegroundAlphaColorSpan(Color.TRANSPARENT) mSpanUtils.append(mPrinterString.substring(i, i + 1)).setSpans(span) mForegroundAlphaColorSpanGroup.addSpan(span) ++i } animSsb = mSpanUtils.create() } private fun startAnim() { valueAnimator = ValueAnimator.ofFloat(0f, 1f) valueAnimator.addUpdateListener { animation -> // shader matrix.reset() matrix.setTranslate(animation.animatedValue as Float * mShaderWidth, 0f) mShader.setLocalMatrix(matrix) // blur mBlurMaskFilterSpan.radius = 25 * (1.00001f - animation.animatedValue as Float) // shadow mShadowSpan.dx = 16 * (0.5f - animation.animatedValue as Float) mShadowSpan.dy = 16 * (0.5f - animation.animatedValue as Float) // alpha mForegroundAlphaColorSpan.setAlpha((255 * animation.animatedValue as Float).toInt()) // printer mForegroundAlphaColorSpanGroup.alpha = animation.animatedValue as Float // showMsg spanAboutAnimTv.text = animSsb } valueAnimator.interpolator = LinearInterpolator() valueAnimator.duration = (600 * 3).toLong() valueAnimator.repeatCount = ValueAnimator.INFINITE valueAnimator.start() } override fun doBusiness() {} override fun onDebouncingClick(view: View) {} // override fun onDestroy() { // if (valueAnimator.isRunning) { // valueAnimator.cancel() // } // super.onDestroy() // } } class BlurMaskFilterSpan(private var mRadius: Float) : CharacterStyle(), UpdateAppearance { private var mFilter: MaskFilter? = null var radius: Float get() = mRadius set(radius) { mRadius = radius mFilter = BlurMaskFilter(mRadius, BlurMaskFilter.Blur.NORMAL) } override fun updateDrawState(ds: TextPaint) { ds.maskFilter = mFilter } } class ForegroundAlphaColorSpan(@param:ColorInt private var mColor: Int) : CharacterStyle(), UpdateAppearance { fun setAlpha(alpha: Int) { mColor = Color.argb(alpha, Color.red(mColor), Color.green(mColor), Color.blue(mColor)) } override fun updateDrawState(ds: TextPaint) { ds.color = mColor } } class ForegroundAlphaColorSpanGroup(private val mAlpha: Float) { private val mSpans: ArrayList = ArrayList() var alpha: Float get() = mAlpha set(alpha) { val size = mSpans.size var total = 1.0f * size.toFloat() * alpha for (index in 0 until size) { val span = mSpans[index] if (total >= 1.0f) { span.setAlpha(255) total -= 1.0f } else { span.setAlpha((total * 255).toInt()) total = 0.0f } } } fun addSpan(span: ForegroundAlphaColorSpan) { span.setAlpha((mAlpha * 255).toInt()) mSpans.add(span) } } class ShadowSpan(private val radius: Float, var dx: Float, var dy: Float, private val shadowColor: Int) : CharacterStyle(), UpdateAppearance { override fun updateDrawState(tp: TextPaint) { tp.setShadowLayer(radius, dx, dy, shadowColor) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/CustomToast.kt ================================================ package com.blankj.utilcode.pkg.feature.toast import android.widget.TextView import androidx.annotation.StringRes import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.StringUtils import com.blankj.utilcode.util.ToastUtils import com.blankj.utilcode.util.ViewUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2017/08/31 * desc : demo about ToastUtils * ``` */ object CustomToast { fun showShort(text: CharSequence) { show(text, false) } fun showShort(@StringRes resId: Int) { show(StringUtils.getString(resId), false) } fun showShort(@StringRes resId: Int, vararg args: Any) { show(StringUtils.getString(resId, args), false) } fun showShort(format: String, vararg args: Any) { show(StringUtils.format(format, args), false) } fun showLong(text: CharSequence) { show(text, true) } fun showLong(@StringRes resId: Int) { show(StringUtils.getString(resId), true) } fun showLong(@StringRes resId: Int, vararg args: Any) { show(StringUtils.getString(resId, args), true) } fun showLong(format: String, vararg args: Any) { show(StringUtils.format(format, args), true) } private fun show(text: CharSequence, isLong: Boolean) { val textView = ViewUtils.layoutId2View(R.layout.toast_custom) as TextView textView.text = text ToastUtils.make().setDurationIsLong(isLong).show(textView) } fun cancel() { ToastUtils.cancel() } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/toast/ToastActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.toast import android.content.Context import android.content.Intent import android.graphics.Color import android.view.Gravity import androidx.core.content.ContextCompat import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.pkg.helper.DialogHelper import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.ColorUtils import com.blankj.utilcode.util.SpanUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2016/09/29 * desc : demo about ToastUtils * ``` */ class ToastActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, ToastActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_toast } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.toast_show_short) { Thread(Runnable { ToastUtils.showShort(R.string.toast_short) }).start() }, CommonItemClick(R.string.toast_show_long) { Thread(Runnable { ToastUtils.showLong(R.string.toast_long) }).start() }, CommonItemClick(R.string.toast_show_null) { ToastUtils.showLong(null) }, CommonItemClick(R.string.toast_show_empty) { ToastUtils.showLong("") }, CommonItemClick(R.string.toast_show_span) { ToastUtils.showLong( SpanUtils() .appendImage(R.mipmap.ic_launcher, SpanUtils.ALIGN_CENTER) .appendSpace(32) .append(getString(R.string.toast_span)).setFontSize(24, true) .create() ) }, CommonItemClick(R.string.toast_show_long_string) { ToastUtils.showLong(R.string.toast_long_string) }, CommonItemClick(R.string.toast_show_green_font) { ToastUtils.make().setTextColor(Color.GREEN).setDurationIsLong(true).show(R.string.toast_green_font) }, CommonItemClick(R.string.toast_show_bg_color) { ToastUtils.make().setBgColor(ColorUtils.getColor(R.color.colorAccent)).show(R.string.toast_bg_color) }, CommonItemClick(R.string.toast_show_bg_resource) { ToastUtils.make().setBgResource(R.drawable.toast_round_rect).show(R.string.toast_custom_bg) }, CommonItemClick(R.string.toast_show_left_icon) { ToastUtils.make().setLeftIcon(R.mipmap.ic_launcher).show(R.string.toast_show_left_icon) }, CommonItemClick(R.string.toast_show_dark_mode) { ToastUtils.make().setTopIcon(R.mipmap.ic_launcher).setMode(ToastUtils.MODE.DARK).show(R.string.toast_show_dark_mode) }, CommonItemClick(R.string.toast_show_middle) { ToastUtils.make().setGravity(Gravity.CENTER, 0, 0).show(R.string.toast_middle) }, CommonItemClick(R.string.toast_show_top) { ToastUtils.make().setGravity(Gravity.TOP or Gravity.CENTER_HORIZONTAL, 0, 0).show(R.string.toast_top) }, CommonItemClick(R.string.toast_show_custom_view) { Thread(Runnable { CustomToast.showLong(R.string.toast_custom_view) }).start() }, CommonItemClick(R.string.toast_cancel) { ToastUtils.cancel() }, CommonItemClick(R.string.toast_show_toast_dialog) { DialogHelper.showToastDialog() }, CommonItemClick(R.string.toast_show_toast_when_start_activity) { ToastUtils.showLong(R.string.toast_show_toast_when_start_activity) start(this) } ) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/uiMessage/UiMessageActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.uiMessage import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.common.item.CommonItemTitle import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.UiMessageUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2020/04/14 * desc : demo about UiMessageUtils * ``` */ class UiMessageActivity : CommonActivity(), UiMessageUtils.UiMessageCallback { private val titleItem: CommonItemTitle = CommonItemTitle("", true); private var sendContent: String = "" companion object { fun start(context: Context) { val starter = Intent(context, UiMessageActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_uiMessage } override fun bindItems(): List> { return CollectionUtils.newArrayList( titleItem, CommonItemClick(R.string.uiMessage_add_listener_id) { UiMessageUtils.getInstance().addListener(R.id.utilCodeUiMessageAddListenerId, this) }, CommonItemClick(R.string.uiMessage_remove_all_id) { UiMessageUtils.getInstance().removeListeners(R.id.utilCodeUiMessageAddListenerId) }, CommonItemClick(R.string.uiMessage_add_listener) { UiMessageUtils.getInstance().addListener(this) }, CommonItemClick(R.string.uiMessage_remove_listener) { UiMessageUtils.getInstance().removeListener(this) }, CommonItemClick(R.string.uiMessage_send) { sendContent = "send: UiMessageActivity#${UiMessageActivity.hashCode()}" titleItem.title = "" UiMessageUtils.getInstance().send(R.id.utilCodeUiMessageAddListenerId, UiMessageActivity) } ) } override fun handleMessage(localMessage: UiMessageUtils.UiMessage) { if (localMessage.id == R.id.utilCodeUiMessageAddListenerId) { var content: String = sendContent content += "\nreceive: UiMessageActivity#${localMessage.getObject().hashCode()}" titleItem.title = if (titleItem.title.toString().isEmpty()) { content } else { titleItem.title.toString() + "\n" + content } } } override fun onDestroy() { super.onDestroy() UiMessageUtils.getInstance().removeListeners(R.id.utilCodeUiMessageAddListenerId) UiMessageUtils.getInstance().removeListener(this) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/vibrate/VibrateActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.vibrate import android.content.Context import android.content.Intent import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemClick import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.VibrateUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/12/29 * desc : demo about VibrateUtils * ``` */ class VibrateActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, VibrateActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_vibrate } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( CommonItemClick(R.string.vibrate_1000ms) { VibrateUtils.vibrate(1000) }, CommonItemClick(R.string.vibrate_custom) { VibrateUtils.vibrate(longArrayOf(0, 1000, 1000, 2000, 2000, 1000), 1) }, CommonItemClick(R.string.vibrate_background) { backHome() mContentView.postDelayed({ // VibrateUtils.vibrate(1000) -- can not vibrate in background VibrateUtils.vibrateCompat(longArrayOf(0, 1000, 1000, 2000, 2000, 1000), 1) // VibrateUtils.vibrateCompat(1000) }, 1000) }, CommonItemClick(R.string.vibrate_cancel) { VibrateUtils.cancel() } ) } override fun onDestroy() { super.onDestroy() VibrateUtils.cancel() } private fun backHome() { val intent = Intent(Intent.ACTION_MAIN).apply { addCategory(Intent.CATEGORY_HOME) } startActivity(intent) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/feature/volume/VolumeActivity.kt ================================================ package com.blankj.utilcode.pkg.feature.volume import android.content.Context import android.content.Intent import android.media.AudioManager import android.widget.SeekBar import com.blankj.common.activity.CommonActivity import com.blankj.common.item.CommonItem import com.blankj.common.item.CommonItemSeekBar import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.CollectionUtils import com.blankj.utilcode.util.VolumeUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/12/29 * desc : demo about VibrateUtils * ``` */ class VolumeActivity : CommonActivity() { companion object { fun start(context: Context) { val starter = Intent(context, VolumeActivity::class.java) context.startActivity(starter) } } override fun bindTitleRes(): Int { return R.string.demo_volume } override fun bindItems(): MutableList> { return CollectionUtils.newArrayList( getItemSeekBar("Voice Call", AudioManager.STREAM_VOICE_CALL), getItemSeekBar("System", AudioManager.STREAM_SYSTEM), getItemSeekBar("Music", AudioManager.STREAM_MUSIC), getItemSeekBar("Ring", AudioManager.STREAM_RING), getItemSeekBar("Alarm", AudioManager.STREAM_ALARM), getItemSeekBar("Notification", AudioManager.STREAM_NOTIFICATION), getItemSeekBar("Dtmf", AudioManager.STREAM_DTMF) ) } private fun getItemSeekBar(title: CharSequence, streamType: Int): CommonItemSeekBar { return CommonItemSeekBar(title, VolumeUtils.getMaxVolume(streamType), object : CommonItemSeekBar.ProgressListener() { override fun getCurValue(): Int { return VolumeUtils.getVolume(streamType) } override fun onProgressChanged(seekBar: SeekBar?, progress: Int, fromUser: Boolean) { VolumeUtils.setVolume(streamType, progress, AudioManager.FLAG_SHOW_UI) } }) } override fun onResume() { super.onResume() itemsView.updateItems(bindItems()) } } ================================================ FILE: feature/utilcode/pkg/src/main/java/com/blankj/utilcode/pkg/helper/DialogHelper.kt ================================================ package com.blankj.utilcode.pkg.helper import android.content.Context import android.content.DialogInterface import android.graphics.Bitmap import android.graphics.drawable.ColorDrawable import android.text.method.ScrollingMovementMethod import android.view.Gravity import android.view.View import android.view.Window import android.widget.Button import android.widget.EditText import android.widget.ImageView import android.widget.TextView import androidx.fragment.app.FragmentActivity import com.blankj.base.dialog.BaseDialogFragment import com.blankj.base.dialog.DialogLayoutCallback import com.blankj.utilcode.pkg.R import com.blankj.utilcode.util.ActivityUtils import com.blankj.utilcode.util.KeyboardUtils import com.blankj.utilcode.util.ScreenUtils import com.blankj.utilcode.util.ToastUtils /** * ``` * author: Blankj * blog : http://blankj.com * time : 2018/01/10 * desc : helper about dialog * ``` */ object DialogHelper { fun showKeyboardDialog(context: Context) { BaseDialogFragment().init(context, object : DialogLayoutCallback { override fun bindTheme(): Int { return View.NO_ID } override fun bindLayout(): Int { return R.layout.keyboard_dialog } override fun initView(dialog: BaseDialogFragment, contentView: View) { dialog.dialog.setCanceledOnTouchOutside(false) val keyboardDialogEt = contentView.findViewById(R.id.keyboardDialogEt) val listener = View.OnClickListener { v -> when (v.id) { R.id.keyboardDialogHideSoftInputBtn -> KeyboardUtils.hideSoftInput(keyboardDialogEt) R.id.keyboardDialogShowSoftInputBtn -> KeyboardUtils.showSoftInput(keyboardDialogEt) R.id.keyboardDialogToggleSoftInputBtn -> KeyboardUtils.toggleSoftInput() R.id.keyboardDialogCloseBtn -> { KeyboardUtils.hideSoftInput(keyboardDialogEt) dialog.dismiss() } } } contentView.findViewById(R.id.keyboardDialogHideSoftInputBtn).setOnClickListener(listener) contentView.findViewById(R.id.keyboardDialogShowSoftInputBtn).setOnClickListener(listener) contentView.findViewById(R.id.keyboardDialogToggleSoftInputBtn).setOnClickListener(listener) contentView.findViewById(R.id.keyboardDialogCloseBtn).setOnClickListener(listener) dialog.dialog.setOnShowListener(DialogInterface.OnShowListener { KeyboardUtils.fixAndroidBug5497(dialog.dialog.window!!) KeyboardUtils.showSoftInput() }) } override fun setWindowStyle(window: Window) { window.setBackgroundDrawable(ColorDrawable(0)) val attributes = window.attributes attributes.gravity = Gravity.BOTTOM attributes.width = ScreenUtils.getAppScreenWidth() attributes.height = ScreenUtils.getAppScreenHeight() * 2 / 5 attributes.windowAnimations = R.style.BottomDialogAnimation window.attributes = attributes } override fun onCancel(dialog: BaseDialogFragment) {} override fun onDismiss(dialog: BaseDialogFragment) {} }).show() } fun showFragmentDialog(info: CharSequence) { val topActivity = ActivityUtils.getTopActivity() ?: return BaseDialogFragment().init(topActivity as FragmentActivity, object : DialogLayoutCallback { override fun bindTheme(): Int { return R.style.CommonContentDialogStyle } override fun bindLayout(): Int { return R.layout.fragment_dialog } override fun initView(dialog: BaseDialogFragment, contentView: View) { val aboutTv = contentView.findViewById(R.id.fragmentDialogAboutTv) aboutTv.movementMethod = ScrollingMovementMethod.getInstance() aboutTv.text = info } override fun setWindowStyle(window: Window) {} override fun onCancel(dialog: BaseDialogFragment) {} override fun onDismiss(dialog: BaseDialogFragment) {} }).show() } fun showScreenshotDialog(screenshot: Bitmap) { val topActivity = ActivityUtils.getTopActivity() ?: return BaseDialogFragment().init(topActivity as FragmentActivity, object : DialogLayoutCallback { override fun bindTheme(): Int { return R.style.CommonContentDialogStyle } override fun bindLayout(): Int { return R.layout.screen_dialog } override fun initView(dialog: BaseDialogFragment, contentView: View) { contentView.findViewById(R.id.screenDialogScreenshotIv) .setImageBitmap(screenshot) } override fun setWindowStyle(window: Window) {} override fun onCancel(dialog: BaseDialogFragment) {} override fun onDismiss(dialog: BaseDialogFragment) {} }).show() } fun showToastDialog() { val topActivity = ActivityUtils.getTopActivity() ?: return BaseDialogFragment().init(topActivity as FragmentActivity, object : DialogLayoutCallback { override fun bindTheme(): Int { return R.style.CommonContentDialogStyle } override fun bindLayout(): Int { return R.layout.toast_dialog } override fun initView(dialog: BaseDialogFragment, contentView: View) { contentView.findViewById