├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── app ├── .gitignore ├── build.gradle ├── github │ └── release │ │ ├── app-github-release.apk │ │ └── output.json ├── libs │ ├── activation.jar │ ├── additionnal.jar │ ├── commons-email-1.4.jar │ └── mail.jar ├── proguard-fresco.pro ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── ml │ │ └── timik │ │ └── picbox │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── assets │ │ ├── License.txt │ │ └── Privacy.txt │ ├── ic_launcher-web.png │ ├── java │ │ └── ml │ │ │ └── timik │ │ │ └── picbox │ │ │ ├── beans │ │ │ ├── Category.java │ │ │ ├── Collection.java │ │ │ ├── CollectionGroup.java │ │ │ ├── Comment.java │ │ │ ├── CommentRule.java │ │ │ ├── DownloadItemStatus.java │ │ │ ├── DownloadTask.java │ │ │ ├── LocalCollection.java │ │ │ ├── MarketSiteCategory.java │ │ │ ├── MarketSource.java │ │ │ ├── Picture.java │ │ │ ├── PictureRule.java │ │ │ ├── Rule.java │ │ │ ├── Selector.java │ │ │ ├── Site.java │ │ │ ├── SiteGroup.java │ │ │ ├── SubRule.java │ │ │ ├── Tag.java │ │ │ ├── TagRule.java │ │ │ ├── Video.java │ │ │ └── VideoRule.java │ │ │ ├── configs │ │ │ ├── ImagePipelineConfigBuilder.java │ │ │ ├── Names.java │ │ │ ├── PasteEEConfig.java │ │ │ └── UrlConfig.java │ │ │ ├── core │ │ │ ├── CrashHandler.java │ │ │ ├── HtmlContentParser.java │ │ │ └── RuleParser.java │ │ │ ├── dataholders │ │ │ ├── AbstractTagHolder.java │ │ │ ├── DBHelper.java │ │ │ ├── DownloadTaskHolder.java │ │ │ ├── FavorTagHolder.java │ │ │ ├── FavouriteHolder.java │ │ │ ├── HistoryHolder.java │ │ │ ├── MarketSourceHolder.java │ │ │ ├── SearchHistoryHolder.java │ │ │ ├── SearchSuggestionHolder.java │ │ │ ├── SiteHolder.java │ │ │ └── SiteTagHolder.java │ │ │ ├── download │ │ │ ├── DownloadManager.java │ │ │ └── DownloadService.java │ │ │ ├── helpers │ │ │ ├── DataBackup.java │ │ │ ├── DataRestore.java │ │ │ ├── DynamicIjkLibLoader.java │ │ │ ├── DynamicLibDownloader.java │ │ │ ├── ExampleSites.java │ │ │ ├── FastBlur.java │ │ │ ├── FileHelper.java │ │ │ ├── Logger.java │ │ │ ├── MDStatusBarCompat.java │ │ │ ├── SiteFlagHandler.java │ │ │ ├── SitePropViewHolder.java │ │ │ ├── URLImageParser.java │ │ │ ├── UpdateManager.java │ │ │ └── VideoThumbLoader.java │ │ │ ├── http │ │ │ ├── DownloadUtil.java │ │ │ ├── HProxy.java │ │ │ ├── HRequestBuilder.java │ │ │ ├── HViewerHttpClient.java │ │ │ ├── HttpDns.java │ │ │ ├── ImageLoader.java │ │ │ ├── ImageSizeInputStreamProvider.java │ │ │ └── MyOkHttpNetworkFetcher.java │ │ │ ├── libraries │ │ │ ├── advrecyclerview │ │ │ │ └── common │ │ │ │ │ ├── data │ │ │ │ │ └── AbstractExpandableDataProvider.java │ │ │ │ │ └── widget │ │ │ │ │ ├── ExpandableItemIndicator.java │ │ │ │ │ ├── ExpandableItemIndicatorImplAnim.java │ │ │ │ │ └── ExpandableItemIndicatorImplNoAnim.java │ │ │ └── swipeback │ │ │ │ ├── common │ │ │ │ ├── ActivityLifecycleHelper.java │ │ │ │ └── SwipeBackApplication.java │ │ │ │ └── dispatchactivity │ │ │ │ ├── SwipeBackActivity.java │ │ │ │ ├── SwipeDialog.java │ │ │ │ └── SwipeWindowHelper.java │ │ │ ├── picboxApplication.java │ │ │ ├── ui │ │ │ ├── activities │ │ │ │ ├── AddSiteActivity.java │ │ │ │ ├── BaseActivity.java │ │ │ │ ├── CollectionActivity.java │ │ │ │ ├── DownloadActivity.java │ │ │ │ ├── DownloadTaskActivity.java │ │ │ │ ├── FavouriteActivity.java │ │ │ │ ├── HistoryActivity.java │ │ │ │ ├── LicenseActivity.java │ │ │ │ ├── LockActivity.java │ │ │ │ ├── LoginActivity.java │ │ │ │ ├── MainActivity.java │ │ │ │ ├── MarketActivity.java │ │ │ │ ├── ModifySiteActivity.java │ │ │ │ ├── MyCaptureActivity.java │ │ │ │ ├── PictureViewerActivity.java │ │ │ │ ├── PrivacyActivity.java │ │ │ │ ├── SetPatternActivity.java │ │ │ │ ├── SetPinActivity.java │ │ │ │ ├── SettingActivity.java │ │ │ │ └── VideoViewerActivity.java │ │ │ ├── adapters │ │ │ │ ├── CategoryAdapter.java │ │ │ │ ├── CategoryInputAdapter.java │ │ │ │ ├── CollectionAdapter.java │ │ │ │ ├── CollectionTagAdapter.java │ │ │ │ ├── CommentAdapter.java │ │ │ │ ├── DownloadedTaskAdapter.java │ │ │ │ ├── DownloadingTaskAdapter.java │ │ │ │ ├── LocalCollectionAdapter.java │ │ │ │ ├── MarketSiteAdapter.java │ │ │ │ ├── MySearchAdapter.java │ │ │ │ ├── PicturePagerAdapter.java │ │ │ │ ├── PictureVideoAdapter.java │ │ │ │ ├── PictureViewerAdapter.java │ │ │ │ ├── SiteAdapter.java │ │ │ │ ├── SiteTagAdapter.java │ │ │ │ └── ViewPagerAdapter.java │ │ │ ├── customs │ │ │ │ ├── AnimationOnActivity.java │ │ │ │ ├── AreaClickHelper.java │ │ │ │ ├── AutoFitGridLayoutManager.java │ │ │ │ ├── AutoFitStaggeredGridLayoutManager.java │ │ │ │ ├── DragMarginDrawerLayout.java │ │ │ │ ├── ExAutoLabelUI.java │ │ │ │ ├── ExPagerBottomTabLayout.java │ │ │ │ ├── ExTabLayout.java │ │ │ │ ├── ExViewPager.java │ │ │ │ ├── MultiTouchViewPager.java │ │ │ │ ├── RetainingDataSourceSupplier.java │ │ │ │ ├── ScalingImageView.java │ │ │ │ ├── WrappedGridLayoutManager.java │ │ │ │ ├── WrappedLinearLayoutManager.java │ │ │ │ ├── WrappedPullLoadMoreRecyclerView.java │ │ │ │ └── WrappedStaggeredGridLayoutManager.java │ │ │ ├── dataproviders │ │ │ │ ├── AbstractDataProvider.java │ │ │ │ ├── ExpandableDataProvider.java │ │ │ │ └── ListDataProvider.java │ │ │ ├── fragments │ │ │ │ ├── AboutFragment.java │ │ │ │ ├── CollectionFragment.java │ │ │ │ ├── LockMethodFragment.java │ │ │ │ ├── MyFragment.java │ │ │ │ ├── ProxyFragment.java │ │ │ │ └── SettingFragment.java │ │ │ ├── listeners │ │ │ │ ├── AppBarStateChangeListener.java │ │ │ │ ├── OnItemLongClickListener.java │ │ │ │ ├── SimpleVideoListener.java │ │ │ │ └── SwipeBackOnPageChangeListener.java │ │ │ └── preferences │ │ │ │ ├── LockMethodPreference.java │ │ │ │ ├── LongClickPreference.java │ │ │ │ ├── NumberPickerPreference.java │ │ │ │ ├── SetPatternLockPreference.java │ │ │ │ └── SetPinLockPreference.java │ │ │ └── utils │ │ │ ├── AppUtils.java │ │ │ ├── DensityUtil.java │ │ │ ├── DocumentUtil.java │ │ │ ├── DrawableUtil.java │ │ │ ├── EmailUtil.java │ │ │ ├── FileType.java │ │ │ ├── FileUtils.java │ │ │ ├── ImageScaleUtil.java │ │ │ ├── MathUtil.java │ │ │ ├── MyThumbnailUtils.java │ │ │ ├── PatternLockUtils.java │ │ │ ├── QRCodeUtil.java │ │ │ ├── RandomUtil.java │ │ │ ├── RegexValidateUtil.java │ │ │ ├── SharedPreferencesUtil.java │ │ │ ├── SimpleFileUtil.java │ │ │ ├── StringEscapeUtils.java │ │ │ ├── UriUtil.java │ │ │ ├── VibratorUtil.java │ │ │ └── ViewUtil.java │ └── res │ │ ├── anim │ │ ├── bottom_bar_hide_to_bottom.xml │ │ ├── bottom_bar_show_from_bottom.xml │ │ ├── fade_in.xml │ │ ├── fade_out.xml │ │ ├── hide_to_bottom.xml │ │ ├── in_from_left.xml │ │ ├── in_from_right.xml │ │ ├── no_anim.xml │ │ ├── out_to_left.xml │ │ ├── out_to_right.xml │ │ └── show_from_bottom.xml │ │ ├── animator │ │ ├── expand_less_to_expand_more_rotation.xml │ │ └── expand_more_to_expand_less_rotation.xml │ │ ├── drawable-hdpi │ │ └── material_shadow_z3.xml │ │ ├── drawable-ldpi │ │ └── material_shadow_z3.xml │ │ ├── drawable-mdpi │ │ └── material_shadow_z3.xml │ │ ├── drawable-nodpi │ │ ├── backdrop.jpg │ │ ├── icon_grid.png │ │ ├── icon_list.png │ │ ├── material_shadow_z3_mdpi.9.png │ │ ├── material_shadow_z3_xhdpi.9.png │ │ ├── material_shadow_z3_xxhdpi.9.png │ │ ├── material_shadow_z3_xxxhdpi.9.png │ │ ├── polygon_5.jpg │ │ ├── shadow_bottom.xml │ │ ├── shadow_right.xml │ │ └── shadow_top.xml │ │ ├── drawable-xhdpi │ │ └── material_shadow_z3.xml │ │ ├── drawable-xxhdpi │ │ └── material_shadow_z3.xml │ │ ├── drawable-xxxhdpi │ │ └── material_shadow_z3.xml │ │ ├── drawable │ │ ├── avatar.jpg │ │ ├── bg_button.xml │ │ ├── bg_cover.xml │ │ ├── dot_filled_black.xml │ │ ├── ic_add_black.xml │ │ ├── ic_add_white.xml │ │ ├── ic_backspace_black.png │ │ ├── ic_broken_image_white.xml │ │ ├── ic_check_white.xml │ │ ├── ic_clear_all_white.xml │ │ ├── ic_comment_primary.xml │ │ ├── ic_create_new_group_black.xml │ │ ├── ic_description_primary.xml │ │ ├── ic_exit_to_app_black.xml │ │ ├── ic_expand_less.xml │ │ ├── ic_expand_less_to_expand_more.xml │ │ ├── ic_expand_more.xml │ │ ├── ic_expand_more_to_expand_less.xml │ │ ├── ic_favorite_border_white.xml │ │ ├── ic_favorite_white.xml │ │ ├── ic_file_download_primary.xml │ │ ├── ic_file_download_white.xml │ │ ├── ic_filter_1_black.xml │ │ ├── ic_filter_2_black.xml │ │ ├── ic_filter_3_black.xml │ │ ├── ic_filter_4_black.xml │ │ ├── ic_filter_5_black.xml │ │ ├── ic_filter_6_black.xml │ │ ├── ic_filter_7_black.xml │ │ ├── ic_filter_8_black.xml │ │ ├── ic_filter_9_black.xml │ │ ├── ic_filter_9_plus_black.xml │ │ ├── ic_folder_image_primary.xml │ │ ├── ic_folder_image_white.xml │ │ ├── ic_gallery_black.xml │ │ ├── ic_gallery_primary.xml │ │ ├── ic_gallery_white.xml │ │ ├── ic_group_black.xml │ │ ├── ic_high_res_white.xml │ │ ├── ic_history_white.xml │ │ ├── ic_info_outline_white.xml │ │ ├── ic_json_white.xml │ │ ├── ic_load_high_res_white.xml │ │ ├── ic_next_download_primary_dark.xml │ │ ├── ic_pause_primary_dark.xml │ │ ├── ic_play_arrow_primary_dark.xml │ │ ├── ic_qrcode_scan_white.xml │ │ ├── ic_refresh_white.xml │ │ ├── ic_screen_rotation_white.xml │ │ ├── ic_search_white.xml │ │ ├── ic_settings_black.xml │ │ ├── ic_shopping_basket_white.xml │ │ ├── ic_star_border_white.xml │ │ ├── ic_star_white.xml │ │ ├── ic_update_white.xml │ │ ├── ic_video_white.xml │ │ ├── ic_web_white.xml │ │ ├── selector_check.xml │ │ ├── selector_comment.xml │ │ ├── selector_description.xml │ │ ├── selector_download.xml │ │ ├── selector_download_primary.xml │ │ ├── selector_favourite.xml │ │ ├── selector_folder_image.xml │ │ ├── selector_folder_image_primary.xml │ │ ├── selector_gallery.xml │ │ ├── selector_history.xml │ │ ├── selector_search.xml │ │ ├── selector_web.xml │ │ └── side_nav_bar.xml │ │ ├── layout │ │ ├── activity_add_site.xml │ │ ├── activity_collection.xml │ │ ├── activity_collection_list.xml │ │ ├── activity_download_list.xml │ │ ├── activity_lock.xml │ │ ├── activity_login.xml │ │ ├── activity_main.xml │ │ ├── activity_market.xml │ │ ├── activity_modify_site.xml │ │ ├── activity_picture_viewer.xml │ │ ├── activity_preference.xml │ │ ├── activity_set_pin.xml │ │ ├── activity_text.xml │ │ ├── activity_video_viewer.xml │ │ ├── content_main.xml │ │ ├── dialog_delete_confirm.xml │ │ ├── dialog_loading.xml │ │ ├── dialog_picture_exif.xml │ │ ├── dialog_update.xml │ │ ├── fragment_collection.xml │ │ ├── item_add_btn.xml │ │ ├── item_category.xml │ │ ├── item_category_input.xml │ │ ├── item_collection.xml │ │ ├── item_collection_grid.xml │ │ ├── item_collection_group.xml │ │ ├── item_collection_tag.xml │ │ ├── item_collection_waterfall.xml │ │ ├── item_comment.xml │ │ ├── item_download_task.xml │ │ ├── item_market_site.xml │ │ ├── item_picture_index.xml │ │ ├── item_picture_viewer.xml │ │ ├── item_site.xml │ │ ├── item_site_group.xml │ │ ├── item_site_tag.xml │ │ ├── item_source_spinner.xml │ │ ├── item_tab.xml │ │ ├── item_video_index.xml │ │ ├── nav_categories.xml │ │ ├── nav_main.xml │ │ ├── nav_tags.xml │ │ ├── view_collection_comment.xml │ │ ├── view_collection_desciption.xml │ │ ├── view_collection_index.xml │ │ ├── view_collection_list.xml │ │ ├── view_input_source.xml │ │ ├── view_input_text.xml │ │ ├── view_market_site_list.xml │ │ ├── view_picture_viewer.xml │ │ ├── view_site_details.xml │ │ ├── view_tag_list.xml │ │ └── widget_expandable_item_indicator.xml │ │ ├── menu │ │ └── search.xml │ │ ├── mipmap-hdpi │ │ └── ic_launcher.png │ │ ├── mipmap-mdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxhdpi │ │ └── ic_launcher.png │ │ ├── mipmap-xxxhdpi │ │ ├── download.png │ │ ├── favorites.png │ │ └── ic_launcher.png │ │ ├── values-v19 │ │ ├── dimens.xml │ │ └── styles.xml │ │ ├── values-v21 │ │ ├── dimens.xml │ │ └── styles.xml │ │ ├── values │ │ ├── attrs.xml │ │ ├── colors.xml │ │ ├── dimens.xml │ │ ├── drawables.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── about.xml │ │ ├── preferences.xml │ │ ├── preferences_lock_methods.xml │ │ ├── proxy.xml │ │ └── shortcuts.xml │ └── test │ └── java │ └── ml │ └── timik │ └── picbox │ └── ExampleUnitTest.java ├── build.gradle ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── httpdns ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── ml │ │ └── timik │ │ └── httpdns │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── sina │ │ │ └── util │ │ │ └── dnscache │ │ │ ├── AppConfigUtil.java │ │ │ ├── DNSCache.java │ │ │ ├── DNSCacheConfig.java │ │ │ ├── DomainInfo.java │ │ │ ├── Tools.java │ │ │ ├── cache │ │ │ ├── DBConstants.java │ │ │ ├── DNSCacheDatabaseHelper.java │ │ │ ├── DnsCacheManager.java │ │ │ └── IDnsCache.java │ │ │ ├── dnsp │ │ │ ├── DnsConfig.java │ │ │ ├── DnsManager.java │ │ │ ├── IDns.java │ │ │ ├── IDnsProvider.java │ │ │ ├── IJsonParser.java │ │ │ └── impl │ │ │ │ ├── HttpPodDns.java │ │ │ │ ├── LocalDns.java │ │ │ │ ├── SinaHttpDns.java │ │ │ │ └── UdpDns.java │ │ │ ├── log │ │ │ ├── FileUtil.java │ │ │ ├── HttpDnsLogManager.java │ │ │ └── IDnsLog.java │ │ │ ├── model │ │ │ ├── ConnectFailModel.java │ │ │ ├── DomainModel.java │ │ │ ├── HttpDnsPack.java │ │ │ └── IpModel.java │ │ │ ├── net │ │ │ ├── ApacheHttpClientNetworkRequests.java │ │ │ ├── INetworkRequests.java │ │ │ └── networktype │ │ │ │ ├── Constants.java │ │ │ │ ├── NetworkManager.java │ │ │ │ └── NetworkStateReceiver.java │ │ │ ├── query │ │ │ ├── IQuery.java │ │ │ └── QueryManager.java │ │ │ ├── score │ │ │ ├── IPlugIn.java │ │ │ ├── IScore.java │ │ │ ├── PlugInManager.java │ │ │ ├── ScoreManager.java │ │ │ └── plugin │ │ │ │ ├── ErrNumPlugin.java │ │ │ │ ├── PriorityPlugin.java │ │ │ │ ├── SpeedTestPlugin.java │ │ │ │ ├── SuccessNumPlugin.java │ │ │ │ └── SuccessTimePlugin.java │ │ │ ├── speedtest │ │ │ ├── BaseSpeedTest.java │ │ │ ├── ISpeedtest.java │ │ │ ├── SpeedtestManager.java │ │ │ └── impl │ │ │ │ ├── PingTest.java │ │ │ │ └── Socket80Test.java │ │ │ └── thread │ │ │ └── RealTimeThreadPool.java │ └── res │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── ml │ └── timik │ └── httpdns │ └── ExampleUnitTest.java ├── images ├── 1.png ├── 10.png ├── 11.png ├── 12.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.gif ├── 7.gif ├── 8.gif ├── 9.png ├── getitoncoolmarket.png └── qrcodes │ ├── 1.lofi.png │ ├── 10.pixiv.png │ ├── 11.177.png │ ├── 12.绝对领域.png │ ├── 13.二次萌エロ画像ブログ.png │ ├── 2.g.png │ ├── 3.exhentai.png │ ├── 4.wnacg.png │ ├── 5.nhentai.png │ ├── 6.草榴社区.png │ ├── 7.e-shuushuu.png │ ├── 8.xiuren.png │ └── 9.rosiyy.png └── settings.gradle /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .externalNativeBuild 10 | 11 | # Built application files 12 | *.ap_ 13 | 14 | # Files for the Dalvik VM 15 | *.dex 16 | 17 | # Java class files 18 | *.class 19 | 20 | # Generated files 21 | bin/ 22 | gen/ 23 | 24 | # Gradle files 25 | .gradle/ 26 | build/ 27 | 28 | # Local configuration file (sdk path, etc) 29 | local.properties 30 | 31 | # Proguard folder generated by Eclipse 32 | proguard/ 33 | 34 | # Log Files 35 | *.log 36 | 37 | # Windows clutter 38 | Thumbs.db 39 | 40 | # Intellij IDEA (see https://intellij-support.jetbrains.com/entries/23393067) 41 | .idea/workspace.xml 42 | .idea/tasks.xml 43 | .idea/datasources.xml 44 | .idea/dataSources.ids 45 | /images/raws 46 | /images/icons 47 | /gradle.properties 48 | /.idea 49 | *.apk 50 | *.apk 51 | *.apk 52 | app/github/release/output.json 53 | app/github/release/app-github-release.apk 54 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/github/release/app-github-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/github/release/app-github-release.apk -------------------------------------------------------------------------------- /app/github/release/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":101},"path":"app-github-release.apk","properties":{"packageId":"com.timik.picbox","split":"","minSdkVersion":"17"}}] -------------------------------------------------------------------------------- /app/libs/activation.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/libs/activation.jar -------------------------------------------------------------------------------- /app/libs/additionnal.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/libs/additionnal.jar -------------------------------------------------------------------------------- /app/libs/commons-email-1.4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/libs/commons-email-1.4.jar -------------------------------------------------------------------------------- /app/libs/mail.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/libs/mail.jar -------------------------------------------------------------------------------- /app/proguard-fresco.pro: -------------------------------------------------------------------------------- 1 | # Keep our interfaces so they can be used by other ProGuard rules. 2 | # See http://sourceforge.net/p/proguard/bugs/466/ 3 | -keep,allowobfuscation @interface com.facebook.common.internal.DoNotStrip 4 | 5 | # Do not strip any method/class that is annotated with @DoNotStrip 6 | -keep @com.facebook.common.internal.DoNotStrip class * 7 | -keepclassmembers class * { 8 | @com.facebook.common.internal.DoNotStrip *; 9 | } 10 | 11 | # Keep native methods 12 | -keepclassmembers class * { 13 | native ; 14 | } 15 | 16 | -dontwarn okio.** 17 | -dontwarn com.squareup.okhttp.** 18 | -dontwarn okhttp3.** 19 | -dontwarn javax.annotation.** 20 | -dontwarn com.android.volley.toolbox.** 21 | -dontwarn com.facebook.infer.annotation.** 22 | 23 | # Works around a bug in the animated GIF module which will be fixed in 0.12.0 24 | -keep class com.facebook.imagepipeline.animated.factory.AnimatedFactoryImpl { 25 | public AnimatedFactoryImpl(com.facebook.imagepipeline.bitmaps.PlatformBitmapFactory,com.facebook.imagepipeline.core.ExecutorSupplier); 26 | } 27 | -------------------------------------------------------------------------------- /app/src/androidTest/java/ml/timik/picbox/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.assertEquals; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("ml.puredark.hviewer", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/ic_launcher-web.png -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/Category.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import ml.timik.picbox.ui.dataproviders.AbstractDataProvider; 4 | 5 | public class Category extends AbstractDataProvider.Data { 6 | public int cid; 7 | public String title, url; 8 | 9 | public Category(int cid, String title, String url) { 10 | this.cid = cid; 11 | this.title = title; 12 | this.url = url; 13 | } 14 | 15 | @Override 16 | public int getId() { 17 | return cid; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/CollectionGroup.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | 4 | import ml.timik.picbox.libraries.advrecyclerview.common.data.AbstractExpandableDataProvider; 5 | 6 | /** 7 | * Created by PureDark on 2016/9/21. 8 | */ 9 | 10 | public class CollectionGroup extends AbstractExpandableDataProvider.GroupData { 11 | public int gid, index; 12 | public String title; 13 | 14 | public CollectionGroup(int gid, String title) { 15 | this.gid = gid; 16 | this.title = title; 17 | } 18 | 19 | @Override 20 | public boolean isSectionHeader() { 21 | return false; 22 | } 23 | 24 | @Override 25 | public int getId() { 26 | return gid; 27 | } 28 | 29 | @Override 30 | public long getGroupId() { 31 | return gid; 32 | } 33 | 34 | @Override 35 | public String getText() { 36 | return title; 37 | } 38 | 39 | @Override 40 | public String toString(){ 41 | return "gid="+gid+" title="+title; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/Comment.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import ml.timik.picbox.ui.dataproviders.AbstractDataProvider; 4 | 5 | 6 | public class Comment extends AbstractDataProvider.Data { 7 | public int cid; 8 | public String avatar, author, datetime, content; 9 | public String referer; 10 | 11 | public Comment(int cid, String avatar, String author, String datetime, String content, String referer) { 12 | this.cid = cid; 13 | this.avatar = avatar; 14 | this.author = author; 15 | this.datetime = datetime; 16 | this.content = content; 17 | this.referer = referer; 18 | } 19 | 20 | @Override 21 | public int getId() { 22 | return cid; 23 | } 24 | 25 | @Override 26 | public boolean equals(Object obj) { 27 | if ((obj instanceof Comment)) { 28 | Comment item = (Comment) obj; 29 | return equals(item.author, author) && 30 | equals(item.datetime, datetime); 31 | } 32 | return false; 33 | } 34 | 35 | public boolean equals(Object obj1, Object obj2) { 36 | if (obj1 == obj2) { 37 | return true; 38 | } 39 | if (obj1 == null || obj2 == null) { 40 | return false; 41 | } 42 | return obj1.equals(obj2); 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/CommentRule.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * Created by PureDark on 2016/10/11. 7 | */ 8 | 9 | public class CommentRule extends SubRule { 10 | public Selector item, avatar, author, datetime, content; 11 | 12 | public boolean isEmpty() { 13 | boolean notEmpty = false; 14 | Field[] fs = getClass().getDeclaredFields(); 15 | try { 16 | for (Field f : fs) { 17 | f.setAccessible(true); 18 | Object value = f.get(this); 19 | notEmpty |= (value != null); 20 | } 21 | } catch (IllegalAccessException e) { 22 | e.printStackTrace(); 23 | } 24 | return !notEmpty; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/DownloadItemStatus.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | /** 4 | * Created by PureDark on 2017/3/4. 5 | */ 6 | 7 | public class DownloadItemStatus { 8 | public final static int STATUS_WAITING = 1; 9 | public final static int STATUS_DOWNLOADING = 2; 10 | public final static int STATUS_DOWNLOADED = 3; 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/LocalCollection.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | public class LocalCollection extends Collection { 4 | public Site site; 5 | public int index = 0; 6 | public int gid = 0; 7 | 8 | public LocalCollection(Collection collection, Site site) { 9 | super(collection.cid, collection.idCode, collection.title, collection.uploader, collection.cover, collection.category, 10 | collection.datetime, collection.description, collection.rating, collection.referer, collection.tags, 11 | collection.pictures, collection.videos, collection.comments, collection.preloaded); 12 | this.site = site; 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/MarketSiteCategory.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.util.List; 4 | 5 | import ml.timik.picbox.ui.dataproviders.AbstractDataProvider; 6 | 7 | /** 8 | * Created by PureDark on 2016/9/27. 9 | */ 10 | 11 | public class MarketSiteCategory { 12 | public int cid; 13 | public String title, english; 14 | public boolean r18; 15 | public List sites; 16 | 17 | public static boolean equals(Object obj1, Object obj2) { 18 | if (obj1 == obj2) { 19 | return true; 20 | } 21 | if (obj1 == null || obj2 == null) { 22 | return false; 23 | } 24 | return obj1.equals(obj2); 25 | } 26 | 27 | @Override 28 | public boolean equals(Object obj) { 29 | if ((obj instanceof MarketSiteCategory)) { 30 | MarketSiteCategory item = (MarketSiteCategory) obj; 31 | return equals(item.title, title); 32 | } 33 | return false; 34 | } 35 | 36 | @Override 37 | public int hashCode() { 38 | int ret = String.valueOf(title).hashCode(); 39 | return ret; 40 | } 41 | 42 | public static class MarketSite extends AbstractDataProvider.Data { 43 | public int sid; 44 | public String title, author, icon, description, json; 45 | public int versionCode; 46 | public String lastUpdate; 47 | public boolean r18; 48 | 49 | @Override 50 | public int getId() { 51 | return sid; 52 | } 53 | 54 | @Override 55 | public boolean equals(Object obj) { 56 | if ((obj instanceof MarketSite)) { 57 | MarketSite item = (MarketSite) obj; 58 | return MarketSiteCategory.equals(item.title, title) 59 | && MarketSiteCategory.equals(item.author, author); 60 | } 61 | return false; 62 | } 63 | } 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/MarketSource.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | /** 4 | * Created by PureDark on 2017/8/7. 5 | */ 6 | 7 | public class MarketSource { 8 | public int msid; 9 | public String name, jsonUrl; 10 | 11 | public MarketSource(int msid, String name, String jsonUrl){ 12 | this.msid = msid; 13 | this.name = name; 14 | this.jsonUrl = jsonUrl; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/Picture.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import ml.timik.picbox.ui.dataproviders.AbstractDataProvider; 4 | 5 | import static ml.timik.picbox.beans.DownloadItemStatus.STATUS_WAITING; 6 | 7 | public class Picture extends AbstractDataProvider.Data { 8 | public int pid; 9 | public String thumbnail, url, pic, highRes; 10 | public int retries; 11 | public int status = STATUS_WAITING; 12 | public String referer; 13 | public boolean loadedHighRes; 14 | 15 | public Picture(int pid, String url, String thumbnail, String highRes, String referer) { 16 | this.pid = pid; 17 | this.url = url; 18 | this.thumbnail = thumbnail; 19 | this.highRes = highRes; 20 | this.referer = referer; 21 | } 22 | 23 | public static boolean hasPicPosfix(String url) { 24 | return url != null && (url.endsWith(".jpg") || url.endsWith(".png") || url.endsWith(".bmp") || url.endsWith(".gif") || url.endsWith(".webp")); 25 | } 26 | 27 | @Override 28 | public int getId() { 29 | return pid; 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | if ((obj instanceof Picture)) { 35 | Picture item = (Picture) obj; 36 | return equals(item.thumbnail, thumbnail) && equals(item.url, url); 37 | } 38 | return false; 39 | } 40 | 41 | public boolean equals(Object obj1, Object obj2) { 42 | if (obj1 == obj2) { 43 | return true; 44 | } 45 | if (obj1 == null || obj2 == null) { 46 | return false; 47 | } 48 | return obj1.equals(obj2); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/PictureRule.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * Created by PureDark on 2016/10/11. 7 | */ 8 | 9 | public class PictureRule extends SubRule { 10 | public Selector id, item, thumbnail, url, highRes; 11 | 12 | public boolean isEmpty() { 13 | boolean notEmpty = false; 14 | Field[] fs = getClass().getDeclaredFields(); 15 | try { 16 | for (Field f : fs) { 17 | f.setAccessible(true); 18 | Object value = f.get(this); 19 | notEmpty |= (value != null); 20 | } 21 | } catch (IllegalAccessException e) { 22 | e.printStackTrace(); 23 | } 24 | return !notEmpty; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/Selector.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | public class Selector { 6 | public String selector, path, fun, param, regex, replacement; 7 | 8 | public Selector() { 9 | } 10 | 11 | ; 12 | 13 | public Selector(String selector, String fun, String param, String regex, String replacement) { 14 | this.selector = selector; 15 | this.fun = fun; 16 | this.param = param; 17 | this.regex = regex; 18 | this.replacement = replacement; 19 | } 20 | 21 | public Selector(String path, String fun, String param, String regex, String replacement, boolean isJson) { 22 | if (isJson) 23 | this.path = path; 24 | else 25 | this.selector = path; 26 | this.fun = fun; 27 | this.param = param; 28 | this.regex = regex; 29 | this.replacement = replacement; 30 | } 31 | 32 | @Override 33 | public String toString() { 34 | return "selector=" + selector + "\n" + 35 | "path=" + path + "\n" + 36 | "fun=" + fun + "\n" + 37 | "param=" + param + "\n" + 38 | "regex=" + regex + "\n" + 39 | "replacement=" + replacement + "\n"; 40 | } 41 | 42 | public void replace(Selector selector) { 43 | if (selector == null) 44 | return; 45 | Field[] fs = Selector.class.getDeclaredFields(); 46 | try { 47 | for (Field f : fs) { 48 | f.setAccessible(true); 49 | if ("path".equals(f.getName())) { 50 | String newPath = (String) f.get(selector); 51 | if (newPath != null) 52 | f.set(this, newPath); 53 | } else 54 | f.set(this, f.get(selector)); 55 | } 56 | } catch (IllegalAccessException e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/SiteGroup.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | 4 | import ml.timik.picbox.libraries.advrecyclerview.common.data.AbstractExpandableDataProvider; 5 | 6 | /** 7 | * Created by PureDark on 2016/9/21. 8 | */ 9 | 10 | public class SiteGroup extends AbstractExpandableDataProvider.GroupData { 11 | public int gid, index; 12 | public String title; 13 | 14 | public SiteGroup(int gid, String title) { 15 | this.gid = gid; 16 | this.title = title; 17 | } 18 | 19 | @Override 20 | public boolean isSectionHeader() { 21 | return false; 22 | } 23 | 24 | @Override 25 | public int getId() { 26 | return gid; 27 | } 28 | 29 | @Override 30 | public long getGroupId() { 31 | return gid; 32 | } 33 | 34 | @Override 35 | public String getText() { 36 | return title; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/SubRule.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * Created by PureDark on 2016/10/31. 7 | */ 8 | 9 | public class SubRule { 10 | 11 | public void replace(SubRule rule) { 12 | if (rule == null) 13 | return; 14 | Field[] fs = getClass().getDeclaredFields(); 15 | try { 16 | for (Field f : fs) { 17 | f.setAccessible(true); 18 | if (f.getType() == Selector.class) { 19 | Selector newProp = (Selector) f.get(rule); 20 | f.set(this, newProp); 21 | } 22 | } 23 | } catch (IllegalAccessException e) { 24 | e.printStackTrace(); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/Tag.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.io.Serializable; 4 | 5 | import ml.timik.picbox.ui.dataproviders.AbstractDataProvider; 6 | 7 | public class Tag extends AbstractDataProvider.Data implements Serializable { 8 | public int tid; 9 | public String title = ""; 10 | public String url; 11 | public boolean selected = false; 12 | 13 | public Tag(int tid, String title) { 14 | this.tid = tid; 15 | this.title = title; 16 | } 17 | 18 | public Tag(int tid, String title, String url) { 19 | this.tid = tid; 20 | this.title = title; 21 | this.url = url; 22 | } 23 | 24 | @Override 25 | public int getId() { 26 | return tid; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/TagRule.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * Created by PureDark on 2016/10/11. 7 | */ 8 | 9 | public class TagRule extends SubRule { 10 | public Selector item, title, url; 11 | 12 | public boolean isEmpty() { 13 | boolean notEmpty = false; 14 | Field[] fs = getClass().getDeclaredFields(); 15 | try { 16 | for (Field f : fs) { 17 | f.setAccessible(true); 18 | Object value = f.get(this); 19 | notEmpty |= (value != null); 20 | } 21 | } catch (IllegalAccessException e) { 22 | e.printStackTrace(); 23 | } 24 | return !notEmpty; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/Video.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import ml.timik.picbox.ui.dataproviders.AbstractDataProvider; 4 | 5 | import static ml.timik.picbox.beans.DownloadItemStatus.STATUS_WAITING; 6 | 7 | public class Video extends AbstractDataProvider.Data { 8 | public int vid; 9 | public String thumbnail, content; 10 | public String vlink; 11 | public int status = STATUS_WAITING; 12 | public int percent = 0; 13 | public int retries; 14 | 15 | public Video(int vid, String thumbnail, String content) { 16 | this.vid = vid; 17 | this.thumbnail = thumbnail; 18 | this.content = content; 19 | } 20 | 21 | @Override 22 | public int getId() { 23 | return vid; 24 | } 25 | 26 | @Override 27 | public boolean equals(Object obj) { 28 | if ((obj instanceof Video)) { 29 | Video item = (Video) obj; 30 | return equals(item.thumbnail, thumbnail) && equals(item.content, content); 31 | } 32 | return false; 33 | } 34 | 35 | public boolean equals(Object obj1, Object obj2) { 36 | if (obj1 == obj2) { 37 | return true; 38 | } 39 | if (obj1 == null || obj2 == null) { 40 | return false; 41 | } 42 | return obj1.equals(obj2); 43 | } 44 | 45 | @Override 46 | public String toString() { 47 | return "vid=" + vid + "\n" + 48 | "thumbnail=" + thumbnail + "\n" + 49 | "content=" + content + "\n"; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/beans/VideoRule.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.beans; 2 | 3 | import java.lang.reflect.Field; 4 | 5 | /** 6 | * Created by PureDark on 2016/10/11. 7 | */ 8 | 9 | public class VideoRule extends SubRule { 10 | public Selector id, item, thumbnail, content; 11 | 12 | public boolean isEmpty() { 13 | boolean notEmpty = false; 14 | Field[] fs = getClass().getDeclaredFields(); 15 | try { 16 | for (Field f : fs) { 17 | f.setAccessible(true); 18 | Object value = f.get(this); 19 | notEmpty |= (value != null); 20 | } 21 | } catch (IllegalAccessException e) { 22 | e.printStackTrace(); 23 | } 24 | return !notEmpty; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/configs/Names.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.configs; 2 | 3 | /** 4 | * Created by GKF on 2016/12/20. 5 | */ 6 | 7 | public class Names { 8 | public static final String appdirname = "Picbox"; 9 | public static final String backupdirname = "Backup"; 10 | public static final String sitename = "Sites.json"; 11 | public static final String settingname = "Setting.json"; 12 | public static final String favouritesname = "Favourites.json"; 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/configs/PasteEEConfig.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.configs; 2 | 3 | /** 4 | * Created by PureDark on 2016/9/27. 5 | */ 6 | 7 | public class PasteEEConfig { 8 | public final static String apiUrl = "https://paste.ee/api"; 9 | public final static String appkey = "37cce657eb1503f34ccf7a50bbe03444"; 10 | } 11 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/dataholders/AbstractTagHolder.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.dataholders; 2 | 3 | import java.util.List; 4 | 5 | import ml.timik.picbox.beans.Tag; 6 | 7 | /** 8 | * Created by PureDark on 2016/10/12. 9 | */ 10 | 11 | public abstract class AbstractTagHolder { 12 | 13 | public abstract void addTag(int sid, Tag item); 14 | 15 | public abstract void clear(int sid); 16 | 17 | public abstract void deleteTag(int sid, Tag item); 18 | 19 | public abstract List getTags(int sid); 20 | 21 | public abstract boolean tagExist(int sid, Tag item); 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/helpers/Logger.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.helpers; 2 | 3 | import android.util.Log; 4 | 5 | import ml.timik.picbox.picboxApplication; 6 | 7 | /** 8 | * Created by PureDark on 2016/9/24. 9 | */ 10 | 11 | public class Logger { 12 | 13 | public static void d(String tag, String message) { 14 | if (picboxApplication.DEBUG) 15 | Log.d(tag, message); 16 | } 17 | 18 | public static void e(String tag, String message, Throwable e) { 19 | if (picboxApplication.DEBUG) 20 | Log.e(tag, message, e); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/http/HRequestBuilder.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.http; 2 | 3 | import java.net.URLEncoder; 4 | 5 | import ml.timik.picbox.picboxApplication; 6 | import ml.timik.picbox.R; 7 | import okhttp3.Request; 8 | 9 | public class HRequestBuilder extends Request.Builder { 10 | private boolean disableHProxy = false; 11 | 12 | public HRequestBuilder() { 13 | super(); 14 | } 15 | 16 | public HRequestBuilder(boolean disableHProxy) { 17 | super(); 18 | this.disableHProxy = disableHProxy; 19 | this.header("User-Agent", picboxApplication.mContext.getResources().getString(R.string.UA)); 20 | } 21 | 22 | @Override 23 | public HRequestBuilder url(String url) { 24 | if (!disableHProxy && HProxy.isEnabled() && HProxy.isAllowRequest()) { 25 | HProxy proxy = new HProxy(url); 26 | this.header(proxy.getHeaderKey(), URLEncoder.encode(proxy.getHeaderValue())); 27 | super.url(proxy.getProxyUrl()); 28 | } else { 29 | super.url(url); 30 | } 31 | 32 | return this; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/http/HttpDns.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.http; 2 | 3 | import com.sina.util.dnscache.DNSCache; 4 | import com.sina.util.dnscache.DomainInfo; 5 | import com.sina.util.dnscache.Tools; 6 | 7 | import java.net.InetAddress; 8 | import java.net.UnknownHostException; 9 | import java.util.Arrays; 10 | import java.util.List; 11 | 12 | import okhttp3.Dns; 13 | 14 | /** 15 | * Created by PureDark on 2016/9/22. 16 | */ 17 | 18 | public class HttpDns implements Dns { 19 | 20 | @Override 21 | public List lookup(String hostname) throws UnknownHostException { 22 | DomainInfo[] infoList = DNSCache.getInstance().getDomainServerIp(hostname); 23 | if (infoList != null) { 24 | DomainInfo domainModel = infoList[0]; 25 | String ip = Tools.getHostName(domainModel.url); 26 | if (Tools.isIPV4(ip)) { 27 | List inetAddresses; 28 | try { 29 | inetAddresses = Arrays.asList(InetAddress.getAllByName(ip)); 30 | return inetAddresses; 31 | } catch (UnknownHostException e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | } 36 | return Dns.SYSTEM.lookup(hostname); 37 | } 38 | } -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/http/ImageSizeInputStreamProvider.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.http; 2 | 3 | import android.text.TextUtils; 4 | 5 | import java.io.File; 6 | import java.io.FileInputStream; 7 | import java.io.InputStream; 8 | import java.net.URL; 9 | import java.net.URLConnection; 10 | 11 | import q.rorbin.fastimagesize.net.InputStreamProvider; 12 | 13 | /** 14 | * Created by PureDark on 2017/3/14. 15 | */ 16 | 17 | public class ImageSizeInputStreamProvider implements InputStreamProvider { 18 | private String referer, cookie; 19 | 20 | public ImageSizeInputStreamProvider(String referer, String cookie) { 21 | this.referer = referer; 22 | this.cookie = cookie; 23 | } 24 | 25 | @Override 26 | public InputStream getInputStream(String imagePath) { 27 | InputStream stream = null; 28 | try { 29 | if (imagePath.startsWith("http")) { 30 | URLConnection connection = new URL(imagePath).openConnection(); 31 | connection.setConnectTimeout(1000); 32 | connection.setReadTimeout(1000); 33 | if (!TextUtils.isEmpty(referer)) 34 | connection.setRequestProperty("Referer", referer); 35 | if (!TextUtils.isEmpty(cookie)) 36 | connection.setRequestProperty("Cookie", cookie); 37 | connection.connect(); 38 | stream = connection.getInputStream(); 39 | } else { 40 | File file = new File(imagePath); 41 | if (file.exists()) { 42 | stream = new FileInputStream(file); 43 | } 44 | } 45 | } catch (Exception e) { 46 | e.printStackTrace(); 47 | return stream; 48 | } 49 | return stream; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/libraries/advrecyclerview/common/widget/ExpandableItemIndicatorImplNoAnim.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Haruki Hasegawa 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ml.timik.picbox.libraries.advrecyclerview.common.widget; 18 | 19 | import android.content.Context; 20 | import android.support.annotation.DrawableRes; 21 | import android.util.AttributeSet; 22 | import android.view.LayoutInflater; 23 | import android.view.View; 24 | import android.widget.ImageView; 25 | 26 | import ml.timik.picbox.R; 27 | 28 | class ExpandableItemIndicatorImplNoAnim extends ExpandableItemIndicator.Impl { 29 | private ImageView mImageView; 30 | 31 | @Override 32 | public void onInit(Context context, AttributeSet attrs, int defStyleAttr, ExpandableItemIndicator thiz) { 33 | View v = LayoutInflater.from(context).inflate(R.layout.widget_expandable_item_indicator, thiz, true); 34 | mImageView = (ImageView) v.findViewById(R.id.image_view); 35 | } 36 | 37 | @Override 38 | public void setExpandedState(boolean isExpanded, boolean animate) { 39 | @DrawableRes int resId = (isExpanded) ? R.drawable.ic_expand_less : R.drawable.ic_expand_more; 40 | mImageView.setImageResource(resId); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/libraries/swipeback/common/SwipeBackApplication.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.libraries.swipeback.common; 2 | 3 | import android.app.Application; 4 | 5 | /** 6 | * Created by fhf11991 on 2016/7/18. 7 | */ 8 | 9 | public class SwipeBackApplication extends Application { 10 | 11 | private ActivityLifecycleHelper mActivityLifecycleHelper; 12 | 13 | @Override 14 | public void onCreate() { 15 | super.onCreate(); 16 | registerActivityLifecycleCallbacks(mActivityLifecycleHelper = new ActivityLifecycleHelper()); 17 | } 18 | 19 | public ActivityLifecycleHelper getActivityLifecycleHelper() { 20 | return mActivityLifecycleHelper; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/libraries/swipeback/dispatchactivity/SwipeBackActivity.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.libraries.swipeback.dispatchactivity; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.view.MotionEvent; 5 | 6 | 7 | /** 8 | * Created by fhf11991 on 2016/7/25. 9 | */ 10 | public class SwipeBackActivity extends AppCompatActivity { 11 | private static final String TAG = "SwipeBackActivity"; 12 | private boolean swipeEnable = true; 13 | 14 | private SwipeWindowHelper mSwipeWindowHelper; 15 | 16 | @Override 17 | public boolean dispatchTouchEvent(MotionEvent ev) { 18 | if (!supportSlideBack()) { 19 | return super.dispatchTouchEvent(ev); 20 | } 21 | 22 | if (mSwipeWindowHelper == null) { 23 | mSwipeWindowHelper = new SwipeWindowHelper(getWindow()); 24 | } 25 | return mSwipeWindowHelper.processTouchEvent(ev) || super.dispatchTouchEvent(ev); 26 | } 27 | 28 | /** 29 | * 是否支持滑动返回 30 | * 31 | * @return 32 | */ 33 | protected boolean supportSlideBack() { 34 | return swipeEnable; 35 | } 36 | 37 | public void setSwipeBackEnable(boolean enable) { 38 | swipeEnable = enable; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/libraries/swipeback/dispatchactivity/SwipeDialog.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.libraries.swipeback.dispatchactivity; 2 | 3 | import android.app.Dialog; 4 | import android.content.Context; 5 | import android.view.MotionEvent; 6 | 7 | /** 8 | * Created by fhf11991 on 2016/9/18. 9 | */ 10 | 11 | public class SwipeDialog extends Dialog { 12 | 13 | private SwipeWindowHelper mSwipeWindowHelper; 14 | 15 | public SwipeDialog(Context context) { 16 | super(context); 17 | } 18 | 19 | public SwipeDialog(Context context, int themeResId) { 20 | super(context, themeResId); 21 | } 22 | 23 | 24 | @Override 25 | public boolean dispatchTouchEvent(MotionEvent ev) { 26 | if (mSwipeWindowHelper == null) { 27 | mSwipeWindowHelper = new SwipeWindowHelper(getWindow()); 28 | } 29 | return mSwipeWindowHelper.processTouchEvent(ev) || super.dispatchTouchEvent(ev); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/activities/LicenseActivity.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.activities; 2 | 3 | import android.os.Bundle; 4 | import android.support.design.widget.AppBarLayout; 5 | import android.support.design.widget.CoordinatorLayout; 6 | import android.support.v7.widget.Toolbar; 7 | import android.widget.ImageView; 8 | import android.widget.TextView; 9 | 10 | import java.io.IOException; 11 | 12 | import butterknife.BindView; 13 | import butterknife.ButterKnife; 14 | import butterknife.OnClick; 15 | import ml.timik.picbox.R; 16 | import ml.timik.picbox.helpers.MDStatusBarCompat; 17 | import ml.timik.picbox.utils.SimpleFileUtil; 18 | 19 | public class LicenseActivity extends BaseActivity { 20 | 21 | @BindView(R.id.coordinator_layout) 22 | CoordinatorLayout coordinatorLayout; 23 | @BindView(R.id.app_bar) 24 | AppBarLayout appbar; 25 | @BindView(R.id.toolbar) 26 | Toolbar toolbar; 27 | @BindView(R.id.btn_return) 28 | ImageView btnReturn; 29 | @BindView(R.id.tv_title) 30 | TextView tvTitle; 31 | @BindView(R.id.tv_license) 32 | TextView tvLicense; 33 | 34 | @Override 35 | protected void onCreate(Bundle savedInstanceState) { 36 | super.onCreate(savedInstanceState); 37 | setContentView(R.layout.activity_text); 38 | ButterKnife.bind(this); 39 | MDStatusBarCompat.setSwipeBackToolBar(this, coordinatorLayout, appbar, toolbar); 40 | 41 | setSupportActionBar(toolbar); 42 | getSupportActionBar().setDisplayShowTitleEnabled(false); 43 | 44 | setContainer(coordinatorLayout); 45 | /* 为返回按钮加载图标 */ 46 | setReturnButton(btnReturn); 47 | 48 | tvTitle.setText("开源协议"); 49 | 50 | String license; 51 | try { 52 | license = SimpleFileUtil.getFromAssets(this, "License.txt"); 53 | } catch (IOException e) { 54 | e.printStackTrace(); 55 | license = "获取失败"; 56 | } 57 | 58 | tvLicense.setText(license); 59 | } 60 | 61 | @OnClick(R.id.btn_return) 62 | void back() { 63 | onBackPressed(); 64 | } 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/activities/MyCaptureActivity.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.activities; 2 | 3 | import android.Manifest; 4 | import android.content.pm.PackageManager; 5 | import android.os.Bundle; 6 | import android.support.v4.app.ActivityCompat; 7 | import android.support.v4.content.ContextCompat; 8 | import android.widget.Toast; 9 | 10 | import com.journeyapps.barcodescanner.CaptureActivity; 11 | 12 | public class MyCaptureActivity extends CaptureActivity { 13 | 14 | @Override 15 | public void onCreate(Bundle savedInstanceState) { 16 | super.onCreate(savedInstanceState); 17 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) 18 | != PackageManager.PERMISSION_GRANTED) { 19 | ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.CAMERA}, 1); 20 | } 21 | } 22 | 23 | @Override 24 | public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { 25 | super.onRequestPermissionsResult(requestCode, permissions, grantResults); 26 | doNext(requestCode, grantResults); 27 | } 28 | 29 | private void doNext(int requestCode, int[] grantResults) { 30 | if (requestCode == 1) { 31 | if (grantResults[0] == PackageManager.PERMISSION_GRANTED) { 32 | // Permission Granted 33 | } else { 34 | // Permission Denied 35 | Toast.makeText(this, "请在应用管理中打开“相机”访问权限!", Toast.LENGTH_LONG).show(); 36 | finish(); 37 | } 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/activities/SetPatternActivity.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Zhang Hai 3 | * All Rights Reserved. 4 | */ 5 | 6 | package ml.timik.picbox.ui.activities; 7 | 8 | import android.os.Bundle; 9 | import android.view.MenuItem; 10 | 11 | import java.util.List; 12 | 13 | import me.zhanghai.android.patternlock.PatternView; 14 | import ml.timik.picbox.helpers.MDStatusBarCompat; 15 | import ml.timik.picbox.ui.fragments.LockMethodFragment; 16 | import ml.timik.picbox.utils.AppUtils; 17 | import ml.timik.picbox.utils.PatternLockUtils; 18 | import ml.timik.picbox.utils.SharedPreferencesUtil; 19 | 20 | public class SetPatternActivity extends me.zhanghai.android.patternlock.SetPatternActivity { 21 | 22 | @Override 23 | protected void onCreate(Bundle savedInstanceState) { 24 | super.onCreate(savedInstanceState); 25 | AppUtils.setActionBarDisplayUp(this); 26 | MDStatusBarCompat.setOrdinaryToolBar(this); 27 | setTitle("解锁图案"); 28 | } 29 | 30 | @Override 31 | public boolean onOptionsItemSelected(MenuItem item) { 32 | switch (item.getItemId()) { 33 | case android.R.id.home: 34 | AppUtils.navigateUp(this); 35 | return true; 36 | default: 37 | return super.onOptionsItemSelected(item); 38 | } 39 | } 40 | 41 | @Override 42 | protected void onSetPattern(List pattern) { 43 | PatternLockUtils.setPattern(this, pattern); 44 | SharedPreferencesUtil.saveData(this, LockMethodFragment.KEY_PREF_CURR_LOCK_METHOD, "pattern"); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/adapters/ViewPagerAdapter.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.adapters; 2 | 3 | import android.support.v4.view.PagerAdapter; 4 | import android.view.View; 5 | import android.view.ViewGroup; 6 | 7 | import java.util.List; 8 | 9 | public class ViewPagerAdapter extends PagerAdapter { 10 | List viewLists; 11 | List titles; 12 | 13 | public ViewPagerAdapter(List lists, List titles) { 14 | viewLists = lists; 15 | this.titles = titles; 16 | } 17 | 18 | @Override 19 | public int getCount() { 20 | return viewLists.size(); 21 | } 22 | 23 | @Override 24 | public boolean isViewFromObject(View view, Object object) { 25 | return view == object; 26 | } 27 | 28 | @Override 29 | public void destroyItem(ViewGroup container, int position, Object object) { 30 | if (viewLists.get(position) != null) { 31 | container.removeView(viewLists.get(position)); 32 | } 33 | } 34 | 35 | @Override 36 | public Object instantiateItem(ViewGroup container, int position) { 37 | if (position > container.getChildCount()) 38 | return viewLists.get(position); 39 | container.addView(viewLists.get(position), position); 40 | return viewLists.get(position); 41 | } 42 | 43 | @Override 44 | public CharSequence getPageTitle(int position) { 45 | return titles.get(position); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/AnimationOnActivity.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.support.v7.graphics.drawable.DrawerArrowDrawable; 4 | 5 | import com.nineoldandroids.animation.Animator; 6 | import com.nineoldandroids.animation.ValueAnimator; 7 | 8 | /** 9 | * Created by PureDark on 2016/8/12. 10 | */ 11 | 12 | public class AnimationOnActivity { 13 | 14 | public static void start(DrawerArrowDrawable btnReturnIcon, Animator.AnimatorListener listener) { 15 | ValueAnimator arrow = getArrowAnimator(btnReturnIcon); 16 | arrow.addListener(listener); 17 | arrow.start(); 18 | } 19 | 20 | public static void reverse(DrawerArrowDrawable btnReturnIcon, Animator.AnimatorListener listener) { 21 | ValueAnimator arrow = getArrowAnimator(btnReturnIcon); 22 | arrow.addListener(listener); 23 | arrow.reverse(); 24 | } 25 | 26 | static ValueAnimator getArrowAnimator(final DrawerArrowDrawable btnReturnIcon) { 27 | float start = 0f; 28 | float end = 1f; 29 | ValueAnimator animator = ValueAnimator.ofFloat(start, end); 30 | animator.setDuration(300); 31 | animator.addUpdateListener(animation -> btnReturnIcon.setProgress((Float) animation.getAnimatedValue())); 32 | return animator; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/MultiTouchViewPager.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.content.Context; 4 | import android.support.annotation.NonNull; 5 | import android.support.v4.view.ViewPager; 6 | import android.util.AttributeSet; 7 | import android.view.MotionEvent; 8 | 9 | public class MultiTouchViewPager extends ViewPager { 10 | 11 | private boolean mIsDisallowIntercept = false; 12 | 13 | public MultiTouchViewPager(Context context) { 14 | super(context); 15 | } 16 | 17 | public MultiTouchViewPager(Context context, AttributeSet attrs) { 18 | super(context, attrs); 19 | } 20 | 21 | @Override 22 | public void requestDisallowInterceptTouchEvent(boolean disallowIntercept) { 23 | mIsDisallowIntercept = disallowIntercept; 24 | super.requestDisallowInterceptTouchEvent(disallowIntercept); 25 | } 26 | 27 | @Override 28 | public boolean dispatchTouchEvent(@NonNull MotionEvent ev) { 29 | if (ev.getPointerCount() > 1 && mIsDisallowIntercept) { 30 | requestDisallowInterceptTouchEvent(false); 31 | boolean handled = super.dispatchTouchEvent(ev); 32 | requestDisallowInterceptTouchEvent(true); 33 | return handled; 34 | } else { 35 | return super.dispatchTouchEvent(ev); 36 | } 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/ScalingImageView.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.content.Context; 4 | import android.graphics.drawable.Drawable; 5 | import android.util.AttributeSet; 6 | 7 | /** 8 | * An ImageView which works as if adjustViewBounds=true and 9 | * only changes the height. 10 | *

11 | * Usage example: 12 | *

<com.triposo.barone.ScalingImageView
13 |  *   android:layout_width="match_parent"
14 |  *   android:layout_height="0px"
15 |  *   />
16 |  * 
17 | */ 18 | public class ScalingImageView extends android.support.v7.widget.AppCompatImageView { 19 | 20 | public ScalingImageView(Context context) { 21 | super(context); 22 | } 23 | 24 | public ScalingImageView(Context context, AttributeSet attrs) { 25 | super(context, attrs); 26 | } 27 | 28 | public ScalingImageView(Context context, AttributeSet attrs, int defStyle) { 29 | super(context, attrs, defStyle); 30 | } 31 | 32 | protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { 33 | Drawable mDrawable = getDrawable(); 34 | if (mDrawable != null) { 35 | int mDrawableWidth = mDrawable.getIntrinsicWidth(); 36 | int mDrawableHeight = mDrawable.getIntrinsicHeight(); 37 | float actualAspect = (float) mDrawableWidth / (float) mDrawableHeight; 38 | 39 | // Assuming the width is ok, so we calculate the height. 40 | final int actualWidth = MeasureSpec.getSize(widthMeasureSpec); 41 | final int height = (int) (actualWidth / actualAspect); 42 | heightMeasureSpec = MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY); 43 | } 44 | super.onMeasure(widthMeasureSpec, heightMeasureSpec); 45 | } 46 | } -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/WrappedGridLayoutManager.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.GridLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.Log; 7 | 8 | /** 9 | * Created by PureDark on 2016/10/29. 10 | */ 11 | 12 | public class WrappedGridLayoutManager extends GridLayoutManager { 13 | 14 | public WrappedGridLayoutManager(Context context, int spanCount) { 15 | super(context, spanCount); 16 | } 17 | 18 | @Override 19 | public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 20 | try { 21 | super.onLayoutChildren(recycler, state); 22 | } catch (IndexOutOfBoundsException e) { 23 | Log.e("probe", "meet a IOOBE in RecyclerView"); 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/WrappedLinearLayoutManager.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.LinearLayoutManager; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.util.AttributeSet; 7 | import android.util.Log; 8 | 9 | public class WrappedLinearLayoutManager extends LinearLayoutManager { 10 | public WrappedLinearLayoutManager(Context context) { 11 | super(context); 12 | } 13 | 14 | public WrappedLinearLayoutManager(Context context, int orientation, boolean reverseLayout) { 15 | super(context, orientation, reverseLayout); 16 | } 17 | 18 | public WrappedLinearLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 19 | super(context, attrs, defStyleAttr, defStyleRes); 20 | } 21 | 22 | @Override 23 | public boolean supportsPredictiveItemAnimations() { 24 | return false; 25 | } 26 | 27 | @Override 28 | public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 29 | //override this method and implement code as below 30 | try { 31 | super.onLayoutChildren(recycler, state); 32 | } catch (IndexOutOfBoundsException e) { 33 | Log.e("probe", "meet a IOOBE in RecyclerView"); 34 | } 35 | } 36 | } -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/WrappedPullLoadMoreRecyclerView.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.content.Context; 4 | import android.util.AttributeSet; 5 | 6 | import com.wuxiaolong.pullloadmorerecyclerview.PullLoadMoreRecyclerView; 7 | 8 | /** 9 | * Created by PureDark on 2016/9/29. 10 | */ 11 | 12 | public class WrappedPullLoadMoreRecyclerView extends PullLoadMoreRecyclerView { 13 | 14 | public WrappedPullLoadMoreRecyclerView(Context context) { 15 | super(context); 16 | } 17 | 18 | public WrappedPullLoadMoreRecyclerView(Context context, AttributeSet attrs) { 19 | super(context, attrs); 20 | super.getRecyclerView().setOnTouchListener(null); 21 | } 22 | 23 | // 重写以支持SwipeBack 24 | @Override 25 | protected void onDetachedFromWindow() { 26 | try { 27 | super.onDetachedFromWindow(); 28 | } catch (Exception e) { 29 | } 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/customs/WrappedStaggeredGridLayoutManager.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.customs; 2 | 3 | import android.content.Context; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.support.v7.widget.StaggeredGridLayoutManager; 6 | import android.util.AttributeSet; 7 | import android.util.Log; 8 | 9 | public class WrappedStaggeredGridLayoutManager extends StaggeredGridLayoutManager { 10 | 11 | public WrappedStaggeredGridLayoutManager(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) { 12 | super(context, attrs, defStyleAttr, defStyleRes); 13 | } 14 | 15 | public WrappedStaggeredGridLayoutManager(int spanCount, int orientation) { 16 | super(spanCount, orientation); 17 | } 18 | 19 | @Override 20 | public boolean supportsPredictiveItemAnimations() { 21 | return false; 22 | } 23 | 24 | @Override 25 | public int scrollVerticallyBy(int dy, RecyclerView.Recycler recycler, RecyclerView.State state) { 26 | try { 27 | return super.scrollVerticallyBy(dy, recycler, state); 28 | } catch (Exception e) { 29 | return 0; 30 | } 31 | } 32 | 33 | @Override 34 | public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) { 35 | //override this method and implement code as below 36 | try { 37 | super.onLayoutChildren(recycler, state); 38 | } catch (IndexOutOfBoundsException e) { 39 | Log.e("probe", "meet a IOOBE in RecyclerView"); 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/dataproviders/AbstractDataProvider.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.dataproviders; 2 | 3 | import java.util.Collection; 4 | 5 | public abstract class AbstractDataProvider { 6 | 7 | public abstract int getCount(); 8 | 9 | public abstract C getItems(); 10 | 11 | public abstract T getItem(int index); 12 | 13 | public abstract void removeItem(int position); 14 | 15 | public abstract void clear(); 16 | 17 | public abstract void setDataSet(C datas); 18 | 19 | public abstract void addItem(T item); 20 | 21 | public abstract void addItem(int position, T item); 22 | 23 | public abstract void addAll(Collection items); 24 | 25 | public static abstract class Data { 26 | public abstract int getId(); 27 | } 28 | } -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/dataproviders/ListDataProvider.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.dataproviders; 2 | 3 | import java.util.Collection; 4 | import java.util.List; 5 | 6 | public class ListDataProvider extends AbstractDataProvider { 7 | 8 | private List items; 9 | 10 | public ListDataProvider(List items) { 11 | this.items = items; 12 | } 13 | 14 | @Override 15 | public int getCount() { 16 | return (items == null) ? 0 : items.size(); 17 | } 18 | 19 | @Override 20 | public List getItems() { 21 | return items; 22 | } 23 | 24 | @Override 25 | public T getItem(int index) { 26 | if (index < 0 || index >= getCount()) { 27 | throw new IndexOutOfBoundsException("index = " + index); 28 | } 29 | 30 | return items.get(index); 31 | } 32 | 33 | @Override 34 | public void removeItem(int position) { 35 | items.remove(position); 36 | } 37 | 38 | @Override 39 | public void clear() { 40 | items.clear(); 41 | } 42 | 43 | @Override 44 | public void setDataSet(List datas) { 45 | items = datas; 46 | } 47 | 48 | @Override 49 | public void addItem(T item) { 50 | items.add(item); 51 | } 52 | 53 | @Override 54 | public void addItem(int position, T item) { 55 | items.add(position, item); 56 | } 57 | 58 | @Override 59 | public void addAll(Collection items) { 60 | this.items.addAll(items); 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/fragments/MyFragment.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.fragments; 2 | 3 | 4 | import android.support.v4.app.Fragment; 5 | 6 | import ml.timik.picbox.beans.Site; 7 | 8 | /** 9 | * Created by PureDark on 2015/12/9. 10 | */ 11 | public abstract class MyFragment extends Fragment { 12 | 13 | public abstract Site getCurrSite(); 14 | 15 | public abstract void onSearch(String keyword); 16 | 17 | public abstract void onLoadUrl(String url); 18 | 19 | public abstract void onJumpToPage(int page); 20 | 21 | public abstract void setRecyclerViewToList(); 22 | 23 | public abstract void setRecyclerViewToGrid(); 24 | 25 | } 26 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/fragments/ProxyFragment.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.fragments; 2 | 3 | import android.annotation.SuppressLint; 4 | import android.os.Bundle; 5 | import android.preference.Preference; 6 | import android.preference.PreferenceFragment; 7 | 8 | import ml.timik.picbox.R; 9 | import ml.timik.picbox.ui.activities.BaseActivity; 10 | import ml.timik.picbox.utils.SharedPreferencesUtil; 11 | 12 | import static ml.timik.picbox.ui.fragments.SettingFragment.KEY_PREF_PROXY_SERVER; 13 | 14 | /** 15 | * Created by PureDark on 2016/9/25. 16 | */ 17 | public class ProxyFragment extends PreferenceFragment 18 | implements Preference.OnPreferenceChangeListener { 19 | 20 | private BaseActivity activity; 21 | 22 | public ProxyFragment() { 23 | } 24 | 25 | @SuppressLint("ValidFragment") 26 | public ProxyFragment(BaseActivity activity) { 27 | this.activity = activity; 28 | } 29 | 30 | @Override 31 | public void onCreate(final Bundle savedInstanceState) { 32 | super.onCreate(savedInstanceState); 33 | getPreferenceManager().setSharedPreferencesName(SharedPreferencesUtil.FILE_NAME); 34 | addPreferencesFromResource(R.xml.proxy); 35 | 36 | String proxyServer = getPreferenceManager().getSharedPreferences().getString(KEY_PREF_PROXY_SERVER, null); 37 | if (proxyServer != null) 38 | getPreferenceManager().findPreference(KEY_PREF_PROXY_SERVER).setSummary(proxyServer); 39 | 40 | getPreferenceManager().findPreference(KEY_PREF_PROXY_SERVER).setOnPreferenceChangeListener(this); 41 | 42 | } 43 | 44 | @Override 45 | public boolean onPreferenceChange(Preference preference, Object newValue) { 46 | if (preference.getKey().equals(KEY_PREF_PROXY_SERVER)) { 47 | getPreferenceManager().findPreference(KEY_PREF_PROXY_SERVER).setSummary((String) newValue); 48 | } 49 | return true; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/listeners/AppBarStateChangeListener.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.listeners; 2 | 3 | import android.support.design.widget.AppBarLayout; 4 | 5 | /** 6 | * Created by PureDark on 2016/8/12. 7 | */ 8 | 9 | public abstract class AppBarStateChangeListener implements AppBarLayout.OnOffsetChangedListener { 10 | 11 | private State mCurrentState = State.IDLE; 12 | 13 | @Override 14 | public final void onOffsetChanged(AppBarLayout appBarLayout, int i) { 15 | if (i == 0) { 16 | if (mCurrentState != State.EXPANDED) { 17 | onStateChanged(appBarLayout, State.EXPANDED); 18 | } 19 | mCurrentState = State.EXPANDED; 20 | } else if (Math.abs(i) >= appBarLayout.getTotalScrollRange()) { 21 | if (mCurrentState != State.COLLAPSED) { 22 | onStateChanged(appBarLayout, State.COLLAPSED); 23 | } 24 | mCurrentState = State.COLLAPSED; 25 | } else { 26 | if (mCurrentState != State.IDLE) { 27 | onStateChanged(appBarLayout, State.IDLE); 28 | } 29 | mCurrentState = State.IDLE; 30 | } 31 | } 32 | 33 | public abstract void onStateChanged(AppBarLayout appBarLayout, State state); 34 | 35 | public enum State { 36 | EXPANDED, 37 | COLLAPSED, 38 | IDLE 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/listeners/OnItemLongClickListener.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.listeners; 2 | 3 | import android.view.View; 4 | 5 | /** 6 | * Created by PureDark on 2016/10/21. 7 | */ 8 | 9 | public interface OnItemLongClickListener { 10 | boolean onItemLongClick(View view, int position); 11 | } 12 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/listeners/SwipeBackOnPageChangeListener.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.listeners; 2 | 3 | import android.support.v4.view.ViewPager.OnPageChangeListener; 4 | 5 | import ml.timik.picbox.libraries.swipeback.dispatchactivity.SwipeBackActivity; 6 | 7 | /** 8 | * Created by PureDark on 2016/9/29. 9 | */ 10 | 11 | public class SwipeBackOnPageChangeListener implements OnPageChangeListener { 12 | private SwipeBackActivity mActivity; 13 | 14 | public SwipeBackOnPageChangeListener(SwipeBackActivity activity) { 15 | mActivity = activity; 16 | } 17 | 18 | @Override 19 | public void onPageScrolled(int position, float positionOffset, int positionOffsetPixels) { 20 | } 21 | 22 | @Override 23 | public void onPageSelected(int position) { 24 | if (mActivity == null) 25 | return; 26 | if (position == 0) 27 | mActivity.setSwipeBackEnable(true); 28 | else 29 | mActivity.setSwipeBackEnable(false); 30 | } 31 | 32 | @Override 33 | public void onPageScrollStateChanged(int state) { 34 | 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/ui/preferences/LockMethodPreference.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.ui.preferences; 2 | 3 | import android.content.Context; 4 | import android.preference.Preference; 5 | import android.support.v4.hardware.fingerprint.FingerprintManagerCompat; 6 | import android.text.TextUtils; 7 | import android.util.AttributeSet; 8 | 9 | import ml.timik.picbox.R; 10 | import ml.timik.picbox.ui.fragments.LockMethodFragment; 11 | 12 | /** 13 | * Created by PureDark on 2016/10/9. 14 | */ 15 | 16 | public class LockMethodPreference extends Preference { 17 | 18 | public LockMethodPreference(Context context) { 19 | super(context); 20 | } 21 | 22 | public LockMethodPreference(Context context, AttributeSet attrs, int defStyleAttr) { 23 | super(context, attrs, defStyleAttr); 24 | } 25 | 26 | public LockMethodPreference(Context context, AttributeSet attrs) { 27 | super(context, attrs); 28 | } 29 | 30 | @Override 31 | public CharSequence getSummary() { 32 | Context context = getContext(); 33 | FingerprintManagerCompat manager = FingerprintManagerCompat.from(context); 34 | boolean isFingerPrintLock = false; 35 | try { 36 | isFingerPrintLock = manager.hasEnrolledFingerprints(); 37 | } catch (Exception e){ 38 | } 39 | boolean isPatternLock = LockMethodFragment.getCurrentLockMethod(context) == LockMethodFragment.METHOD_PATTERN; 40 | boolean isPinLock = LockMethodFragment.getCurrentLockMethod(context) == LockMethodFragment.METHOD_PIN; 41 | String summary = (isPatternLock) ? "图案解锁" : (isPinLock) ? "数字解锁" : ""; 42 | if (!TextUtils.isEmpty(summary)) 43 | summary += (isFingerPrintLock) ? "、指纹" : ""; 44 | else 45 | summary = context.getString(R.string.settings_lock_methods_detail_summary); 46 | return summary; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/utils/DrawableUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Haruki Hasegawa 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ml.timik.picbox.utils; 18 | 19 | import android.graphics.drawable.Drawable; 20 | 21 | public class DrawableUtil { 22 | private static final int[] EMPTY_STATE = new int[]{}; 23 | 24 | public static void clearState(Drawable drawable) { 25 | if (drawable != null) { 26 | drawable.setState(EMPTY_STATE); 27 | } 28 | } 29 | 30 | } 31 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/utils/EmailUtil.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.utils; 2 | 3 | import android.util.Log; 4 | 5 | import org.apache.commons.mail.EmailException; 6 | import org.apache.commons.mail.HtmlEmail; 7 | 8 | import static ml.timik.picbox.picboxApplication.mContext; 9 | 10 | /** 11 | * Created by PureDark on 2016/8/26. 12 | */ 13 | 14 | public class EmailUtil { 15 | 16 | public final static String smtpHost = "smtp.qq.com"; 17 | 18 | public final static String fromEmail = "zonb@qq.com"; 19 | 20 | public final static String username = "zonb"; 21 | 22 | public final static String password = "Lm20061002!"; 23 | 24 | public static void sendEmail(String to, String title, String content) { 25 | try { 26 | sendMailByApache(to, title, content); 27 | SharedPreferencesUtil.saveData(mContext, "unupload_log", false); 28 | } catch (Exception e) { 29 | e.printStackTrace(); 30 | } 31 | } 32 | 33 | public static void sendMailByApache(String to, String title, String content) { 34 | 35 | try { 36 | HtmlEmail email = new HtmlEmail(); 37 | // 这里是发送服务器的名字 38 | email.setHostName(smtpHost); 39 | // 编码集的设置 40 | email.setTLS(true); 41 | email.setSSL(true); 42 | 43 | email.setCharset("utf-8"); 44 | // 收件人的邮箱 45 | email.addTo(to); 46 | // 发送人的邮箱 47 | email.setFrom(fromEmail); 48 | // 如果需要认证信息的话,设置认证:用户名-密码。分别为发件人在邮件服务器上的注册名称和密码 49 | email.setAuthentication(username, password); 50 | email.setSubject(title); 51 | // 要发送的信息 52 | email.setMsg(content); 53 | // 发送 54 | email.send(); 55 | } catch (EmailException e) { 56 | Log.i("EmailUtil", e.getMessage()); 57 | } 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/utils/PatternLockUtils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2015 Zhang Hai 3 | * All Rights Reserved. 4 | */ 5 | 6 | package ml.timik.picbox.utils; 7 | 8 | import android.content.Context; 9 | import android.text.TextUtils; 10 | 11 | import java.util.List; 12 | 13 | import me.zhanghai.android.patternlock.PatternUtils; 14 | import me.zhanghai.android.patternlock.PatternView; 15 | import ml.timik.picbox.ui.fragments.LockMethodFragment; 16 | 17 | public class PatternLockUtils { 18 | public static void setPattern(Context context, List pattern) { 19 | SharedPreferencesUtil.saveData(context, LockMethodFragment.KEY_PREF_PATTERN_LOCK, 20 | PatternUtils.patternToSha1String(pattern)); 21 | } 22 | 23 | private static String getPatternSha1(Context context) { 24 | return (String) SharedPreferencesUtil.getData(context, LockMethodFragment.KEY_PREF_PATTERN_LOCK, ""); 25 | } 26 | 27 | public static boolean hasPattern(Context context) { 28 | return !TextUtils.isEmpty(getPatternSha1(context)); 29 | } 30 | 31 | public static boolean isPatternCorrect(Context context, List pattern) { 32 | return TextUtils.equals(PatternUtils.patternToSha1String(pattern), getPatternSha1(context)); 33 | } 34 | 35 | public static void clearPattern(Context context) { 36 | SharedPreferencesUtil.deleteData(context, LockMethodFragment.KEY_PREF_PATTERN_LOCK); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/utils/RandomUtil.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.utils; 2 | 3 | import java.util.Random; 4 | 5 | /** 6 | * Created by PureDark on 2016/8/6. 7 | */ 8 | 9 | public class RandomUtil { 10 | public static int[] randomArray(int min, int max, int n) { 11 | int len = max - min + 1; 12 | 13 | if (max < min || n > len) { 14 | return null; 15 | } 16 | 17 | //初始化给定范围的待选数组 18 | int[] source = new int[len]; 19 | for (int i = min; i < min + len; i++) { 20 | source[i - min] = i; 21 | } 22 | 23 | int[] result = new int[n]; 24 | Random rd = new Random(); 25 | int index = 0; 26 | for (int i = 0; i < result.length; i++) { 27 | //待选数组0到(len-2)随机一个下标 28 | index = Math.abs(rd.nextInt() % len--); 29 | //将随机到的数放入结果集 30 | result[i] = source[index]; 31 | //将待选数组中被随机到的数,用待选数组(len-1)下标对应的数替换 32 | source[index] = source[len]; 33 | } 34 | return result; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/utils/VibratorUtil.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox.utils; 2 | 3 | import android.app.Service; 4 | import android.content.Context; 5 | import android.os.Vibrator; 6 | 7 | 8 | public class VibratorUtil { 9 | 10 | /** 11 | * 按一定模式震动 12 | * 13 | * @param context 上下文 14 | * @param milliseconds 震动时长,单位是毫秒 15 | */ 16 | public static void Vibrate(Context context, long milliseconds) { 17 | Vibrator vib = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE); 18 | vib.vibrate(milliseconds); 19 | } 20 | 21 | 22 | /** 23 | * 按一定模式震动 24 | * 25 | * @param context 上下文 26 | * @param pattern 自定义震动模式,数组含义:[静止时长,震动时长,静止时长,震动时长……] 单位是毫秒 27 | * @param isRepeat 是否重复震动 28 | */ 29 | public static void Vibrate(Context context, long[] pattern, boolean isRepeat) { 30 | Vibrator vib = (Vibrator) context.getSystemService(Service.VIBRATOR_SERVICE); 31 | vib.vibrate(pattern, isRepeat ? 1 : -1); 32 | } 33 | 34 | } 35 | -------------------------------------------------------------------------------- /app/src/main/java/ml/timik/picbox/utils/ViewUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (C) 2015 Haruki Hasegawa 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); 5 | * you may not use this file except in compliance with the License. 6 | * You may obtain a copy of the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, 12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | * See the License for the specific language governing permissions and 14 | * limitations under the License. 15 | */ 16 | 17 | package ml.timik.picbox.utils; 18 | 19 | import android.support.v4.view.ViewCompat; 20 | import android.view.View; 21 | 22 | import com.nineoldandroids.view.ViewHelper; 23 | 24 | public class ViewUtil { 25 | public static boolean hitTest(View v, int x, int y) { 26 | final int tx = (int) (ViewCompat.getTranslationX(v) + 0.5f); 27 | final int ty = (int) (ViewCompat.getTranslationY(v) + 0.5f); 28 | final int left = v.getLeft() + tx; 29 | final int right = v.getRight() + tx; 30 | final int top = v.getTop() + ty; 31 | final int bottom = v.getBottom() + ty; 32 | 33 | return (x >= left) && (x <= right) && (y >= top) && (y <= bottom); 34 | } 35 | 36 | public static float centerX(View view) { 37 | return ViewHelper.getX(view) + view.getWidth() / 2; 38 | } 39 | 40 | public static float centerY(View view) { 41 | return ViewHelper.getY(view) + view.getHeight() / 2; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bottom_bar_hide_to_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/bottom_bar_show_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_in.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/anim/fade_out.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/anim/hide_to_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/in_from_left.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/in_from_right.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/no_anim.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /app/src/main/res/anim/out_to_left.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/out_to_right.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/anim/show_from_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/animator/expand_less_to_expand_more_rotation.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/animator/expand_more_to_expand_less_rotation.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-hdpi/material_shadow_z3.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-ldpi/material_shadow_z3.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-mdpi/material_shadow_z3.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/backdrop.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/backdrop.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/icon_grid.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/icon_grid.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/icon_list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/icon_list.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/material_shadow_z3_mdpi.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/material_shadow_z3_mdpi.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/material_shadow_z3_xhdpi.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/material_shadow_z3_xhdpi.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/material_shadow_z3_xxhdpi.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/material_shadow_z3_xxhdpi.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/material_shadow_z3_xxxhdpi.9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/material_shadow_z3_xxxhdpi.9.png -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/polygon_5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable-nodpi/polygon_5.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/shadow_bottom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/shadow_right.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-nodpi/shadow_top.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xhdpi/material_shadow_z3.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxhdpi/material_shadow_z3.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-xxxhdpi/material_shadow_z3.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/avatar.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable/avatar.jpg -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_button.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/bg_cover.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/dot_filled_black.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_add_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_backspace_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/drawable/ic_backspace_black.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_broken_image_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_check_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_clear_all_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_comment_primary.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_create_new_group_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_description_primary.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 12 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_exit_to_app_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_less.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 24 | 25 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_less_to_expand_more.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_more.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 24 | 25 | 30 | 31 | 32 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_expand_more_to_expand_less.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 19 | 20 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite_border_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_favorite_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_file_download_primary.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_file_download_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_1_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_2_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_3_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_4_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_5_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_6_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_7_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_8_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_9_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_filter_9_plus_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder_image_primary.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_folder_image_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_gallery_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_gallery_primary.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_gallery_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_group_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_history_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_info_outline_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_json_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_load_high_res_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 32 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_next_download_primary_dark.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_pause_primary_dark.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_play_arrow_primary_dark.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_qrcode_scan_white.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_refresh_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_screen_rotation_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_search_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_settings_black.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_shopping_basket_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star_border_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_star_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_update_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_video_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 7 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_web_white.xml: -------------------------------------------------------------------------------- 1 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_check.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_comment.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_description.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_download.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_download_primary.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_favourite.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_folder_image.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_folder_image_primary.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_gallery.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_history.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_search.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/selector_web.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/side_nav_bar.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 10 | 11 | 18 | 19 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_video_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 15 | 16 | 17 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_delete_confirm.xml: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 17 | 18 | 25 | 26 | 32 | 36 | 37 | 42 | 43 | 44 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_loading.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 19 | 20 | 25 | 26 | 27 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/dialog_update.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 15 | 21 | 22 | 23 | 27 | 28 | 38 | 39 | 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /app/src/main/res/layout/fragment_collection.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_add_btn.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 18 | 22 | 23 | 33 | 34 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_category.xml: -------------------------------------------------------------------------------- 1 | 2 | 21 | 22 | 26 | 27 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_category_input.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 17 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_collection_tag.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_picture_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 14 | 15 | 19 | 26 | 27 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_picture_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 15 | 21 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_site_tag.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_source_spinner.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_tab.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 9 | 13 | 14 | 20 | 21 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/layout/item_video_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 19 | 20 | 26 | 27 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /app/src/main/res/layout/nav_tags.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 25 | 26 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_collection_comment.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_collection_index.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_collection_list.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_input_source.xml: -------------------------------------------------------------------------------- 1 | 2 | 8 | 15 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_input_text.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_market_site_list.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /app/src/main/res/layout/view_picture_viewer.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 14 | 20 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/layout/widget_expandable_item_indicator.xml: -------------------------------------------------------------------------------- 1 | 2 | 17 | 21 | 22 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/main/res/menu/search.xml: -------------------------------------------------------------------------------- 1 | 3 | 9 | 15 | 21 | 27 | 33 | -------------------------------------------------------------------------------- /app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/download.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-xxxhdpi/download.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/favorites.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-xxxhdpi/favorites.png -------------------------------------------------------------------------------- /app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/values-v19/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 16dp 7 | 8dp 8 | 9 | 8dp 10 | 11 | 25dp 12 | 13 | 90dp 14 | 193dp 15 | 120dp 16 | 32dp 17 | 40dp 18 | 14sp 19 | 16dp 20 | 145dp 21 | 56dp 22 | 16dp 23 | 32dp 24 | 48dp 25 | 56dp 26 | 240dp 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/values-v21/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 16dp 7 | 8dp 8 | 9 | 8dp 10 | 11 | 0dp 12 | 13 | 90dp 14 | 193dp 15 | 100dp 16 | 32dp 17 | 40dp 18 | 14sp 19 | 16dp 20 | 145dp 21 | 56dp 22 | 16dp 23 | 32dp 24 | 48dp 25 | 56dp 26 | 240dp 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/values/attrs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 16dp 7 | 6dp 8 | 9 | 6dp 10 | 11 | 0dp 12 | 13 | 60dp 14 | 168dp 15 | 100dp 16 | 32dp 17 | 40dp 18 | 14sp 19 | 16dp 20 | 120dp 21 | 56dp 22 | 16dp 23 | 32dp 24 | 48dp 25 | 56dp 26 | 240dp 27 | 28 | 300dp 29 | 30 | -------------------------------------------------------------------------------- /app/src/main/res/values/drawables.xml: -------------------------------------------------------------------------------- 1 | 2 | @android:drawable/ic_menu_camera 3 | @android:drawable/ic_menu_gallery 4 | @android:drawable/ic_menu_slideshow 5 | @android:drawable/ic_menu_manage 6 | @android:drawable/ic_menu_share 7 | @android:drawable/ic_menu_send 8 | 9 | -------------------------------------------------------------------------------- /app/src/main/res/xml/about.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 19 | 23 | 27 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /app/src/main/res/xml/preferences_lock_methods.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 10 | 11 | 15 | 16 | 20 | 21 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/main/res/xml/proxy.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 13 | 14 | 20 | 21 | 27 | 28 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /app/src/main/res/xml/shortcuts.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 14 | 15 | 16 | 17 | 24 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /app/src/test/java/ml/timik/picbox/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package ml.timik.picbox; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.assertEquals; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | buildscript { 3 | repositories { 4 | mavenLocal() 5 | mavenCentral() 6 | maven { 7 | url "https://maven.aliyun.com/repository/public/" 8 | } 9 | maven { 10 | url "https://maven.aliyun.com/repository/google/" 11 | } 12 | maven { 13 | url "https://jitpack.io" 14 | } 15 | maven { 16 | url "http://guardian.github.io/maven/repo-releases" 17 | } 18 | } 19 | dependencies { 20 | classpath 'com.android.tools.build:gradle:3.2.1' 21 | classpath 'com.neenbedankt.gradle.plugins:android-apt:1.8' 22 | // NOTE: Do not place your application dependencies here; they belong 23 | // in the individual module build.gradle files 24 | } 25 | } 26 | repositories { 27 | mavenCentral() 28 | } 29 | allprojects { 30 | repositories { 31 | google() 32 | mavenCentral() 33 | maven { 34 | url "https://jitpack.io" 35 | } 36 | maven { 37 | url "http://maven.aliyun.com/nexus/content/repositories/releases/" 38 | } 39 | } 40 | } 41 | task clean(type: Delete) { 42 | delete rootProject.buildDir 43 | } 44 | ext { 45 | minSdkVersion = 17 46 | targetSdkVersion = 25 47 | compileSdkVersion = 25 48 | buildToolsVersion = '26.0.3' 49 | supportLibraryVersion = '25.2.0' 50 | } -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Nov 01 13:27:09 CST 2021 2 | distributionBase=GRADLE_USER_HOME 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-4.8.1-bin.zip 4 | distributionPath=wrapper/dists 5 | zipStorePath=wrapper/dists 6 | zipStoreBase=GRADLE_USER_HOME 7 | -------------------------------------------------------------------------------- /httpdns/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /httpdns/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.library' 2 | 3 | android { 4 | compileSdkVersion parent.ext.compileSdkVersion 5 | buildToolsVersion parent.ext.buildToolsVersion 6 | defaultConfig { 7 | minSdkVersion parent.ext.minSdkVersion 8 | targetSdkVersion parent.ext.targetSdkVersion 9 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 10 | } 11 | buildTypes { 12 | release { 13 | minifyEnabled false 14 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' 15 | } 16 | } 17 | } 18 | dependencies { 19 | api fileTree(dir: 'libs', include: ['*.jar']) 20 | androidTestImplementation('com.android.support.test.espresso:espresso-core:2.2.2', { 21 | exclude group: 'com.android.support', module: 'support-annotations' 22 | }) 23 | //http 24 | api 'com.squareup.okhttp3:okhttp:3.12.1' 25 | testImplementation 'junit:junit:4.12' 26 | } 27 | -------------------------------------------------------------------------------- /httpdns/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # By default, the flags in this file are appended to flags specified 3 | # in D:\Coding\adt-bundle-windows-x86_64-20140702\sdk/tools/proguard/proguard-android.txt 4 | # You can edit the include path and order by changing the proguardFiles 5 | # directive in build.gradle. 6 | # 7 | # For more details, see 8 | # http://developer.android.com/guide/developing/tools/proguard.html 9 | 10 | # Add any project specific keep options here: 11 | 12 | # If your project uses WebView with JS, uncomment the following 13 | # and specify the fully qualified class name to the JavaScript interface 14 | # class: 15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 16 | # public *; 17 | #} 18 | -------------------------------------------------------------------------------- /httpdns/src/androidTest/java/ml/timik/httpdns/ExampleInstrumentedTest.java: -------------------------------------------------------------------------------- 1 | package ml.timik.httpdns; 2 | 3 | import android.content.Context; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | 10 | import static org.junit.Assert.*; 11 | 12 | /** 13 | * Instrumentation test, which will execute on an Android device. 14 | * 15 | * @see Testing documentation 16 | */ 17 | @RunWith(AndroidJUnit4.class) 18 | public class ExampleInstrumentedTest { 19 | @Test 20 | public void useAppContext() throws Exception { 21 | // Context of the app under test. 22 | Context appContext = InstrumentationRegistry.getTargetContext(); 23 | 24 | assertEquals("ml.puredark.httpdns.test", appContext.getPackageName()); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /httpdns/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/dnsp/DnsConfig.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.dnsp; 2 | 3 | import java.util.ArrayList; 4 | 5 | /** 6 | * 7 | * 项目名称: DNSCache
8 | * 类名称: HttpDnsConfig
9 | * 类描述: HTTPDNS 接口配置类
10 | * 创建人: fenglei
11 | * 创建时间: 2015-4-15 下午9:10:10
12 | * 13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | * 17 | * @version V1.0 18 | */ 19 | public class DnsConfig { 20 | 21 | /** 22 | * 是否使用 自己的httpdns 服务器 23 | */ 24 | public static boolean enableSinaHttpDns = false ; 25 | 26 | /** 27 | * DNSPOD http dns 开端 28 | */ 29 | public static boolean enableDnsPod = true ; 30 | 31 | /** 32 | * DNSPOD http dns 开端 33 | */ 34 | public static boolean enableUdpDns = true ; 35 | 36 | /** 37 | * httpdns 服务器地址 38 | */ 39 | public static ArrayList SINA_HTTPDNS_SERVER_API = new ArrayList(); 40 | 41 | /** 42 | * DNSPOD 服务器地址 43 | */ 44 | public static String DNSPOD_SERVER_API = "http://119.29.29.29/d?dn=" ; 45 | 46 | /** 47 | * dns 服务器地址 48 | */ 49 | public static String UDPDNS_SERVER_API = "119.29.29.29" ; 50 | 51 | 52 | } 53 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/dnsp/IDns.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.dnsp; 2 | 3 | import com.sina.util.dnscache.model.HttpDnsPack; 4 | 5 | import java.util.ArrayList; 6 | 7 | public interface IDns { 8 | 9 | /** 10 | * 请求dns server,解析该domain域名 11 | * @param domain 12 | * @return 13 | */ 14 | public HttpDnsPack requestDns(String domain) ; 15 | 16 | /** 17 | * debug调试信息 18 | * @return 19 | */ 20 | public ArrayList getDebugInfo() ; 21 | 22 | /** 23 | * 初始化debug信息 24 | * @return 25 | */ 26 | public void initDebugInfo() ; 27 | 28 | } -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/dnsp/IDnsProvider.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.dnsp; 2 | 3 | import com.sina.util.dnscache.model.HttpDnsPack; 4 | 5 | public interface IDnsProvider { 6 | 7 | /** 8 | * 请求dns server,返回指定的域名解析信息 9 | * @return 10 | */ 11 | public HttpDnsPack requestDns(String domain) ; 12 | 13 | /** 14 | * 被执行的优先级 15 | * @return 16 | */ 17 | public int getPriority(); 18 | 19 | /** 20 | * 是否是激活状态 21 | * @return 22 | */ 23 | public boolean isActivate(); 24 | 25 | 26 | /** 27 | * 获取dns server的地址 28 | * @return 29 | */ 30 | public String getServerApi(); 31 | } -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/dnsp/IJsonParser.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.sina.util.dnscache.dnsp; 5 | 6 | import com.sina.util.dnscache.model.HttpDnsPack; 7 | 8 | import org.json.JSONArray; 9 | import org.json.JSONObject; 10 | 11 | /** 12 | * 13 | * 项目名称: DNSCache 类名称: IJsonParser 类描述: 创建人: fenglei 创建时间: 2015-3-30 下午3:37:05 14 | * 15 | * 修改人: 修改时间: 修改备注: 16 | * 17 | * @version V1.0 18 | */ 19 | public interface IJsonParser { 20 | 21 | public HttpDnsPack JsonStrToObj(String jsonStr) throws Exception; 22 | 23 | public class JavaJSON_SINAHTTPDNS implements IJsonParser { 24 | 25 | @Override 26 | public HttpDnsPack JsonStrToObj(String jsonStr) throws Exception { 27 | HttpDnsPack dnsPack = new HttpDnsPack(); 28 | JSONObject jsonObj = new JSONObject(jsonStr); 29 | dnsPack.rawResult = jsonStr; 30 | dnsPack.domain = jsonObj.getString("domain"); 31 | dnsPack.device_ip = jsonObj.getString("device_ip"); 32 | dnsPack.device_sp = jsonObj.getString("device_sp"); 33 | 34 | JSONArray jsonarray = jsonObj.getJSONArray("dns"); 35 | dnsPack.dns = new HttpDnsPack.IP[jsonarray.length()]; 36 | for (int i = 0; i < dnsPack.dns.length; i++) { 37 | JSONObject tempJsonObj = new JSONObject(jsonarray.getString(i)); 38 | dnsPack.dns[i] = new HttpDnsPack.IP(); 39 | dnsPack.dns[i].ip = tempJsonObj.getString("ip"); 40 | dnsPack.dns[i].ttl = tempJsonObj.getString("ttl"); 41 | dnsPack.dns[i].priority = tempJsonObj.getString("priority"); 42 | } 43 | return dnsPack; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/log/IDnsLog.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.log; 2 | 3 | import java.io.File; 4 | 5 | public interface IDnsLog { 6 | 7 | /** 8 | * 记录日志 9 | * 10 | * @param type 11 | * 日志类型 12 | * @param body 13 | * 日志信息,建议用json字符串 14 | */ 15 | void writeLog(int type, String action, String body); 16 | 17 | void writeLog(int type, String action, String body, boolean enableSample); 18 | 19 | void writeLog(int type, String action, String body, boolean enableSample, int sampleRate); 20 | 21 | /** 22 | * 获取日志文件 23 | * 24 | * @return 25 | */ 26 | File getLogFile(); 27 | 28 | /** 29 | * 删除文件 30 | * 31 | * @return 32 | */ 33 | boolean deleteLogFile(); 34 | } 35 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/model/ConnectFailModel.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.sina.util.dnscache.model; 5 | 6 | 7 | /** 8 | * 9 | * 项目名称: DNSCache
10 | * 类名称: ConnectFailModel
11 | * 类描述: 链接异常数据模型 - 对应connect_fail表
12 | * 创建人: fenglei
13 | * 创建时间: 2015-3-26 下午5:26:04
14 | * 15 | * 修改人:
16 | * 修改时间:
17 | * 修改备注:
18 | * 19 | * @version V1.0 20 | */ 21 | public class ConnectFailModel { 22 | 23 | public ConnectFailModel(){} 24 | 25 | /** 26 | * 链接失败表 自曾id
27 | * 28 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_ID 字段
29 | */ 30 | public int id = -1 ; 31 | 32 | /** 33 | * 链接失败的ip地址
34 | * 35 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_IP 字段
36 | */ 37 | public int ip = -1 ; 38 | 39 | /** 40 | * 链接失败服务器的端口号
41 | * 42 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_PORT 字段
43 | */ 44 | public int port = -1 ; 45 | 46 | /** 47 | * 链接失败的错误代码,(一般都是http的错误代码)
48 | * 49 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_ERRCODE 字段
50 | */ 51 | public String errcode = "" ; 52 | 53 | /** 54 | * 链接失败时本地网络类型
55 | * 56 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_NETWORK_TYPE 字段
57 | */ 58 | public String network_type = "" ; 59 | 60 | /** 61 | * 链接失败时如果是手机运营商,则统计运营商sp—code(为了重现现场收集数据)
62 | * 63 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_SPCODE 字段
64 | */ 65 | public String spcode = "" ; 66 | 67 | /** 68 | * 链接该服务器总共的错误次数
69 | * 70 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_COUNT 字段
71 | */ 72 | public String count = "" ; 73 | 74 | /** 75 | * 链接该服务器最后失败时间
76 | * 77 | * 该字段映射类 {@link com.sina.util.dnscache.cache.DBConstants } CONNECT_FAIL_FINALLY_TIME 字段
78 | */ 79 | public String finally_tiem = "" ; 80 | 81 | 82 | } 83 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/net/INetworkRequests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * 3 | */ 4 | package com.sina.util.dnscache.net; 5 | 6 | import java.util.HashMap; 7 | 8 | /** 9 | * 10 | * 项目名称: DNSCache 11 | * 类名称: INetworkRequests 12 | * 类描述: 由于该工程是一个辅助lib 尽量复用项目工程里在使用的网络库。 13 | * 创建人: fenglei 14 | * 创建时间: 2015-3-30 上午11:34:07 15 | * 16 | * 修改人: 17 | * 修改时间: 18 | * 修改备注: 19 | * 20 | * @version V1.0 21 | */ 22 | public interface INetworkRequests { 23 | 24 | /** 25 | * 请求网络接口 26 | * @return 返回url数据内容 27 | */ 28 | public String requests(String url) ; 29 | 30 | /** 31 | * 请求网络接口 (带host访问) 32 | * 33 | * @return 返回url数据内容 34 | */ 35 | public String requests(String url, String host) ; 36 | 37 | /** 38 | * 请求网络接口 (多个head访问) 39 | * 40 | * @return 返回url数据内容 41 | */ 42 | public String requests(String url, HashMap head) ; 43 | 44 | /** 45 | * 请求网络接口 (多个head访问) 46 | * 47 | * @return 返回url数据内容 48 | */ 49 | public byte[] requestsByteArr(String url, HashMap head) ; 50 | 51 | } 52 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/net/networktype/NetworkStateReceiver.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.net.networktype; 2 | 3 | import android.content.BroadcastReceiver; 4 | import android.content.Context; 5 | import android.content.Intent; 6 | import android.content.IntentFilter; 7 | import android.net.ConnectivityManager; 8 | import android.net.NetworkInfo; 9 | import android.text.TextUtils; 10 | 11 | import com.sina.util.dnscache.DNSCache; 12 | 13 | public class NetworkStateReceiver extends BroadcastReceiver { 14 | 15 | public String TAG = "TAG_NET" ; 16 | 17 | @Override 18 | public void onReceive(Context context, Intent intent) { 19 | 20 | String action = intent.getAction(); 21 | if (TextUtils.equals(action, ConnectivityManager.CONNECTIVITY_ACTION)) { 22 | NetworkInfo networkInfo = getActiveNetwork(context); 23 | if( networkInfo != null ){ 24 | 25 | // 刷新网络环境 26 | if( NetworkManager.getInstance() != null ) { 27 | NetworkManager.getInstance().Init(); 28 | if( DNSCache.getInstance() != null ){ 29 | DNSCache.getInstance().onNetworkStatusChanged(networkInfo); 30 | } 31 | } 32 | } 33 | } 34 | } 35 | 36 | public static NetworkInfo getActiveNetwork(Context context) { 37 | if (context == null) 38 | return null; 39 | ConnectivityManager mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE); 40 | 41 | if (mConnMgr == null) 42 | return null; 43 | 44 | NetworkInfo aActiveInfo = mConnMgr.getActiveNetworkInfo(); // 获取活动网络连接信息 45 | return aActiveInfo; 46 | } 47 | 48 | public static void register(Context context) { 49 | IntentFilter mFilter = new IntentFilter(); 50 | mFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION); 51 | context.registerReceiver(new NetworkStateReceiver(), mFilter); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/query/IQuery.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.query; 2 | 3 | import com.sina.util.dnscache.model.DomainModel; 4 | 5 | /** 6 | * 7 | * 项目名称: DNSCache
8 | * 类名称: IQuery
9 | * 类描述: 查询模块 对外接口
10 | * 创建人: fenglei
11 | * 创建时间: 2015-4-15 下午5:23:06
12 | * 13 | * 修改人:
14 | * 修改时间:
15 | * 修改备注:
16 | * 17 | * @version V1.0 18 | */ 19 | public interface IQuery { 20 | 21 | public DomainModel queryDomainIp(String sp, String host) ; 22 | 23 | 24 | public DomainModel getCacheDomainIp(String sp, String host) ; 25 | } 26 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/IPlugIn.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score; 2 | 3 | import com.sina.util.dnscache.model.IpModel; 4 | 5 | import java.util.ArrayList; 6 | 7 | 8 | public interface IPlugIn { 9 | 10 | /** 11 | * 插件实现计算分值的方法 12 | */ 13 | public abstract void run(ArrayList list); 14 | 15 | abstract float getWeight(); 16 | 17 | abstract boolean isActivated(); 18 | } 19 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/IScore.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score; 2 | 3 | import com.sina.util.dnscache.model.DomainModel; 4 | import com.sina.util.dnscache.model.IpModel; 5 | 6 | import java.util.ArrayList; 7 | 8 | /** 9 | * Created by fenglei on 15/4/21. 10 | */ 11 | public interface IScore { 12 | 13 | public String[] serverIpScore(DomainModel domainModel) ; 14 | 15 | public String[] ListToArr(ArrayList list) ; 16 | } 17 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/ScoreManager.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score; 2 | 3 | import com.sina.util.dnscache.Tools; 4 | import com.sina.util.dnscache.model.DomainModel; 5 | import com.sina.util.dnscache.model.IpModel; 6 | 7 | import java.util.ArrayList; 8 | 9 | /** 10 | * 11 | * 对 ip 进行排序 12 | * 13 | * Created by fenglei on 15/4/21. 14 | */ 15 | public class ScoreManager implements IScore { 16 | 17 | /** 18 | * 是否开启排序开关 19 | */ 20 | public static boolean IS_SORT = true ; 21 | 22 | private PlugInManager plugInManager = new PlugInManager() ; 23 | 24 | @Override 25 | public String[] serverIpScore(DomainModel domainModel) { 26 | 27 | String[] IpArr = null ; 28 | 29 | // 数据库中得数据,进行排序 , 当ipmodelSize 大于1个的时候在参与排序 30 | if (domainModel.ipModelArr.size() > 1) { 31 | if (IS_SORT) { 32 | plugInManager.run(domainModel.ipModelArr); 33 | } else { 34 | Tools.randomSort(domainModel.ipModelArr); 35 | } 36 | } 37 | 38 | // 转换数据格式 39 | IpArr = ListToArr(domainModel.ipModelArr) ; 40 | 41 | return IpArr; 42 | } 43 | 44 | public String[] ListToArr( ArrayList list){ 45 | if(list == null || list.size() == 0 ) return null ; 46 | String[] IpArr = new String[list.size()]; 47 | for (int i = 0; i < list.size(); i++) { 48 | if( list.get(i) == null ) continue ; 49 | IpArr[i] = list.get(i).ip; 50 | } 51 | return IpArr ; 52 | } 53 | 54 | 55 | } 56 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/plugin/ErrNumPlugin.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score.plugin; 2 | 3 | import com.sina.util.dnscache.model.IpModel; 4 | import com.sina.util.dnscache.score.IPlugIn; 5 | import com.sina.util.dnscache.score.PlugInManager; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class ErrNumPlugin implements IPlugIn { 10 | 11 | @Override 12 | public void run(ArrayList list) { 13 | // 查找到最大错误数 14 | float MAX_ERRNUM = 0; 15 | for (int i = 0; i < list.size(); i++) { 16 | IpModel temp = list.get(i); 17 | if (temp.err_num == null || temp.err_num.equals("")) 18 | continue; 19 | float err_num = Float.parseFloat(temp.err_num); 20 | MAX_ERRNUM = Math.max(MAX_ERRNUM, err_num); 21 | } 22 | // 计算比值 23 | if (MAX_ERRNUM == 0) { 24 | return; 25 | } 26 | float bi = getWeight() / MAX_ERRNUM; 27 | // 计算得分 28 | for (int i = 0; i < list.size(); i++) { 29 | IpModel temp = list.get(i); 30 | if (temp.err_num == null || temp.err_num.equals("")){ 31 | continue; 32 | } 33 | float err_num = Float.parseFloat(temp.err_num); 34 | temp.grade += (err_num - (err_num * bi)); // 错误最少的 得分应该最高 35 | } 36 | } 37 | 38 | @Override 39 | public float getWeight() { 40 | return PlugInManager.ErrNumPluginNum; 41 | } 42 | 43 | @Override 44 | public boolean isActivated() { 45 | return true; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/plugin/PriorityPlugin.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score.plugin; 2 | 3 | import com.sina.util.dnscache.model.IpModel; 4 | import com.sina.util.dnscache.score.IPlugIn; 5 | import com.sina.util.dnscache.score.PlugInManager; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class PriorityPlugin implements IPlugIn { 10 | 11 | @Override 12 | public void run(ArrayList list) { 13 | // 查找到最大优先级 14 | float MAX_PRIORITY = 0; 15 | for (int i = 0; i < list.size(); i++) { 16 | IpModel temp = list.get(i); 17 | if (temp.priority == null || temp.priority.equals("")) 18 | continue; 19 | float priority = Float.parseFloat(temp.priority); 20 | MAX_PRIORITY = Math.max(MAX_PRIORITY, priority); 21 | } 22 | // 计算比值 23 | if (MAX_PRIORITY == 0) { 24 | return; 25 | } 26 | float bi = getWeight() / MAX_PRIORITY; 27 | // 计算得分 28 | for (int i = 0; i < list.size(); i++) { 29 | IpModel temp = list.get(i); 30 | if (temp.priority == null || temp.priority.equals("")){ 31 | continue; 32 | } 33 | float priority = Float.parseFloat(temp.priority); 34 | temp.grade += (priority * bi); 35 | } 36 | 37 | } 38 | 39 | @Override 40 | public float getWeight() { 41 | return PlugInManager.PriorityPluginNum; 42 | } 43 | 44 | @Override 45 | public boolean isActivated() { 46 | return true; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/plugin/SpeedTestPlugin.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score.plugin; 2 | 3 | import com.sina.util.dnscache.model.IpModel; 4 | import com.sina.util.dnscache.score.IPlugIn; 5 | import com.sina.util.dnscache.score.PlugInManager; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class SpeedTestPlugin implements IPlugIn { 10 | 11 | @Override 12 | public void run(ArrayList list) { 13 | // 查找到最大速度 14 | float MAX_SPEED = 0; 15 | for (int i = 0; i < list.size(); i++) { 16 | IpModel temp = list.get(i); 17 | if (temp.rtt == null || temp.rtt.equals("")) 18 | continue; 19 | float finallySpeed = Float.parseFloat(temp.rtt); 20 | MAX_SPEED = Math.max(MAX_SPEED, finallySpeed); 21 | } 22 | // 计算比值 23 | if (MAX_SPEED == 0) { 24 | return; 25 | } 26 | float bi = getWeight() / MAX_SPEED; 27 | // 计算得分 28 | for (int i = 0; i < list.size(); i++) { 29 | IpModel temp = list.get(i); 30 | if (temp.rtt == null || temp.rtt.equals("")){ 31 | continue; 32 | } 33 | float finallySpeed = Float.parseFloat(temp.rtt); 34 | temp.grade += (getWeight() - (finallySpeed * bi)); 35 | } 36 | } 37 | 38 | @Override 39 | public float getWeight() { 40 | return PlugInManager.SpeedTestPluginNum; 41 | } 42 | 43 | @Override 44 | public boolean isActivated() { 45 | return true; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/plugin/SuccessNumPlugin.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score.plugin; 2 | 3 | import com.sina.util.dnscache.model.IpModel; 4 | import com.sina.util.dnscache.score.IPlugIn; 5 | import com.sina.util.dnscache.score.PlugInManager; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class SuccessNumPlugin implements IPlugIn { 10 | 11 | @Override 12 | public void run(ArrayList list) { 13 | // 查找到最大历史成功次数 14 | float MAX_SUCCESSNUM = 0; 15 | for (int i = 0; i < list.size(); i++) { 16 | IpModel temp = list.get(i); 17 | if (temp.success_num == null || temp.success_num.equals("")) 18 | continue; 19 | float successNum = Float.parseFloat(temp.success_num); 20 | MAX_SUCCESSNUM = Math.max(MAX_SUCCESSNUM, successNum); 21 | } 22 | // 计算比值 23 | if (MAX_SUCCESSNUM == 0) { 24 | return; 25 | } 26 | float bi = getWeight() / MAX_SUCCESSNUM; 27 | // 计算得分 28 | for (int i = 0; i < list.size(); i++) { 29 | IpModel temp = list.get(i); 30 | if (temp.success_num == null || temp.success_num.equals("")){ 31 | continue; 32 | } 33 | float successNum = Float.parseFloat(temp.success_num); 34 | temp.grade += (successNum * bi); 35 | } 36 | 37 | } 38 | 39 | @Override 40 | public float getWeight() { 41 | return PlugInManager.SuccessNumPluginNum; 42 | } 43 | 44 | @Override 45 | public boolean isActivated() { 46 | return true; 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/score/plugin/SuccessTimePlugin.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.score.plugin; 2 | 3 | import com.sina.util.dnscache.model.IpModel; 4 | import com.sina.util.dnscache.score.IPlugIn; 5 | import com.sina.util.dnscache.score.PlugInManager; 6 | 7 | import java.util.ArrayList; 8 | 9 | public class SuccessTimePlugin implements IPlugIn { 10 | 11 | @Override 12 | public void run(ArrayList list) { 13 | final float dayTime = 24 * 60;// 单位是minute 14 | final float bi = getWeight() / dayTime; 15 | for (int i = 0; i < list.size(); i++) { 16 | IpModel temp = list.get(i); 17 | if (temp.finally_success_time == null || temp.finally_success_time.equals("")) 18 | continue; 19 | long lastSuccTime = Long.parseLong(temp.finally_success_time); 20 | long now = System.currentTimeMillis(); 21 | long offTime = (now - lastSuccTime) / 1000 / 60; // 单位是minute 22 | if (offTime > dayTime) { 23 | continue; 24 | } else { 25 | temp.grade += (getWeight() - (offTime * bi)); 26 | } 27 | } 28 | } 29 | 30 | @Override 31 | public float getWeight() { 32 | return PlugInManager.SuccessTimePluginNum; 33 | } 34 | 35 | @Override 36 | public boolean isActivated() { 37 | return true; 38 | } 39 | 40 | } 41 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/speedtest/BaseSpeedTest.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.speedtest; 2 | 3 | 4 | public abstract class BaseSpeedTest { 5 | 6 | public abstract int speedTest(String ip, String host); 7 | 8 | /** 9 | * 被执行的优先级 10 | * @return 11 | */ 12 | public abstract int getPriority(); 13 | 14 | /** 15 | * 是否是激活状态 16 | * @return 17 | */ 18 | public abstract boolean isActivate(); 19 | 20 | } -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/speedtest/ISpeedtest.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.speedtest; 2 | 3 | /** 4 | * Created by fenglei on 15/4/22. 5 | */ 6 | public interface ISpeedtest { 7 | 8 | public int speedTest(String ip, String host); 9 | 10 | } 11 | -------------------------------------------------------------------------------- /httpdns/src/main/java/com/sina/util/dnscache/speedtest/impl/Socket80Test.java: -------------------------------------------------------------------------------- 1 | package com.sina.util.dnscache.speedtest.impl; 2 | 3 | import com.sina.util.dnscache.speedtest.BaseSpeedTest; 4 | import com.sina.util.dnscache.speedtest.SpeedtestManager; 5 | 6 | import java.io.IOException; 7 | import java.net.InetSocketAddress; 8 | import java.net.Socket; 9 | 10 | public class Socket80Test extends BaseSpeedTest { 11 | 12 | static final int TIMEOUT = 5 * 1000; 13 | 14 | @Override 15 | public int speedTest(String ip, String host) { 16 | Socket socket = null; 17 | try { 18 | long begin = System.currentTimeMillis(); 19 | Socket s1 = new Socket(); 20 | s1.connect(new InetSocketAddress(ip, 80), TIMEOUT); 21 | long end = System.currentTimeMillis(); 22 | int rtt = (int) (end - begin); 23 | return rtt; 24 | } catch (Exception e) { 25 | e.printStackTrace(); 26 | } finally { 27 | try { 28 | if (null != socket) { 29 | socket.close(); 30 | } 31 | } catch (IOException e) { 32 | e.printStackTrace(); 33 | } 34 | } 35 | return SpeedtestManager.OCUR_ERROR; 36 | } 37 | 38 | @Override 39 | public int getPriority() { 40 | return 10; 41 | } 42 | 43 | @Override 44 | public boolean isActivate() { 45 | return true; 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /httpdns/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | HttpDns 3 | 4 | -------------------------------------------------------------------------------- /httpdns/src/test/java/ml/timik/httpdns/ExampleUnitTest.java: -------------------------------------------------------------------------------- 1 | package ml.timik.httpdns; 2 | 3 | import org.junit.Test; 4 | 5 | import static org.junit.Assert.*; 6 | 7 | /** 8 | * Example local unit test, which will execute on the development machine (host). 9 | * 10 | * @see Testing documentation 11 | */ 12 | public class ExampleUnitTest { 13 | @Test 14 | public void addition_isCorrect() throws Exception { 15 | assertEquals(4, 2 + 2); 16 | } 17 | } -------------------------------------------------------------------------------- /images/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/1.png -------------------------------------------------------------------------------- /images/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/10.png -------------------------------------------------------------------------------- /images/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/11.png -------------------------------------------------------------------------------- /images/12.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/12.png -------------------------------------------------------------------------------- /images/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/2.png -------------------------------------------------------------------------------- /images/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/3.png -------------------------------------------------------------------------------- /images/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/4.png -------------------------------------------------------------------------------- /images/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/5.png -------------------------------------------------------------------------------- /images/6.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/6.gif -------------------------------------------------------------------------------- /images/7.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/7.gif -------------------------------------------------------------------------------- /images/8.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/8.gif -------------------------------------------------------------------------------- /images/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/9.png -------------------------------------------------------------------------------- /images/getitoncoolmarket.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/getitoncoolmarket.png -------------------------------------------------------------------------------- /images/qrcodes/1.lofi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/1.lofi.png -------------------------------------------------------------------------------- /images/qrcodes/10.pixiv.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/10.pixiv.png -------------------------------------------------------------------------------- /images/qrcodes/11.177.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/11.177.png -------------------------------------------------------------------------------- /images/qrcodes/12.绝对领域.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/12.绝对领域.png -------------------------------------------------------------------------------- /images/qrcodes/13.二次萌エロ画像ブログ.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/13.二次萌エロ画像ブログ.png -------------------------------------------------------------------------------- /images/qrcodes/2.g.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/2.g.png -------------------------------------------------------------------------------- /images/qrcodes/3.exhentai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/3.exhentai.png -------------------------------------------------------------------------------- /images/qrcodes/4.wnacg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/4.wnacg.png -------------------------------------------------------------------------------- /images/qrcodes/5.nhentai.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/5.nhentai.png -------------------------------------------------------------------------------- /images/qrcodes/6.草榴社区.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/6.草榴社区.png -------------------------------------------------------------------------------- /images/qrcodes/7.e-shuushuu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/7.e-shuushuu.png -------------------------------------------------------------------------------- /images/qrcodes/8.xiuren.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/8.xiuren.png -------------------------------------------------------------------------------- /images/qrcodes/9.rosiyy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TminiK/Picbox/db9df30618b880348792acdaedc0dd010d10d1af/images/qrcodes/9.rosiyy.png -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app', ':httpdns' 2 | --------------------------------------------------------------------------------