├── project ├── settings.gradle ├── app │ ├── app-release.apk │ ├── src │ │ └── main │ │ │ ├── res │ │ │ ├── mipmap-hdpi │ │ │ │ ├── ic_mood.png │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-mdpi │ │ │ │ ├── ic_mood.png │ │ │ │ └── ic_launcher.png │ │ │ ├── values-w820dp │ │ │ │ └── dimens.xml │ │ │ ├── drawable-hdpi │ │ │ │ ├── ic_gif.png │ │ │ │ ├── ic_arrow_down.png │ │ │ │ ├── ic_arrow_up.png │ │ │ │ ├── ic_play_black.png │ │ │ │ ├── ic_play_white.png │ │ │ │ ├── ic_camera_black.png │ │ │ │ ├── ic_camera_white.png │ │ │ │ ├── ic_delete_black.png │ │ │ │ ├── ic_delete_white.png │ │ │ │ ├── ic_share_black.png │ │ │ │ ├── ic_share_white.png │ │ │ │ ├── ic_video_black.png │ │ │ │ ├── ic_video_white.png │ │ │ │ ├── ic_settings_black.png │ │ │ │ ├── ic_settings_white.png │ │ │ │ ├── ic_visibility_off.png │ │ │ │ ├── ic_crop_rotate_black.png │ │ │ │ └── ic_crop_rotate_white.png │ │ │ ├── drawable-mdpi │ │ │ │ ├── ic_gif.png │ │ │ │ ├── ic_arrow_down.png │ │ │ │ ├── ic_arrow_up.png │ │ │ │ ├── ic_play_black.png │ │ │ │ ├── ic_play_white.png │ │ │ │ ├── ic_camera_black.png │ │ │ │ ├── ic_camera_white.png │ │ │ │ ├── ic_delete_black.png │ │ │ │ ├── ic_delete_white.png │ │ │ │ ├── ic_share_black.png │ │ │ │ ├── ic_share_white.png │ │ │ │ ├── ic_video_black.png │ │ │ │ ├── ic_video_white.png │ │ │ │ ├── ic_settings_black.png │ │ │ │ ├── ic_settings_white.png │ │ │ │ ├── ic_visibility_off.png │ │ │ │ ├── ic_crop_rotate_black.png │ │ │ │ └── ic_crop_rotate_white.png │ │ │ ├── drawable-xhdpi │ │ │ │ ├── ic_gif.png │ │ │ │ ├── ic_arrow_up.png │ │ │ │ ├── ic_arrow_down.png │ │ │ │ ├── ic_play_black.png │ │ │ │ ├── ic_play_white.png │ │ │ │ ├── ic_share_black.png │ │ │ │ ├── ic_share_white.png │ │ │ │ ├── ic_video_black.png │ │ │ │ ├── ic_video_white.png │ │ │ │ ├── ic_camera_black.png │ │ │ │ ├── ic_camera_white.png │ │ │ │ ├── ic_delete_black.png │ │ │ │ ├── ic_delete_white.png │ │ │ │ ├── ic_settings_black.png │ │ │ │ ├── ic_settings_white.png │ │ │ │ ├── ic_visibility_off.png │ │ │ │ ├── ic_crop_rotate_black.png │ │ │ │ └── ic_crop_rotate_white.png │ │ │ ├── drawable-xxhdpi │ │ │ │ ├── ic_gif.png │ │ │ │ ├── ic_arrow_up.png │ │ │ │ ├── ic_arrow_down.png │ │ │ │ ├── ic_play_black.png │ │ │ │ ├── ic_play_white.png │ │ │ │ ├── ic_camera_black.png │ │ │ │ ├── ic_camera_white.png │ │ │ │ ├── ic_delete_black.png │ │ │ │ ├── ic_delete_white.png │ │ │ │ ├── ic_share_black.png │ │ │ │ ├── ic_share_white.png │ │ │ │ ├── ic_video_black.png │ │ │ │ ├── ic_video_white.png │ │ │ │ ├── ic_settings_black.png │ │ │ │ ├── ic_settings_white.png │ │ │ │ ├── ic_visibility_off.png │ │ │ │ ├── ic_crop_rotate_black.png │ │ │ │ └── ic_crop_rotate_white.png │ │ │ ├── mipmap-xhdpi │ │ │ │ ├── ic_mood.png │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxhdpi │ │ │ │ ├── ic_mood.png │ │ │ │ └── ic_launcher.png │ │ │ ├── mipmap-xxxhdpi │ │ │ │ ├── ic_mood.png │ │ │ │ └── ic_launcher.png │ │ │ ├── drawable-xxxhdpi │ │ │ │ ├── ic_gif.png │ │ │ │ ├── ic_arrow_up.png │ │ │ │ ├── ic_arrow_down.png │ │ │ │ ├── ic_camera_black.png │ │ │ │ ├── ic_camera_white.png │ │ │ │ ├── ic_delete_black.png │ │ │ │ ├── ic_delete_white.png │ │ │ │ ├── ic_play_black.png │ │ │ │ ├── ic_play_white.png │ │ │ │ ├── ic_share_black.png │ │ │ │ ├── ic_share_white.png │ │ │ │ ├── ic_video_black.png │ │ │ │ ├── ic_video_white.png │ │ │ │ ├── ic_settings_black.png │ │ │ │ ├── ic_settings_white.png │ │ │ │ ├── ic_visibility_off.png │ │ │ │ ├── ic_crop_rotate_black.png │ │ │ │ └── ic_crop_rotate_white.png │ │ │ ├── values-sw600dp │ │ │ │ └── dimens.xml │ │ │ ├── drawable │ │ │ │ ├── ripple.xml │ │ │ │ ├── circle.xml │ │ │ │ ├── vd_pathmorph_plusminus_minus.xml │ │ │ │ ├── vd_pathmorph_plusminus_plus.xml │ │ │ │ ├── avd_pathmorph_plusminus_minus_to_plus.xml │ │ │ │ └── avd_pathmorph_plusminus_plus_to_minus.xml │ │ │ ├── layout │ │ │ │ ├── recycler_view.xml │ │ │ │ ├── media_activity.xml │ │ │ │ ├── hidden_item.xml │ │ │ │ ├── media_fragment.xml │ │ │ │ ├── toolbar.xml │ │ │ │ ├── preference_activity.xml │ │ │ │ ├── main_activity.xml │ │ │ │ ├── bottom_sheet_media_actions.xml │ │ │ │ ├── camera_permission_dialog.xml │ │ │ │ ├── hidden_albums_dialog.xml │ │ │ │ ├── media_actions.xml │ │ │ │ ├── media_pager.xml │ │ │ │ ├── header_layout.xml │ │ │ │ ├── floating_plus.xml │ │ │ │ ├── media_item.xml │ │ │ │ └── bottom_sheet_info.xml │ │ │ ├── values │ │ │ │ ├── dimens.xml │ │ │ │ ├── pathmorph_plusminus.xml │ │ │ │ ├── attrs.xml │ │ │ │ ├── colors.xml │ │ │ │ ├── arrays.xml │ │ │ │ └── strings.xml │ │ │ ├── menu │ │ │ │ └── main.xml │ │ │ ├── xml │ │ │ │ └── prefs.xml │ │ │ ├── values-nl │ │ │ │ └── strings.xml │ │ │ ├── values-cs │ │ │ │ └── strings.xml │ │ │ ├── values-it │ │ │ │ └── strings.xml │ │ │ ├── values-fr │ │ │ │ └── strings.xml │ │ │ └── values-v23 │ │ │ │ └── styles.xml │ │ │ ├── java │ │ │ └── com │ │ │ │ └── enrico │ │ │ │ └── gallery │ │ │ │ └── galleryapp │ │ │ │ ├── albums │ │ │ │ ├── Albums.java │ │ │ │ ├── ItemViewHolder.java │ │ │ │ ├── HeaderViewHolder.java │ │ │ │ ├── MediaFromAlbums.java │ │ │ │ ├── AsyncLoadGallery.java │ │ │ │ ├── AlbumsUtils.java │ │ │ │ └── HeaderRecyclerViewSection.java │ │ │ │ ├── utils │ │ │ │ ├── SDCardUtils.java │ │ │ │ ├── ShareUtils.java │ │ │ │ ├── ApplyWallpaper.java │ │ │ │ ├── InfoUtils.java │ │ │ │ ├── PermissionUtils.java │ │ │ │ ├── SaveTools.java │ │ │ │ ├── DeleteFileUtils.java │ │ │ │ ├── BottomSheetMediaActions.java │ │ │ │ └── MediaBrowser.java │ │ │ │ ├── ImmersiveMode.java │ │ │ │ ├── MediaObserver.java │ │ │ │ ├── settings │ │ │ │ ├── HiddenAlbumsAdapter.java │ │ │ │ ├── HiddenFoldersDialog.java │ │ │ │ ├── SettingsActivity.java │ │ │ │ └── Preferences.java │ │ │ │ ├── MediaActivity.java │ │ │ │ └── MediaPagerFragment.java │ │ │ └── AndroidManifest.xml │ ├── proguard-rules.pro │ └── build.gradle ├── gradle │ └── wrapper │ │ ├── gradle-wrapper.jar │ │ └── gradle-wrapper.properties ├── build.gradle ├── gradle.properties ├── gradlew.bat └── gradlew ├── art ├── icon.png └── screens4.png ├── Policy └── README.md /project/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | -------------------------------------------------------------------------------- /art/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/art/icon.png -------------------------------------------------------------------------------- /art/screens4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/art/screens4.png -------------------------------------------------------------------------------- /project/app/app-release.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/app-release.apk -------------------------------------------------------------------------------- /project/gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-hdpi/ic_mood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-hdpi/ic_mood.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-mdpi/ic_mood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-mdpi/ic_mood.png -------------------------------------------------------------------------------- /project/app/src/main/res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 64dp 4 | 5 | 6 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_gif.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_gif.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_gif.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_gif.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-xhdpi/ic_mood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-xhdpi/ic_mood.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-xxhdpi/ic_mood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-xxhdpi/ic_mood.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-xxxhdpi/ic_mood.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-xxxhdpi/ic_mood.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_gif.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_gif.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_arrow_down.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_arrow_up.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_play_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_play_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_play_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_play_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_arrow_down.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_arrow_up.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_play_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_play_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_play_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_play_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_arrow_up.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_arrow_up.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_camera_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_camera_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_camera_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_camera_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_delete_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_delete_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_delete_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_share_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_share_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_share_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_video_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_video_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_video_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_video_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_camera_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_camera_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_camera_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_camera_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_delete_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_delete_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_delete_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_share_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_share_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_share_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_video_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_video_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_video_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_video_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_arrow_down.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_play_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_play_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_play_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_play_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_share_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_share_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_share_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_video_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_video_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_video_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_video_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_arrow_down.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_play_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_play_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_play_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_play_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_arrow_up.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_arrow_up.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_settings_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_settings_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_visibility_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_visibility_off.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_settings_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_settings_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_visibility_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_visibility_off.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_camera_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_camera_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_camera_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_camera_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_delete_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_delete_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_delete_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_settings_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_settings_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_visibility_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_visibility_off.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_camera_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_camera_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_camera_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_camera_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_delete_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_delete_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_delete_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_share_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_share_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_share_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_video_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_video_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_video_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_video_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_arrow_down.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_arrow_down.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_camera_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_camera_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_camera_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_camera_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_delete_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_delete_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_delete_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_delete_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_play_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_play_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_play_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_play_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_share_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_share_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_share_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_share_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_video_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_video_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_video_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_video_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_crop_rotate_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_crop_rotate_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-hdpi/ic_crop_rotate_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-hdpi/ic_crop_rotate_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_crop_rotate_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_crop_rotate_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-mdpi/ic_crop_rotate_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-mdpi/ic_crop_rotate_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_settings_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_settings_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_visibility_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_visibility_off.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_settings_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_settings_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_settings_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_settings_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_visibility_off.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_visibility_off.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_crop_rotate_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_crop_rotate_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xhdpi/ic_crop_rotate_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xhdpi/ic_crop_rotate_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_crop_rotate_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_crop_rotate_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxhdpi/ic_crop_rotate_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxhdpi/ic_crop_rotate_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_crop_rotate_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_crop_rotate_black.png -------------------------------------------------------------------------------- /project/app/src/main/res/drawable-xxxhdpi/ic_crop_rotate_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/enricocid/Gallery-example/HEAD/project/app/src/main/res/drawable-xxxhdpi/ic_crop_rotate_white.png -------------------------------------------------------------------------------- /project/app/src/main/res/values-sw600dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 24dp 4 | 12dp 5 | 6 | 7 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable/ripple.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | -------------------------------------------------------------------------------- /project/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Sun May 07 18:48:28 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-3.3-all.zip 7 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable/circle.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/recycler_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | -------------------------------------------------------------------------------- /project/app/src/main/res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 16dp 4 | 16dp 5 | 6 | 16dp 7 | 8 | 4dp 9 | 10 | 16dp 11 | 12 | -------------------------------------------------------------------------------- /project/app/src/main/res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 10 | -------------------------------------------------------------------------------- /project/app/src/main/res/values/pathmorph_plusminus.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | M 5,11 L 11,11 L 11,5 L 13,5 L 13,11 L 19,11 L 19,13 L 13,13 L 13,19 L 11,19 L 11,13 L 5,13 Z 4 | M 5,11 L 11,11 L 11,11 L 13,11 L 13,11 L 19,11 L 19,13 L 13,13 L 13,13 L 11,13 L 11,13 L 5,13 Z 5 | 6 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/media_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 9 | 13 | 14 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/hidden_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/media_fragment.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 13 | 14 | -------------------------------------------------------------------------------- /project/build.gradle: -------------------------------------------------------------------------------- 1 | // Top-level build file where you can add configuration options common to all sub-projects/modules. 2 | 3 | buildscript { 4 | repositories { 5 | jcenter() 6 | } 7 | dependencies { 8 | classpath 'com.android.tools.build:gradle:2.3.3' 9 | 10 | } 11 | } 12 | 13 | allprojects { 14 | repositories { 15 | jcenter() 16 | maven { url "https://jitpack.io" } 17 | maven { url 'https://dl.bintray.com/drummer-aidan/maven' } 18 | } 19 | } 20 | 21 | task clean(type: Delete) { 22 | delete rootProject.buildDir 23 | } 24 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/toolbar.xml: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable/vd_pathmorph_plusminus_minus.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable/vd_pathmorph_plusminus_plus.xml: -------------------------------------------------------------------------------- 1 | 7 | 11 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/preference_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 8 | 9 | 12 | 13 | 18 | 19 | -------------------------------------------------------------------------------- /project/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 | -------------------------------------------------------------------------------- /Policy: -------------------------------------------------------------------------------- 1 | Privacy Policy 2 | 3 | Me, Enrico D'Ortenzio, built the Gallery app as an Open Source app. This APP is provided by Me at no cost and is intended for use as is: a Simple Gallery app. 4 | 5 | This page is used to inform Users regarding my policies with the use of android.permission.CAMERA if anyone decided to use my App. 6 | 7 | android.permission.CAMERA permission will be exclusively used to ALLOW USER TO OPEN THE CAMERA/VIDEO APP from within the Gallery App by clicking a Floating Action Button. The permission won't be used to collect or send/share data to third parties. 8 | Moreover, users using Android version >= Marshmallow will be allowed to allow or deny this permission (but camera won't work). 9 | 10 | Best regards, 11 | 12 | Enrico D'Ortenzio -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/Albums.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | 4 | import java.io.File; 5 | 6 | public class Albums { 7 | 8 | private String albumPath; 9 | 10 | void setAlbumsUrl(String albumUrl) { 11 | 12 | File f = new File(albumUrl); 13 | String absolutePath = f.getPath(); 14 | 15 | String filename = absolutePath.substring(absolutePath.lastIndexOf(File.separator) + 1); 16 | 17 | setAlbumsPath(absolutePath.replace(filename, "")); 18 | 19 | } 20 | 21 | String getAlbumsPath() { 22 | return albumPath; 23 | } 24 | 25 | private void setAlbumsPath(String albumPath) { 26 | this.albumPath = albumPath; 27 | } 28 | 29 | } 30 | 31 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/ItemViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.widget.ImageView; 6 | 7 | import com.enrico.gallery.galleryapp.R; 8 | 9 | class ItemViewHolder extends RecyclerView.ViewHolder { 10 | 11 | ImageView picView, cameraView, gifView; 12 | View rootView; 13 | 14 | ItemViewHolder(View itemView) { 15 | super(itemView); 16 | 17 | rootView = itemView; 18 | picView = (ImageView) itemView.findViewById(R.id.imageView); 19 | cameraView = (ImageView) itemView.findViewById(R.id.cameraView); 20 | gifView = (ImageView) itemView.findViewById(R.id.gifView); 21 | 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/main_activity.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 9 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/HeaderViewHolder.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | import android.support.v7.widget.RecyclerView; 4 | import android.view.View; 5 | import android.widget.ImageButton; 6 | import android.widget.ImageView; 7 | import android.widget.TextView; 8 | 9 | import com.enrico.gallery.galleryapp.R; 10 | 11 | class HeaderViewHolder extends RecyclerView.ViewHolder { 12 | 13 | TextView headerTitle; 14 | ImageView imgArrow; 15 | ImageButton imgVisibilty; 16 | 17 | HeaderViewHolder(View itemView) { 18 | super(itemView); 19 | headerTitle = (TextView) itemView.findViewById(R.id.header_id); 20 | imgArrow = (ImageView) itemView.findViewById(R.id.imgArrow); 21 | imgVisibilty = (ImageButton) itemView.findViewById(R.id.imgHide); 22 | } 23 | } -------------------------------------------------------------------------------- /project/app/src/main/res/layout/bottom_sheet_media_actions.xml: -------------------------------------------------------------------------------- 1 | 2 | 13 | 14 | 17 | 18 | 21 | 22 | -------------------------------------------------------------------------------- /project/gradle.properties: -------------------------------------------------------------------------------- 1 | # Project-wide Gradle settings. 2 | 3 | # IDE (e.g. Android Studio) users: 4 | # Gradle settings configured through the IDE *will override* 5 | # any settings specified in this file. 6 | 7 | # For more details on how to configure your build environment visit 8 | # http://www.gradle.org/docs/current/userguide/build_environment.html 9 | 10 | # Specifies the JVM arguments used for the daemon process. 11 | # The setting is particularly useful for tweaking memory settings. 12 | # Default value: -Xmx10248m -XX:MaxPermSize=256m 13 | # org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 14 | 15 | # When configured, Gradle will run in incubating parallel mode. 16 | # This option should only be used with decoupled projects. More details, visit 17 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects 18 | # org.gradle.parallel=true -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/SDCardUtils.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.content.SharedPreferences; 6 | 7 | public class SDCardUtils { 8 | 9 | public static void saveSDCardUri(Activity activity, String uri) { 10 | 11 | SharedPreferences preferenceSD; 12 | preferenceSD = activity.getSharedPreferences("sdUri", Context.MODE_PRIVATE); 13 | 14 | 15 | preferenceSD.edit() 16 | .clear() 17 | .apply(); 18 | 19 | preferenceSD.edit() 20 | .putString("selectedSD", uri) 21 | .apply(); 22 | } 23 | 24 | static String getSDCardUri(Activity activity) { 25 | 26 | SharedPreferences preferenceSD = activity.getSharedPreferences("sdUri", Context.MODE_PRIVATE); 27 | 28 | return preferenceSD.getString("selectedSD", ""); 29 | } 30 | } 31 | 32 | -------------------------------------------------------------------------------- /project/app/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 C:\Users\Enrico\AppData\Local\Android\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 | 19 | # Uncomment this to preserve the line number information for 20 | # debugging stack traces. 21 | #-keepattributes SourceFile,LineNumberTable 22 | 23 | # If you keep the line number information, uncomment this to 24 | # hide the original source file name. 25 | #-renamesourcefileattribute SourceFile -------------------------------------------------------------------------------- /project/app/src/main/res/layout/camera_permission_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 27 | 28 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/ImmersiveMode.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp; 2 | 3 | import android.app.Activity; 4 | import android.view.View; 5 | import android.view.WindowManager; 6 | 7 | /** 8 | * Created by Enrico on 27/05/2017. 9 | */ 10 | 11 | public class ImmersiveMode { 12 | 13 | public static void On(Activity activity) { 14 | 15 | activity.getWindow().setFlags(WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS, 16 | WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS); 17 | 18 | activity.getWindow().getDecorView().setSystemUiVisibility( 19 | View.SYSTEM_UI_FLAG_LAYOUT_STABLE 20 | | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION 21 | | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN 22 | | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION 23 | | View.SYSTEM_UI_FLAG_FULLSCREEN 24 | | View.SYSTEM_UI_FLAG_IMMERSIVE 25 | | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY 26 | ); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/hidden_albums_dialog.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 19 | 20 | 26 | 27 | -------------------------------------------------------------------------------- /project/app/src/main/res/xml/prefs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 8 | 15 | 16 | 23 | 24 | 28 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/ShareUtils.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.net.Uri; 6 | import android.webkit.MimeTypeMap; 7 | 8 | import com.enrico.gallery.galleryapp.R; 9 | 10 | import java.io.File; 11 | 12 | class ShareUtils { 13 | 14 | static void shareFile(Activity activity, String url) { 15 | try { 16 | File myFile = new File(url); 17 | MimeTypeMap mime = MimeTypeMap.getSingleton(); 18 | String ext = myFile.getName().substring(myFile.getName().lastIndexOf(".") + 1); 19 | String type = mime.getMimeTypeFromExtension(ext); 20 | Intent sharingIntent = new Intent("android.intent.action.SEND"); 21 | sharingIntent.setType(type); 22 | sharingIntent.putExtra("android.intent.extra.STREAM", Uri.fromFile(myFile)); 23 | activity.startActivity(Intent.createChooser(sharingIntent, activity.getString(R.string.shareWith))); 24 | } catch (Exception e) { 25 | e.printStackTrace(); 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable/avd_pathmorph_plusminus_minus_to_plus.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /project/app/src/main/res/drawable/avd_pathmorph_plusminus_plus_to_minus.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 6 | 7 | 13 | 14 | 15 | 16 | 17 | 18 | 25 | 26 | 27 | 28 | 29 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/media_actions.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 16 | 17 | 25 | 26 | 34 | 35 | -------------------------------------------------------------------------------- /project/app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | 3 | android { 4 | compileSdkVersion 25 5 | buildToolsVersion "25.0.3" 6 | 7 | lintOptions { 8 | checkReleaseBuilds true 9 | abortOnError false 10 | } 11 | 12 | defaultConfig { 13 | applicationId "com.enrico.gallery.galleryapp" 14 | minSdkVersion 21 15 | targetSdkVersion 25 16 | versionCode 7 17 | versionName "2.1" 18 | } 19 | 20 | buildTypes { 21 | 22 | release { 23 | zipAlignEnabled true 24 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 25 | 'proguard-rules.pro' 26 | } 27 | debug { 28 | zipAlignEnabled true 29 | } 30 | } 31 | } 32 | 33 | dependencies { 34 | 35 | compile 'com.android.support:appcompat-v7:25.3.1' 36 | compile 'com.github.bumptech.glide:glide:3.7.0' 37 | compile 'com.android.support:recyclerview-v7:25.3.1' 38 | compile 'com.android.support:percent:25.3.1' 39 | compile 'com.android.support:design:25.3.1' 40 | compile 'com.github.chrisbanes:PhotoView:2.0.0' 41 | compile 'com.afollestad:easyvideoplayer:0.3.0' 42 | compile 'com.theartofdev.edmodo:android-image-cropper:2.4.6' 43 | compile 'io.github.luizgrp.sectionedrecyclerviewadapter:sectionedrecyclerviewadapter:1.0.5' 44 | } 45 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/MediaFromAlbums.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | 4 | import java.io.File; 5 | import java.io.FilenameFilter; 6 | 7 | class MediaFromAlbums { 8 | 9 | private static final String[] EXTENSIONS = new String[]{ 10 | "gif", "png", "ico", "tiff", "webp", "jpeg", 11 | "bpg", "svg", "bmp", "jpg", "mp4", 12 | "avi", "mpg", "mkv", "webm", "flv", 13 | "wmv", "mov", "qt", "m4p", "m4v", 14 | "mpeg", "mp2", "m2v", "3gp", "3g2", 15 | "f4v", "f4p", "f4a" 16 | }; 17 | 18 | private static final FilenameFilter MEDIA_FILTER = new FilenameFilter() { 19 | 20 | @Override 21 | public boolean accept(final File dir, final String name) { 22 | for (final String ext : EXTENSIONS) { 23 | if (name.endsWith("." + ext)) { 24 | return (true); 25 | } 26 | } 27 | return false; 28 | } 29 | }; 30 | 31 | static String[] listMedia(String path) { 32 | 33 | File[] listFile; 34 | 35 | String[] FilePathStrings; 36 | 37 | File file = new File(path); 38 | 39 | listFile = file.listFiles(MEDIA_FILTER); 40 | 41 | FilePathStrings = new String[listFile.length]; 42 | 43 | for (int i = 0; i < listFile.length; i++) { 44 | 45 | FilePathStrings[i] = listFile[i].getAbsolutePath(); 46 | 47 | } 48 | 49 | return FilePathStrings; 50 | 51 | } 52 | } 53 | 54 | -------------------------------------------------------------------------------- /project/app/src/main/res/values/colors.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | #40ffffff 5 | #40000000 6 | #90ffffff 7 | 8 | #263238 9 | 10 | #616161 11 | #424242 12 | #D32F2F 13 | #0288D1 14 | #FF1744 15 | #F50057 16 | #D500F9 17 | #651FFF 18 | #3D5AFE 19 | #2979FF 20 | #00B0FF 21 | #00E5FF 22 | #1DE9B6 23 | #00E676 24 | #76FF03 25 | #C6FF00 26 | #FFEA00 27 | #FFC400 28 | #FF9100 29 | #FF3D00 30 | #8D6E63 31 | #78909C 32 | 33 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/media_pager.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 10 | 11 | 16 | 17 | 23 | 24 | 35 | 36 | 37 | 40 | 41 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/header_layout.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | 17 | 18 | 23 | 24 | 34 | 35 | 44 | 45 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/AsyncLoadGallery.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | import android.app.Activity; 4 | import android.os.AsyncTask; 5 | import android.support.v7.widget.RecyclerView; 6 | 7 | import java.util.ArrayList; 8 | 9 | import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter; 10 | 11 | public class AsyncLoadGallery { 12 | 13 | public static void execute(Activity activity, RecyclerView recyclerView, SectionedRecyclerViewAdapter sectionedRecyclerViewAdapter) { 14 | 15 | new populateGallery(activity, recyclerView, sectionedRecyclerViewAdapter).execute(); 16 | } 17 | 18 | private static class populateGallery extends AsyncTask { 19 | 20 | Activity activity; 21 | ArrayList albumsList; 22 | 23 | private RecyclerView recyclerView; 24 | private SectionedRecyclerViewAdapter sectionedRecyclerViewAdapter; 25 | 26 | private String[] resultFolders; 27 | 28 | private populateGallery(Activity activity, RecyclerView recyclerView, SectionedRecyclerViewAdapter sectionedRecyclerViewAdapter) { 29 | this.activity = activity; 30 | this.recyclerView = recyclerView; 31 | this.sectionedRecyclerViewAdapter = sectionedRecyclerViewAdapter; 32 | } 33 | 34 | 35 | protected void onPreExecute() { 36 | 37 | } 38 | 39 | @Override 40 | protected Void doInBackground(Void... params) { 41 | 42 | albumsList = AlbumsUtils.getAllAlbums(activity); 43 | resultFolders = AlbumsUtils.initFolders(activity, albumsList); 44 | return null; 45 | } 46 | 47 | @Override 48 | protected void onPostExecute(Void result) { 49 | AlbumsUtils.setupAlbums(activity, resultFolders, recyclerView, sectionedRecyclerViewAdapter); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/floating_plus.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 20 | 21 | 33 | 34 | 45 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gallery example 2 | This is how I want the gallery app ... simple. 3 | 4 | 5 | The app supports 5.0+ devices. 6 | 7 | Features: 8 | 9 | - Albums are shown in a recycler view with expandable sections; 10 | - Change columns number; 11 | - Hide folders (go to settings to make them visible again); 12 | - Bunch of themes; 13 | - Play videos and gifs; 14 | - Long click on media pager will show bottom sheet with infos and actions; 15 | - Crop, share, set as wallpaper or delete media; 16 | 17 | **Message for translators:** 18 | 19 | - Don't include strings marked untranslatable, i.e those with translatable="false"; 20 | 21 | - Don't forget to precede apostrophes by 22 | ``` 23 | \ 24 | ``` 25 | 26 | Thanks!:) 27 | 28 | 29 | ![ScreenShot](https://raw.githubusercontent.com/enricocid/Gallery/master/art/screens4.png) 30 | 31 | 32 | You can download the latest (2.1) signed APK from this repo here: https://github.com/enricocid/Gallery/raw/master/project/app/app-release.apk 33 | 34 | 35 | 36 | 37 | 38 | **Credits:** 39 | 40 | - Ivan, my bro, for the support: https://github.com/ivn888 41 | 42 | - @RoySchutte (https://github.com/RoySchutte), for Dutch translations; 43 | 44 | - Vojt?ch Ho?ánek, @vojta-horanek (https://github.com/vojta-horanek) for Czech translations 45 | 46 | - @Primokorn (https://github.com/Primokorn) for French translations 47 | 48 | - https://materialdesignicons.com/ for icons 49 | 50 | - https://stackoverflow.com/ 51 | 52 | - http://dongerlist.com/?ref=producthunt for ascii 53 | 54 | 55 | **Resources used:** 56 | 57 | - AppCompat, RecyclerView, SupportPercent, Palette,Design by Google 58 | https://developer.android.com/topic/libraries/support-library/packages.html 59 | 60 | - Glide by @bumtech 61 | https://github.com/bumptech/glide 62 | 63 | - PhotoView by Chris Banes (@chrisbanes) 64 | https://github.com/chrisbanes/PhotoView 65 | 66 | - Easy Video Player by Aidan Follestad (@afollestad), https://github.com/afollestad/easy-video-player 67 | 68 | - Image Cropper by Arthur (@ArthurHub) 69 | https://github.com/ArthurHub/Android-Image-Cropper 70 | 71 | - Sectioned RecyclerView Adapter by Gustavo Pagani (@luizgrp) 72 | https://github.com/luizgrp/SectionedRecyclerViewAdapter 73 | 74 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/ApplyWallpaper.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.app.ProgressDialog; 5 | import android.app.WallpaperManager; 6 | import android.graphics.Bitmap; 7 | import android.net.Uri; 8 | import android.os.AsyncTask; 9 | import android.provider.MediaStore; 10 | 11 | import com.enrico.gallery.galleryapp.R; 12 | 13 | import java.io.File; 14 | import java.io.IOException; 15 | 16 | class ApplyWallpaper { 17 | 18 | static void execute(Activity activity, String url) { 19 | 20 | new applyWallpaper(activity, url).execute(); 21 | } 22 | 23 | private static class applyWallpaper extends AsyncTask { 24 | 25 | Activity activity; 26 | String url; 27 | ProgressDialog progressDialog; 28 | 29 | private applyWallpaper(Activity activity, String url) { 30 | this.activity = activity; 31 | this.url = url; 32 | } 33 | 34 | 35 | protected void onPreExecute() { 36 | 37 | progressDialog = new ProgressDialog(activity); 38 | progressDialog.setMessage(activity.getString(R.string.applying_wallpaper)); 39 | progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 40 | progressDialog.setIndeterminate(true); 41 | progressDialog.setProgressNumberFormat(null); 42 | progressDialog.setProgressPercentFormat(null); 43 | progressDialog.show(); 44 | } 45 | 46 | @Override 47 | protected Void doInBackground(Void... params) { 48 | 49 | try { 50 | 51 | final WallpaperManager wallpaperManager = WallpaperManager.getInstance(activity); 52 | 53 | Bitmap bitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), Uri.fromFile(new File(url))); 54 | 55 | wallpaperManager.setBitmap(bitmap); 56 | 57 | } catch (IOException ex) { 58 | ex.printStackTrace(); 59 | } 60 | 61 | return null; 62 | } 63 | 64 | @Override 65 | protected void onPostExecute(Void result) { 66 | progressDialog.dismiss(); 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/media_item.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | 15 | 16 | 22 | 23 | 38 | 39 | 53 | 54 | 55 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/MediaObserver.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp; 2 | 3 | import android.app.Activity; 4 | import android.content.ContentResolver; 5 | import android.database.ContentObserver; 6 | import android.net.Uri; 7 | import android.os.Handler; 8 | import android.provider.MediaStore; 9 | 10 | public class MediaObserver extends ContentObserver { 11 | 12 | private Activity activity; 13 | 14 | private MediaObserver(Handler mHandler, Activity activity) { 15 | 16 | super(mHandler); 17 | this.activity = activity; 18 | } 19 | 20 | static void removeContentObserver(Activity activity) { 21 | 22 | ContentResolver contentResolver = activity.getContentResolver(); 23 | 24 | contentResolver.unregisterContentObserver(new MediaObserver(new Handler(), activity)); 25 | 26 | } 27 | 28 | static void initContentObserver(Activity activity) { 29 | 30 | Uri externalImagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 31 | Uri internalImagesUri = MediaStore.Images.Media.INTERNAL_CONTENT_URI; 32 | Uri externalVideosUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 33 | Uri internalVideosUri = MediaStore.Video.Media.INTERNAL_CONTENT_URI; 34 | 35 | ContentResolver contentResolver = activity.getContentResolver(); 36 | 37 | contentResolver. 38 | registerContentObserver( 39 | externalImagesUri, 40 | true, 41 | new MediaObserver(new Handler(), activity)); 42 | 43 | contentResolver. 44 | registerContentObserver( 45 | internalImagesUri, 46 | true, 47 | new MediaObserver(new Handler(), activity)); 48 | 49 | contentResolver. 50 | registerContentObserver( 51 | externalVideosUri, 52 | true, 53 | new MediaObserver(new Handler(), activity)); 54 | 55 | contentResolver. 56 | registerContentObserver( 57 | internalVideosUri, 58 | true, 59 | new MediaObserver(new Handler(), activity)); 60 | } 61 | 62 | @Override 63 | public void onChange(boolean selfChange, Uri uri) { 64 | 65 | restart(activity); 66 | 67 | } 68 | 69 | public static void restart(Activity activity) { 70 | activity.finish(); 71 | activity.startActivity(MainActivity.starterIntent); 72 | activity.overridePendingTransition(0, 0); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /project/gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /project/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 31 | 32 | 33 | 34 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 55 | 56 | 61 | 62 | 63 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/settings/HiddenAlbumsAdapter.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.settings; 2 | 3 | import android.app.Activity; 4 | import android.support.v4.content.ContextCompat; 5 | import android.support.v7.widget.RecyclerView; 6 | import android.view.LayoutInflater; 7 | import android.view.View; 8 | import android.view.ViewGroup; 9 | import android.widget.TextView; 10 | 11 | import com.enrico.gallery.galleryapp.R; 12 | 13 | import java.util.ArrayList; 14 | 15 | class HiddenAlbumsAdapter extends RecyclerView.Adapter { 16 | 17 | private ArrayList hiddenFolders; 18 | private Activity activity; 19 | 20 | HiddenAlbumsAdapter(Activity activity, ArrayList hiddenFolders) { 21 | 22 | this.hiddenFolders = hiddenFolders; 23 | this.activity = activity; 24 | 25 | } 26 | 27 | @Override 28 | public SimpleViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { 29 | 30 | View itemView = LayoutInflater.from(parent.getContext()) 31 | .inflate(R.layout.hidden_item, parent, false); 32 | return new SimpleViewHolder(activity, itemView, hiddenFolders); 33 | } 34 | 35 | @Override 36 | public void onBindViewHolder(SimpleViewHolder holder, int position) { 37 | 38 | holder.textView.setText(hiddenFolders.get(position)); 39 | 40 | } 41 | 42 | @Override 43 | public int getItemCount() { 44 | 45 | return hiddenFolders.size(); 46 | } 47 | 48 | static class SimpleViewHolder extends RecyclerView.ViewHolder implements View.OnClickListener { 49 | 50 | static ArrayList visibleFolders; 51 | private TextView textView; 52 | private ArrayList hiddenFolders; 53 | 54 | private Activity activity; 55 | 56 | private int originalBgColor; 57 | 58 | SimpleViewHolder(Activity activity, View itemView, ArrayList hiddenFolders) { 59 | super(itemView); 60 | 61 | textView = (TextView) itemView.findViewById(R.id.hidden_folder); 62 | 63 | itemView.setOnClickListener(this); 64 | 65 | this.activity = activity; 66 | this.hiddenFolders = hiddenFolders; 67 | 68 | this.originalBgColor = itemView.getSolidColor(); 69 | 70 | visibleFolders = new ArrayList<>(); 71 | 72 | } 73 | 74 | @Override 75 | public void onClick(View v) { 76 | 77 | if (!itemView.isSelected()) { 78 | 79 | visibleFolders.add(hiddenFolders.get(getAdapterPosition())); 80 | 81 | v.setSelected(true); 82 | 83 | v.setBackgroundColor(ContextCompat.getColor(activity, R.color.material_green_a400)); 84 | 85 | } else { 86 | 87 | visibleFolders.remove(hiddenFolders.get(getAdapterPosition())); 88 | 89 | v.setSelected(false); 90 | 91 | v.setBackgroundColor(originalBgColor); 92 | } 93 | } 94 | } 95 | } -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/settings/HiddenFoldersDialog.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.settings; 2 | 3 | import android.app.Activity; 4 | import android.content.DialogInterface; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import android.support.v7.app.AlertDialog; 7 | import android.support.v7.widget.LinearLayoutManager; 8 | import android.support.v7.widget.RecyclerView; 9 | import android.view.View; 10 | import android.view.ViewGroup; 11 | 12 | import com.enrico.gallery.galleryapp.R; 13 | 14 | import java.util.ArrayList; 15 | 16 | import static android.content.Context.MODE_PRIVATE; 17 | 18 | class HiddenFoldersDialog { 19 | 20 | static void show(final Activity activity, final ArrayList list) { 21 | 22 | final ViewGroup nullParent = null; 23 | 24 | AlertDialog.Builder hiddenFoldersDialog = new AlertDialog.Builder(activity); 25 | 26 | View view = activity.getLayoutInflater().inflate(R.layout.hidden_albums_dialog, nullParent); 27 | hiddenFoldersDialog.setView(view); 28 | 29 | RecyclerView recyclerView = (RecyclerView) view.findViewById(R.id.recyclerView); 30 | 31 | recyclerView.setLayoutManager(new LinearLayoutManager(activity)); 32 | recyclerView.setHasFixedSize(true); 33 | 34 | HiddenAlbumsAdapter hiddenAlbumsAdapter = new HiddenAlbumsAdapter(activity, list); 35 | 36 | recyclerView.setAdapter(hiddenAlbumsAdapter); 37 | 38 | hiddenFoldersDialog 39 | .setTitle(R.string.hidden_title) 40 | .setCancelable(false) 41 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 42 | 43 | public void onClick(DialogInterface dialogBox, int id) { 44 | 45 | if (HiddenAlbumsAdapter.SimpleViewHolder.visibleFolders != null && HiddenAlbumsAdapter.SimpleViewHolder.visibleFolders.size() > 0) { 46 | for (String visibleFolders : HiddenAlbumsAdapter.SimpleViewHolder.visibleFolders) { 47 | 48 | SQLiteDatabase hiddenFoldersDB = activity.openOrCreateDatabase("HIDDEN", MODE_PRIVATE, null); 49 | 50 | hiddenFoldersDB.delete("foldersList", "folder" + "=?", new String[]{String.valueOf(visibleFolders)}); 51 | 52 | SettingsActivity.restartApp(activity); 53 | } 54 | } else { 55 | dialogBox.dismiss(); 56 | } 57 | } 58 | }) 59 | 60 | .setNegativeButton(android.R.string.cancel, 61 | new DialogInterface.OnClickListener() { 62 | public void onClick(DialogInterface dialogBox, int id) { 63 | dialogBox.dismiss(); 64 | } 65 | }); 66 | 67 | AlertDialog alertDialogAndroid = hiddenFoldersDialog.create(); 68 | alertDialogAndroid.show(); 69 | 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /project/app/src/main/res/values/arrays.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | @string/light 6 | @string/dark 7 | @string/red 8 | @string/red_dark 9 | @string/pink 10 | @string/pink_dark 11 | @string/purple 12 | @string/purple_dark 13 | @string/deepPurple 14 | @string/deepPurple_dark 15 | @string/indigo 16 | @string/indigo_dark 17 | @string/blue 18 | @string/blue_dark 19 | @string/lightBlue 20 | @string/lightBlue_dark 21 | @string/cyan 22 | @string/cyan_dark 23 | @string/teal 24 | @string/teal_dark 25 | @string/green 26 | @string/green_dark 27 | @string/lightGreen 28 | @string/lightGreen_dark 29 | @string/lime 30 | @string/lime_dark 31 | @string/yellow 32 | @string/yellow_dark 33 | @string/amber 34 | @string/amber_dark 35 | @string/orange 36 | @string/orange_dark 37 | @string/deepOrange 38 | @string/deepOrange_dark 39 | @string/brown 40 | @string/brown_dark 41 | @string/blueGrey 42 | @string/blueGrey_dark 43 | 44 | 45 | 46 | 47 | 0 48 | 1 49 | 2 50 | 3 51 | 4 52 | 5 53 | 6 54 | 7 55 | 8 56 | 9 57 | 10 58 | 11 59 | 12 60 | 13 61 | 14 62 | 15 63 | 16 64 | 17 65 | 18 66 | 19 67 | 20 68 | 21 69 | 22 70 | 23 71 | 24 72 | 25 73 | 26 74 | 27 75 | 28 76 | 29 77 | 30 78 | 31 79 | 32 80 | 33 81 | 34 82 | 35 83 | 36 84 | 37 85 | 86 | 87 | 88 | 89 | @string/two 90 | @string/three 91 | @string/four 92 | 93 | 94 | 38 95 | 39 96 | 40 97 | 98 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/InfoUtils.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.graphics.BitmapFactory; 5 | import android.media.MediaMetadataRetriever; 6 | import android.net.Uri; 7 | 8 | import com.enrico.gallery.galleryapp.R; 9 | 10 | import java.io.File; 11 | import java.text.DateFormat; 12 | import java.util.Date; 13 | import java.util.Locale; 14 | 15 | import static com.enrico.gallery.galleryapp.albums.HeaderRecyclerViewSection.stringContainsItemFromList; 16 | 17 | class InfoUtils { 18 | 19 | static String fileName(String url) { 20 | 21 | File file = new File(url); 22 | 23 | return file.getName(); 24 | } 25 | 26 | static String filePath(String url) { 27 | 28 | return url.replace(fileName(url), ""); 29 | } 30 | 31 | static String lastModifiedDate(String url) { 32 | 33 | File file = new File(url); 34 | 35 | Date date = new Date(file.lastModified()); 36 | 37 | DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.FULL, Locale.getDefault()); 38 | 39 | return dateFormat.format(date); 40 | } 41 | 42 | static double fileSize(String url) { 43 | 44 | File file = new File(url); 45 | 46 | return file.length(); 47 | } 48 | 49 | static String fileResolution(String url, int which) { 50 | 51 | String[] VIDEO_EXTENSIONS = {"mp4", "avi", "mpg", "mkv", "webm", "flv", 52 | "wmv", "mov", "qt", "m4p", "m4v", "mpeg", "mp2", 53 | "m2v", "3gp", "3g2", "f4v", "f4p", "f4a", "f4b"}; 54 | 55 | String resolution = ""; 56 | 57 | if (stringContainsItemFromList(url, VIDEO_EXTENSIONS)) { 58 | MediaMetadataRetriever retriever = new MediaMetadataRetriever(); 59 | retriever.setDataSource(url); 60 | 61 | int videoWidth = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_WIDTH)); 62 | int videoHeight = Integer.valueOf(retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_VIDEO_HEIGHT)); 63 | 64 | switch (which) { 65 | case 0: 66 | resolution = String.valueOf(videoWidth); 67 | break; 68 | case 1: 69 | resolution = String.valueOf(videoHeight); 70 | break; 71 | } 72 | 73 | retriever.release(); 74 | 75 | } else { 76 | 77 | Uri uri = Uri.parse(url); 78 | 79 | BitmapFactory.Options options = new BitmapFactory.Options(); 80 | options.inJustDecodeBounds = true; 81 | BitmapFactory.decodeFile(new File(uri.getPath()).getAbsolutePath(), options); 82 | int imageHeight = options.outHeight; 83 | int imageWidth = options.outWidth; 84 | 85 | switch (which) { 86 | case 0: 87 | resolution = String.valueOf(imageWidth); 88 | break; 89 | case 1: 90 | resolution = String.valueOf(imageHeight); 91 | break; 92 | } 93 | 94 | } 95 | 96 | return resolution; 97 | } 98 | 99 | static String fileType(Activity activity, String url) { 100 | 101 | String[] VIDEO_EXTENSIONS = {"mp4", "avi", "mpg", "mkv", "webm", "flv", 102 | "wmv", "mov", "qt", "m4p", "m4v", "mpeg", "mp2", 103 | "m2v", "3gp", "3g2", "f4v", "f4p", "f4a", "f4b"}; 104 | 105 | String fileType; 106 | 107 | if (stringContainsItemFromList(url, VIDEO_EXTENSIONS)) { 108 | 109 | String extensionType = activity.getString(R.string.videoType); 110 | 111 | String extension = url.substring(url.lastIndexOf(".")); 112 | 113 | fileType = extensionType + extension; 114 | 115 | } else { 116 | 117 | String extensionType = activity.getString(R.string.imageType); 118 | 119 | String extension = url.substring(url.lastIndexOf(".")); 120 | 121 | fileType = extensionType + extension; 122 | } 123 | 124 | return fileType; 125 | } 126 | } 127 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/MediaActivity.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.os.Parcelable; 7 | import android.support.v4.app.Fragment; 8 | import android.support.v4.app.FragmentManager; 9 | import android.support.v4.app.FragmentStatePagerAdapter; 10 | import android.support.v4.view.PagerAdapter; 11 | import android.support.v4.view.ViewPager; 12 | import android.support.v7.app.AppCompatActivity; 13 | import android.support.v7.view.ContextThemeWrapper; 14 | import android.widget.Toast; 15 | 16 | import com.enrico.gallery.galleryapp.settings.Preferences; 17 | import com.enrico.gallery.galleryapp.utils.SDCardUtils; 18 | 19 | public class MediaActivity extends AppCompatActivity { 20 | 21 | int pos; 22 | 23 | String[] mUrls; 24 | 25 | ContextThemeWrapper contextThemeWrapper; 26 | ViewPager pager; 27 | PagerAdapter mPagerAdapter; 28 | 29 | @Override 30 | protected void onCreate(Bundle savedInstanceState) { 31 | 32 | super.onCreate(savedInstanceState); 33 | 34 | Intent intent = getIntent(); 35 | 36 | mUrls = intent.getExtras().getStringArray("urls"); 37 | 38 | pos = intent.getExtras().getInt("pos"); 39 | 40 | runOnUiThread(new Runnable() { 41 | @Override 42 | public void run() { 43 | 44 | contextThemeWrapper = new ContextThemeWrapper(getBaseContext(), MediaActivity.this.getTheme()); 45 | 46 | Preferences.applyTheme(contextThemeWrapper, getBaseContext()); 47 | 48 | ImmersiveMode.On(MediaActivity.this); 49 | 50 | } 51 | }); 52 | 53 | setContentView(R.layout.media_activity); 54 | 55 | mPagerAdapter = new MyPagerAdapter(getSupportFragmentManager()); 56 | pager = (ViewPager) findViewById(R.id.pager); 57 | 58 | pager.setAdapter(mPagerAdapter); 59 | pager.setCurrentItem(pos); 60 | pager.setClipToPadding(false); 61 | } 62 | 63 | @Override 64 | public void onWindowFocusChanged(boolean hasFocus) { 65 | super.onWindowFocusChanged(hasFocus); 66 | if (hasFocus) { 67 | ImmersiveMode.On(this); 68 | } 69 | } 70 | 71 | @Override 72 | public void onResume() { 73 | super.onResume(); 74 | 75 | MediaObserver.initContentObserver(MediaActivity.this); 76 | 77 | } 78 | 79 | @Override 80 | public void onPause() { 81 | super.onPause(); 82 | 83 | MediaObserver.removeContentObserver(MediaActivity.this); 84 | } 85 | 86 | @Override 87 | protected void onActivityResult(int requestCode, int resultCode, Intent data) { 88 | super.onActivityResult(requestCode, resultCode, data); 89 | switch (requestCode) { 90 | case 2: 91 | if (resultCode == Activity.RESULT_OK) { 92 | 93 | SDCardUtils.saveSDCardUri(this, String.valueOf(data.getData())); 94 | 95 | Toast.makeText(this, getString(R.string.success), Toast.LENGTH_SHORT) 96 | .show(); 97 | 98 | } 99 | break; 100 | } 101 | } 102 | 103 | private class MyPagerAdapter extends FragmentStatePagerAdapter { 104 | 105 | MyPagerAdapter(FragmentManager fm) { 106 | 107 | super(fm); 108 | } 109 | 110 | @Override 111 | public Fragment getItem(int position) { 112 | 113 | MediaPagerFragment frag = new MediaPagerFragment(); 114 | 115 | Bundle bundle = new Bundle(); 116 | 117 | bundle.putStringArray("urls", mUrls); 118 | bundle.putInt("pos", position); 119 | 120 | frag.setArguments(bundle); 121 | 122 | return frag; 123 | } 124 | 125 | @Override 126 | public int getCount() { 127 | return mUrls.length; 128 | } 129 | 130 | @Override 131 | public Parcelable saveState() { 132 | Bundle bundle = (Bundle) super.saveState(); 133 | bundle.putParcelableArray("states", null); 134 | return bundle; 135 | } 136 | } 137 | } 138 | 139 | 140 | -------------------------------------------------------------------------------- /project/app/src/main/res/values-nl/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Galerij 3 | Opties 4 | Aantal kolommen 5 | Wijzig het aantal album kolommen 6 | 2 kolommen 7 | 3 kolommen 8 | 4 kolommen 9 | App thema 10 | Ochtend, nacht of…? 11 | Licht 12 | Donker 13 | Rood 14 | Roze 15 | Paars 16 | Dieppaars 17 | Indigo 18 | Blauw 19 | Lichtblauw 20 | Cyaan 21 | Blauwgroen 22 | Groen 23 | Lichtgroen 24 | Limoen 25 | Geel 26 | Amber 27 | Oranje 28 | Dieporanje 29 | Bruin 30 | Blauwgrijs 31 | Donkerrood 32 | Donkerroze 33 | Donkerpaars 34 | Diepdonkerpaars 35 | Donkerindigo 36 | Donkerblauw 37 | Lichtdonkerblauw 38 | Donkercyaan 39 | Donkerblauwgroen 40 | Donkergroen 41 | Lichtdonkergroen 42 | Donkerlimoen 43 | Donkergeel 44 | Donkeramber 45 | Donkeroranje 46 | Diepdonkeroranje 47 | Donkerbruin 48 | Donkerblauwgrijs 49 | Bestand niet gevonden (╯°□°)╯︵ ┻━┻. Ik ben het SD-kaart pad vergeten! 50 | Zeker weten? (Ծ‸ Ծ) 51 | Weet je zeker dat je  wilt verwijderen? 52 |  ? 53 | Verwijderen 54 | SD-kaart toegang 55 | Je apparaat draait Android 5.0+. Om betstanden op de externe opslag te bewerken, gelieve het externe SD-kaart pad op te geven in de volgende stap ᕙ༼ຈل͜ຈ༽ᕗ 56 | SD-kaart pad succesvol ingesteld. Je kunt nu bestanden verwijderen (⌐■_■) 57 | Deze permissie is vereist als je de camera wilt openen ಠ_ಠ 58 | Deze permissie is vereist als je hier jouw &#$# selfie wilt zien ◔_◔ 59 |  opgeslagen (。◕‿◕。) 60 | Delen via… 61 | Grootte:  62 | Hoogte:  63 | Breedte:  64 | Bestandsnaam:  65 | Bestandstype:  66 | Pad:  67 | Laatst aangepast:  68 | Video/ 69 | Afbeelding/ 70 | Instellen als achtergrond 71 | Zeker weten? (ಥ_ʖಥ) 72 | Weet je zeker dat je  wilt verbergen? 73 | Verbergen 74 | Verborgen albums 75 | Beheer verborgen albums 76 | Tik op de map om het weer zichtbaar te maken. Tik ok om te bevestigen ٩(◕‿◕。)۶ 77 | 78 | -------------------------------------------------------------------------------- /project/app/src/main/res/values-cs/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 |     Galerie 4 |     Možnosti 5 |     Počet sloupců 6 |     Změňte počet sloupců v albu 7 |     2 sloupce 8 |     3 sloupce 9 |     4 sloupce 10 |     Vzhled aplikace 11 |     Ráno, noc nebo…? 12 |     Světlý 13 |     Tmavý 14 |     Červený 15 |     Růžový 16 |     Fialový 17 |     Tmavě fialová 18 |     Indigová 19 |     Modrá 20 |     Světle modrá 21 |     Tyrkysová 22 |     Tealová 23 |     Zelená 24 |     Světle zelená 25 |     Limetková 26 |     Žlutá 27 |     Jantarová 28 |     Oranžová 29 |     Tmavě oranžová 30 |     Hnědá 31 |     Šedě modrá 32 |     Červená noc 33 |     Růžová noc 34 |     Fialová noc 35 |     Tmavě fialová noc 36 |     Indigová noc 37 |     Modrá noc 38 |     Světle modrá noc 39 |     Tyrkysová noc 40 |     Tealová noc 41 |     Zelená noc 42 |     Světle zelená noc 43 |     Limetková noc 44 |     Žlutá noc 45 |     Jantarová noc 46 |     Oranžová noc 47 |     Tmavě oranžová noc 48 |     Hnědá noc 49 |     Šedě modrá noc 50 |     Soubor nenalezen (╯°□°)╯︵ ┻━┻. Zapomněl jsem cestu k SD kartě! 51 |     Jsi si jistej? (Ծ‸ Ծ) 52 |     Vážně chceš smazat  53 |      ? 54 |     Smazat 55 |     Přístup k SD kartě 56 |     Vaše zařízení běží na androidu 5.0+, aby jste mohly editovat soubory na externí SD kartě, řekněte mi prosím cestu k vaší externí SD kartě v dalším kroku ᕙ༼ຈل͜ຈ༽ᕗ 57 |     Úspěch! Podařilo se získat cestu k SD kartě, nyní můžete mazat soubory (⌐■_■) 58 |     Toto oprávnění je potřeba aby jste mohli používat kameru ಠ_ಠ 59 |     Toto oprávnění je potřeba pokud zde checete vidět vaší selfie ◔_◔ 60 |     Uloženo:   (。◕‿◕。) 61 |     Sdílet pomocí … 62 |     Velikost:  63 |     Výška:  64 |     Šířka:  65 |     Název souboru:  66 |     Typ souboru:  67 |     Cesta:  68 |     Naposledy upraveno:  69 |     Video/ 70 |     Obrázek/ 71 |     Nastavit jako tapetu 72 |     Seš si jist? (ಥ_ʖಥ) 73 |     Vážně chceš skrýt   74 |     Skrýt 75 |     Skrytá alba 76 |     Spravovat skrytá alba 77 |     Vyber složky které chceš udělat znova viditelnými. Potom stiskni OK pro potvrzení ٩(◕‿◕。)۶ 78 |     Ukládání ořezu nejspíš bude potřebovat čas. Pokud chcete aby práce byla provedena na pozadí, dotkněte se mimo dialog. 79 |     Nastavování pozadí nejspíš bude potřebovat čas. Pokud chcete aby práce byla provedena na pozadí, dotkněte se mimo dialog 80 | 81 | 82 | 83 | -------------------------------------------------------------------------------- /project/app/src/main/res/values-it/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Galleria 3 | 4 | Opzioni 5 | 6 | Numero colonne 7 | Cambia il numero delle colonne degli album 8 | 2 colonne 9 | 3 colonne 10 | 4 colonne 11 | Tema app 12 | Giorno, notte o…? 13 | Giorno 14 | Notte 15 | Rosso 16 | Rosa 17 | Viola 18 | Viola scuro 19 | Indaco 20 | Blu 21 | Blu chiaro 22 | Ciano 23 | Alzavola 24 | Verde 25 | Verde chiaro 26 | Lime 27 | Giallo 28 | Ambra 29 | Arancio 30 | Arancio scuro 31 | Marrone 32 | Grigio blu 33 | Rosso notte 34 | Rosa notte 35 | Viola notte 36 | Viola scuro notte 37 | Indaco notte 38 | Blu notte 39 | Blu chiaro notte 40 | Ciano notte 41 | Alzavola notte 42 | Verde notte 43 | Verde chiaro notte 44 | Lime notte 45 | Giallo notte 46 | Ambra notte 47 | Arancio notte 48 | Arancio scuro notte 49 | Marrone notte 50 | Grigio blu notte 51 | Dimensione:  52 | Altezza:  53 | Larghezza:  54 | Nome:  55 | Tipo file:  56 | Percorso:  57 | Ultima modifica:  58 | Video/ 59 | Immagine/ 60 | File non trovato (╯°□°)╯︵ ┻━┻. Ho dimenticato il percorso della SD Card! 61 | Sicuro? (Ծ‸ Ծ) 62 | Sicuro vuoi cancellare  63 |  ? 64 | Cancella 65 | Accesso SD Card 66 | Il tuo dispositivo ha una versione di Android 5.0+, per modificare i files sulla SD Card per favore indicaci il suo percorso nella prossima schermata ᕙ༼ຈل͜ຈ༽ᕗ 67 | Percorso SD card impostato con successo. Ora puoi cancellare i file (⌐■_■) 68 | Questo permesso è necessario per aprire la camera ಠ_ಠ 69 | Questo permesso è necessario se vuoi vedere i tuoi &#$# selfie qui ◔_◔ 70 |  salvata (。◕‿◕。) 71 | Condividi usando… 72 | Imposta come wallpaper 73 | Sicuro? (ಥ_ʖಥ) 74 | Sicuro vuoi nascondere  75 | Nascondi 76 | Album nascosti 77 | Gestisci gli album nascosti 78 | Clicca le cartelle che vuoi rendere di nuovo visibili. Clicca OK per confermare ٩(◕‿◕。)۶ 79 | Il salvataggio di un ritaglio può richiedere tempo. Tocca al di fuori del dialog per chiudere, il lavoro continuerà in background 80 | L\'applicazione di uno sfondo può richiedere tempo. Tocca al di fuori del dialog per chiudere, il lavoro continuerà in background 81 | Cancellazione in corso… 82 | 83 | 84 | -------------------------------------------------------------------------------- /project/app/src/main/res/values-fr/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Gallery 3 | Options 4 | Nombre de colonnes 5 | Changer le nombre de colonnes des albums 6 | 2 colonnes 7 | 3 colonnes 8 | 4 colonnes 9 | Thème 10 | Matin, nuit ou…? 11 | Clair 12 | Sombre 13 | Rouge 14 | Rose 15 | Violet 16 | Violet foncé 17 | Indigo 18 | Bleu 19 | Bleu clair 20 | Cyan 21 | Turquoise 22 | Vert 23 | Vert clair 24 | Citron vert 25 | Jaune 26 | Ambre 27 | Orange 28 | Orange foncé 29 | Marron 30 | Bleu gris 31 | Rouge nuit 32 | Rose nuit 33 | Violet nuit 34 | Violet foncé nuit 35 | Indigo nuit 36 | Bleu nuit 37 | Bleu clair nuit 38 | Cyan nuit 39 | Turquoise nuit 40 | Vert nuit 41 | Vert clair nuit 42 | Citron vert nuit 43 | Jaune nuit 44 | Ambre nuit 45 | Orange nuit 46 | Orange foncé nuit 47 | Marron nuit 48 | Bleu gris nuit 49 | Fichier non trouvé not found (╯°□°)╯︵ ┻━┻. J\'ai oublié l\'emplacement SD Card ! 50 | Vous êtes sûr•e ? (Ծ‸ Ծ) 51 | Vous êtes sûr•e de vouloir supprimer  52 |  ? 53 | Supprimer 54 | Accès SD Card 55 | Votre appareil est basé sur Android 5.0+, pour modifier des fichiers sur la SD Card exrerne, veuillez indiquer son emplacement lors de la prochaine étape ᕙ༼ຈل͜ຈ༽ᕗ 56 | Emplacement SD Card défini avec succès. Maintenant vous pouvez supprimer des fichiers (⌐■_■) 57 | Cette permission est requis si vous voulez ouvrir l\'appareil photo ಠ_ಠ 58 | Cette permission est requis si vous voulez voir vos selfies &#$# ici ◔_◔ 59 |  saved (。◕‿◕。) 60 | Partager via… 61 | Taille :  62 | Hauteur :  63 | Largeur :  64 | Nom fichier :  65 | Type fichier :  66 | Emplacement :  67 | Dernière modification :  68 | Vidéo/ 69 | Image/ 70 | Définir comme fond d\'écran 71 | Vous êtes sûr•e ? (ಥ_ʖಥ) 72 | Vous êtes sûr•e de vouloir cacher  73 | Cacher 74 | Albums cachés 75 | Gérer les albums cachés 76 | Appuyez sur le•s dossier•s que vous souhaitez rendre à nouveau visible•s. OK pour valider ٩(◕‿◕。)۶ 77 | Enregistrer un recadrage peut demander du temps. Appuyez en dehors du message pour annuler, la tâche sera effectuée en arrière-plan 78 | Appliquer un fond d\'écran peut demander du temps. Appuyez en dehors du message pour annuler, la tâche sera effectuée en arrière-plan 79 | 80 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/PermissionUtils.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.Manifest; 4 | import android.annotation.TargetApi; 5 | import android.app.Activity; 6 | import android.content.DialogInterface; 7 | import android.content.Intent; 8 | import android.content.pm.PackageManager; 9 | import android.provider.Settings; 10 | import android.support.v7.app.AlertDialog; 11 | import android.text.Html; 12 | import android.text.Spanned; 13 | import android.text.method.LinkMovementMethod; 14 | import android.view.LayoutInflater; 15 | import android.view.View; 16 | import android.view.ViewGroup; 17 | import android.widget.TextView; 18 | 19 | import com.enrico.gallery.galleryapp.R; 20 | 21 | import static android.content.Context.LAYOUT_INFLATER_SERVICE; 22 | 23 | public class PermissionUtils { 24 | 25 | @SuppressWarnings("deprecation") 26 | private static Spanned Linkify(String policy) { 27 | 28 | Spanned result; 29 | if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.N) { 30 | result = Html.fromHtml(policy, Html.FROM_HTML_MODE_LEGACY); 31 | } else { 32 | result = Html.fromHtml(policy); 33 | } 34 | return result; 35 | } 36 | 37 | public static void rationaleDialog(final Activity activity, String title, String rationale, final int requestCode, final Intent intent) { 38 | 39 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( 40 | activity); 41 | 42 | alertDialogBuilder.setTitle(title); 43 | 44 | if (requestCode == 1) { 45 | 46 | String policyLink = "Policy link"; 47 | 48 | LayoutInflater inflater = (LayoutInflater) activity.getSystemService(LAYOUT_INFLATER_SERVICE); 49 | final ViewGroup nullParent = null; 50 | 51 | View layout = inflater.inflate(R.layout.camera_permission_dialog, nullParent); 52 | 53 | TextView rationaleText = (TextView) layout.findViewById(R.id.rationale); 54 | 55 | rationaleText.setText(rationale); 56 | 57 | TextView policyText = (TextView) layout.findViewById(R.id.policy); 58 | 59 | policyText.setMovementMethod(LinkMovementMethod.getInstance()); 60 | 61 | policyText.setText(Linkify(policyLink)); 62 | alertDialogBuilder.setView(layout); 63 | 64 | 65 | } else { 66 | alertDialogBuilder.setMessage(rationale); 67 | } 68 | 69 | alertDialogBuilder 70 | .setCancelable(false) 71 | 72 | .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() { 73 | public void onClick(DialogInterface dialog, int id) { 74 | 75 | switch (requestCode) { 76 | case 0: 77 | askReadWriteAccess(activity); 78 | break; 79 | case 1: 80 | askCameraAccess(activity, intent); 81 | //camera 82 | break; 83 | 84 | case 2: 85 | 86 | activity.startActivityForResult(intent, 2); 87 | break; 88 | } 89 | 90 | } 91 | }); 92 | 93 | AlertDialog alertDialog = alertDialogBuilder.create(); 94 | 95 | alertDialog.show(); 96 | 97 | } 98 | 99 | @TargetApi(23) 100 | public static void askReadWriteAccess(Activity activity) { 101 | 102 | if (!Settings.System.canWrite(activity)) { 103 | 104 | activity.requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, 105 | Manifest.permission.READ_EXTERNAL_STORAGE}, 0); 106 | 107 | } 108 | } 109 | 110 | @TargetApi(23) 111 | public static void askCameraAccess(Activity activity, Intent intent) { 112 | 113 | if (activity.checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) { 114 | activity.startActivity(intent); 115 | 116 | } else { 117 | 118 | activity.requestPermissions(new String[]{Manifest.permission.CAMERA}, 1); 119 | } 120 | } 121 | 122 | static void askSDCardAccess(final Activity activity) { 123 | 124 | activity.runOnUiThread(new Runnable() { 125 | @Override 126 | public void run() { 127 | if (SDCardUtils.getSDCardUri(activity).isEmpty()) { 128 | 129 | Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 130 | 131 | rationaleDialog(activity, activity.getString(R.string.sdcard), activity.getString(R.string.sdcardContent), 2, intent); 132 | 133 | } 134 | } 135 | }); 136 | 137 | } 138 | 139 | } 140 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/SaveTools.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.app.ProgressDialog; 5 | import android.content.Context; 6 | import android.content.Intent; 7 | import android.content.SharedPreferences; 8 | import android.graphics.Bitmap; 9 | import android.net.Uri; 10 | import android.os.AsyncTask; 11 | import android.os.Environment; 12 | import android.provider.MediaStore; 13 | import android.widget.Toast; 14 | 15 | import com.enrico.gallery.galleryapp.R; 16 | 17 | import java.io.ByteArrayOutputStream; 18 | import java.io.File; 19 | import java.io.FileOutputStream; 20 | import java.io.IOException; 21 | 22 | public class SaveTools { 23 | 24 | private static boolean dir_exists(String dir_path) { 25 | boolean ret = false; 26 | File dir = new File(dir_path); 27 | if (dir.exists() && dir.isDirectory()) 28 | ret = true; 29 | return ret; 30 | } 31 | 32 | private static File saveImage(Bitmap bmp, final String fileName, final Activity activity) throws IOException { 33 | 34 | ByteArrayOutputStream bytes = new ByteArrayOutputStream(); 35 | 36 | bmp.compress(Bitmap.CompressFormat.PNG, 100, bytes); 37 | 38 | String dir_path = Environment.getExternalStorageDirectory() + File.separator + "GalleryCropShit"; 39 | 40 | if (!dir_exists(dir_path)) { 41 | File directory = new File(dir_path); 42 | boolean makeDir = directory.mkdirs(); 43 | } 44 | 45 | File f; 46 | 47 | 48 | f = new File(dir_path + File.separator 49 | 50 | + fileName); 51 | 52 | FileOutputStream fo = new FileOutputStream(f); 53 | fo.write(bytes.toByteArray()); 54 | fo.close(); 55 | 56 | notifyChange(f, activity); 57 | 58 | return f; 59 | } 60 | 61 | private static void notifyChange(File f, Activity activity) { 62 | 63 | Intent mediaScannerIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE); 64 | Uri fileContentUri = Uri.fromFile(f); 65 | mediaScannerIntent.setData(fileContentUri); 66 | activity.sendBroadcast(mediaScannerIntent); 67 | } 68 | 69 | private static void setLastInt(Activity activity, int lastInt) { 70 | 71 | SharedPreferences preferenceName; 72 | preferenceName = activity.getSharedPreferences("int", Context.MODE_PRIVATE); 73 | 74 | 75 | preferenceName.edit() 76 | .clear() 77 | .apply(); 78 | 79 | preferenceName.edit() 80 | .putInt("lastInt", lastInt) 81 | .apply(); 82 | } 83 | 84 | private static int getLastInt(Activity activity) { 85 | 86 | SharedPreferences preferenceName = activity.getSharedPreferences("int", Context.MODE_PRIVATE); 87 | 88 | return preferenceName.getInt("lastInt", 0); 89 | } 90 | 91 | public static void saveCrop(Activity activity, Uri uri, String url) { 92 | 93 | new saveCropImage(activity, uri, url).execute(); 94 | } 95 | 96 | private static class saveCropImage extends AsyncTask { 97 | 98 | Activity activity; 99 | Uri uri; 100 | String url; 101 | Bitmap bitmap; 102 | ProgressDialog progressDialog; 103 | int count; 104 | String name; 105 | String fileNameWithoutExt; 106 | String fileName; 107 | 108 | private saveCropImage(Activity activity, Uri uri, String url) { 109 | this.activity = activity; 110 | this.uri = uri; 111 | this.url = url; 112 | } 113 | 114 | 115 | protected void onPreExecute() { 116 | count = getLastInt(activity) + 1; 117 | progressDialog = new ProgressDialog(activity); 118 | progressDialog.setMessage(activity.getString(R.string.saving_crop)); 119 | progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 120 | progressDialog.setIndeterminate(true); 121 | progressDialog.setProgressNumberFormat(null); 122 | progressDialog.setProgressPercentFormat(null); 123 | progressDialog.show(); 124 | } 125 | 126 | @Override 127 | protected Void doInBackground(Void... params) { 128 | 129 | name = url.substring(url.lastIndexOf('/') + 1, url.length()); 130 | 131 | fileNameWithoutExt = name.substring(0, name.lastIndexOf('.')); 132 | 133 | fileName = fileNameWithoutExt + "_crop_" + count + ".png"; 134 | 135 | try { 136 | 137 | bitmap = MediaStore.Images.Media.getBitmap(activity.getContentResolver(), uri); 138 | 139 | SaveTools.saveImage(bitmap, fileName, activity); 140 | 141 | } catch (IOException ex) { 142 | ex.printStackTrace(); 143 | } 144 | 145 | return null; 146 | } 147 | 148 | @Override 149 | protected void onPostExecute(Void result) { 150 | 151 | progressDialog.dismiss(); 152 | 153 | Toast.makeText(activity, fileName + activity.getString(R.string.saved), Toast.LENGTH_SHORT) 154 | .show(); 155 | 156 | setLastInt(activity, count); 157 | } 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/settings/SettingsActivity.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.settings; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.content.SharedPreferences; 6 | import android.database.Cursor; 7 | import android.database.sqlite.SQLiteDatabase; 8 | import android.os.Bundle; 9 | import android.preference.Preference; 10 | import android.preference.PreferenceFragment; 11 | import android.preference.PreferenceScreen; 12 | import android.support.v4.content.IntentCompat; 13 | import android.support.v7.app.AppCompatActivity; 14 | import android.support.v7.view.ContextThemeWrapper; 15 | import android.support.v7.widget.Toolbar; 16 | import android.view.View; 17 | 18 | import com.enrico.gallery.galleryapp.MainActivity; 19 | import com.enrico.gallery.galleryapp.R; 20 | 21 | import java.util.ArrayList; 22 | 23 | public class SettingsActivity extends AppCompatActivity { 24 | 25 | ContextThemeWrapper contextThemeWrapper; 26 | 27 | static void restartApp(Activity activity) { 28 | Intent newIntent = new Intent(activity, MainActivity.class); 29 | newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | IntentCompat.FLAG_ACTIVITY_CLEAR_TASK); 30 | activity.startActivity(newIntent); 31 | activity.overridePendingTransition(0, 0); 32 | activity.finish(); 33 | } 34 | 35 | @Override 36 | public void onCreate(Bundle savedInstanceState) { 37 | 38 | super.onCreate(savedInstanceState); 39 | 40 | contextThemeWrapper = new ContextThemeWrapper(getBaseContext(), this.getTheme()); 41 | Preferences.applyTheme(contextThemeWrapper, getBaseContext()); 42 | 43 | setContentView(R.layout.preference_activity); 44 | 45 | Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar); 46 | setSupportActionBar(toolbar); 47 | 48 | if (getSupportActionBar() != null) { 49 | getSupportActionBar().setDisplayHomeAsUpEnabled(true); 50 | } 51 | 52 | toolbar.setNavigationOnClickListener(new View.OnClickListener() { 53 | @Override 54 | public void onClick(View v) { 55 | onBackPressed(); 56 | overridePendingTransition(0, 0); 57 | } 58 | }); 59 | 60 | if (getFragmentManager().findFragmentById(R.id.content_frame) == null) { 61 | getFragmentManager().beginTransaction().replace(R.id.content_frame, new SettingsFragment()).commit(); 62 | } 63 | } 64 | 65 | public static class SettingsFragment extends PreferenceFragment { 66 | 67 | private SharedPreferences.OnSharedPreferenceChangeListener mListenerOptions; 68 | 69 | @Override 70 | public void onCreate(Bundle savedInstanceState) { 71 | super.onCreate(savedInstanceState); 72 | 73 | addPreferencesFromResource(R.xml.prefs); 74 | 75 | PreferenceScreen preferenceScreen = getPreferenceScreen(); 76 | 77 | Preference hiddenFolders = findPreference("hiddenFolders"); 78 | 79 | SQLiteDatabase hiddenFoldersDB = getActivity().openOrCreateDatabase("HIDDEN", MODE_PRIVATE, null); 80 | 81 | final ArrayList mHiddenFolders = new ArrayList<>(); 82 | 83 | Cursor cursor = hiddenFoldersDB.rawQuery("SELECT * FROM foldersList;", null); 84 | 85 | if (cursor != null && cursor.moveToFirst()) { 86 | 87 | while (!cursor.isAfterLast()) { 88 | 89 | mHiddenFolders.add(cursor.getString(cursor.getColumnIndex("folder"))); 90 | cursor.moveToNext(); 91 | } 92 | cursor.close(); 93 | } 94 | 95 | 96 | if (mHiddenFolders.size() != 0) { 97 | 98 | preferenceScreen.addPreference(hiddenFolders); 99 | 100 | hiddenFolders.setOnPreferenceClickListener(new Preference.OnPreferenceClickListener() { 101 | @Override 102 | public boolean onPreferenceClick(Preference preference) { 103 | 104 | HiddenFoldersDialog.show(getActivity(), mHiddenFolders); 105 | 106 | return false; 107 | } 108 | }); 109 | } else { 110 | preferenceScreen.removePreference(hiddenFolders); 111 | } 112 | 113 | 114 | mListenerOptions = new SharedPreferences.OnSharedPreferenceChangeListener() { 115 | @Override 116 | public void onSharedPreferenceChanged(SharedPreferences preftheme, String key) { 117 | 118 | if (key.equals(getResources().getString(R.string.pref_theme)) | key.equals(getResources().getString(R.string.pref_grid))) { 119 | 120 | restartApp(getActivity()); 121 | } 122 | } 123 | }; 124 | 125 | 126 | } 127 | 128 | @Override 129 | public void onResume() { 130 | super.onResume(); 131 | 132 | getPreferenceManager().getSharedPreferences().registerOnSharedPreferenceChangeListener(mListenerOptions); 133 | } 134 | 135 | @Override 136 | public void onPause() { 137 | getPreferenceManager().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(mListenerOptions); 138 | super.onPause(); 139 | } 140 | } 141 | } -------------------------------------------------------------------------------- /project/gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # Attempt to set APP_HOME 46 | # Resolve links: $0 may be a link 47 | PRG="$0" 48 | # Need this for relative symlinks. 49 | while [ -h "$PRG" ] ; do 50 | ls=`ls -ld "$PRG"` 51 | link=`expr "$ls" : '.*-> \(.*\)$'` 52 | if expr "$link" : '/.*' > /dev/null; then 53 | PRG="$link" 54 | else 55 | PRG=`dirname "$PRG"`"/$link" 56 | fi 57 | done 58 | SAVED="`pwd`" 59 | cd "`dirname \"$PRG\"`/" >/dev/null 60 | APP_HOME="`pwd -P`" 61 | cd "$SAVED" >/dev/null 62 | 63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 64 | 65 | # Determine the Java command to use to start the JVM. 66 | if [ -n "$JAVA_HOME" ] ; then 67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 68 | # IBM's JDK on AIX uses strange locations for the executables 69 | JAVACMD="$JAVA_HOME/jre/sh/java" 70 | else 71 | JAVACMD="$JAVA_HOME/bin/java" 72 | fi 73 | if [ ! -x "$JAVACMD" ] ; then 74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 75 | 76 | Please set the JAVA_HOME variable in your environment to match the 77 | location of your Java installation." 78 | fi 79 | else 80 | JAVACMD="java" 81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 82 | 83 | Please set the JAVA_HOME variable in your environment to match the 84 | location of your Java installation." 85 | fi 86 | 87 | # Increase the maximum file descriptors if we can. 88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 89 | MAX_FD_LIMIT=`ulimit -H -n` 90 | if [ $? -eq 0 ] ; then 91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 92 | MAX_FD="$MAX_FD_LIMIT" 93 | fi 94 | ulimit -n $MAX_FD 95 | if [ $? -ne 0 ] ; then 96 | warn "Could not set maximum file descriptor limit: $MAX_FD" 97 | fi 98 | else 99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 100 | fi 101 | fi 102 | 103 | # For Darwin, add options to specify how the application appears in the dock 104 | if $darwin; then 105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 106 | fi 107 | 108 | # For Cygwin, switch paths to Windows format before running java 109 | if $cygwin ; then 110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 112 | JAVACMD=`cygpath --unix "$JAVACMD"` 113 | 114 | # We build the pattern for arguments to be converted via cygpath 115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 116 | SEP="" 117 | for dir in $ROOTDIRSRAW ; do 118 | ROOTDIRS="$ROOTDIRS$SEP$dir" 119 | SEP="|" 120 | done 121 | OURCYGPATTERN="(^($ROOTDIRS))" 122 | # Add a user-defined pattern to the cygpath arguments 123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 125 | fi 126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 127 | i=0 128 | for arg in "$@" ; do 129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 131 | 132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 134 | else 135 | eval `echo args$i`="\"$arg\"" 136 | fi 137 | i=$((i+1)) 138 | done 139 | case $i in 140 | (0) set -- ;; 141 | (1) set -- "$args0" ;; 142 | (2) set -- "$args0" "$args1" ;; 143 | (3) set -- "$args0" "$args1" "$args2" ;; 144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 150 | esac 151 | fi 152 | 153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 154 | function splitJvmOpts() { 155 | JVM_OPTS=("$@") 156 | } 157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 159 | 160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 161 | -------------------------------------------------------------------------------- /project/app/src/main/res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | Gallery 3 | Options 4 | 5 | Columns number 6 | Change the album\'s number of columns 7 | pref_grid 8 | pref_grid_list 9 | 2 columns 10 | 3 columns 11 | 4 columns 12 | 13 | App theme 14 | Morning, night or…? 15 | pref_theme 16 | pref_theme_list 17 | Light 18 | Dark 19 | 20 | Red 21 | Pink 22 | Purple 23 | Deep purple 24 | Indigo 25 | Blue 26 | Light blue 27 | Cyan 28 | Teal 29 | Green 30 | Light green 31 | Lime 32 | Yellow 33 | Amber 34 | Orange 35 | Deep orange 36 | Brown 37 | Blue grey 38 | Red night 39 | Pink night 40 | Purple night 41 | Deep purple night 42 | Indigo night 43 | Blue night 44 | Light blue night 45 | Cyan night 46 | Teal night 47 | Green night 48 | Light green night 49 | Lime night 50 | Yellow night 51 | Amber night 52 | Orange night 53 | Deep orange night 54 | Brown night 55 | Blue grey night 56 | 57 | File not found (╯°□°)╯︵ ┻━┻. I forgot the SD Card path! 58 | U sure? (Ծ‸ Ծ) 59 | U sure u want to delete  60 |  ? 61 | Delete 62 | 63 | SD Card access 64 | Your device is running Android 5.0+, to edit files on external SD Card please tell us the external SD Card path on the phone in the next step ᕙ༼ຈل͜ຈ༽ᕗ 65 | Successfully set SD Card path. Now you can delete files (⌐■_■) 66 | This permission is needed if You want to open camera ಠ_ಠ 67 | (ಥ﹏ಥ) 68 | щ(゚Д゚щ) 69 | This permission is needed if You want to see Your &#$# selfie here ◔_◔ 70 | 71 |  saved (。◕‿◕。) 72 | 73 | Share using… 74 | 75 | Size:  76 | Height:  77 | Width:  78 | Filename:  79 | File type:  80 | Path:  81 | Last modified:  82 | 83 | Video/ 84 | Image/ 85 | 86 | B 87 | KB  88 | MB  89 | GB  90 | 91 | ) 92 |  ( 93 | 94 | Set as wallpaper 95 | 96 | U sure? (ಥ_ʖಥ) 97 | U sure u want to hide  98 | Hide 99 | Hidden albums 100 | Manage hidden albums 101 | Click on folders You want make visible again. Click OK to confirm ٩(◕‿◕。)۶ 102 | 103 | Saving a crop may require time. Touch outside the dialog to dismiss, the work will be done in background 104 | Applying a wallpaper may require time. Touch outside the dialog to dismiss, the work will be done in background 105 | Deleting… 106 | 107 | 108 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/settings/Preferences.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.settings; 2 | 3 | import android.app.Activity; 4 | import android.content.Context; 5 | import android.preference.PreferenceManager; 6 | import android.support.v7.view.ContextThemeWrapper; 7 | 8 | import com.enrico.gallery.galleryapp.R; 9 | 10 | public class Preferences { 11 | 12 | private static int resolveTheme(Context context) { 13 | 14 | int light = R.style.Base_Theme; 15 | int dark = R.style.Base_Theme_Dark; 16 | int red = R.style.Base_Theme_Red; 17 | int nightRed = R.style.Base_Theme_Dark_Red; 18 | int pink = R.style.Base_Theme_Pink; 19 | int nightPink = R.style.Base_Theme_Dark_Pink; 20 | int purple = R.style.Base_Theme_Purple; 21 | int nightPurple = R.style.Base_Theme_Dark_Purple; 22 | int deepPurple = R.style.Base_Theme_DeepPurple; 23 | int nightDeepPurple = R.style.Base_Theme_Dark_DeepPurple; 24 | int indigo = R.style.Base_Theme_Indigo; 25 | int nightIndigo = R.style.Base_Theme_Dark_Indigo; 26 | int blue = R.style.Base_Theme_Blue; 27 | int nightBlue = R.style.Base_Theme_Dark_Blue; 28 | int lightBlue = R.style.Base_Theme_LightBlue; 29 | int nightLightBlue = R.style.Base_Theme_Dark_LightBlue; 30 | int cyan = R.style.Base_Theme_Cyan; 31 | int nightCyan = R.style.Base_Theme_Dark_Cyan; 32 | int teal = R.style.Base_Theme_Teal; 33 | int nightTeal = R.style.Base_Theme_Dark_Teal; 34 | int green = R.style.Base_Theme_Green; 35 | int nightGreen = R.style.Base_Theme_Dark_Green; 36 | int lightGreen = R.style.Base_Theme_LightGreen; 37 | int nightLightGreen = R.style.Base_Theme_Dark_LightGreen; 38 | int lime = R.style.Base_Theme_Lime; 39 | int nightLime = R.style.Base_Theme_Dark_Lime; 40 | int yellow = R.style.Base_Theme_Yellow; 41 | int nightYellow = R.style.Base_Theme_Dark_Yellow; 42 | int amber = R.style.Base_Theme_Amber; 43 | int nightAmber = R.style.Base_Theme_Dark_Amber; 44 | int orange = R.style.Base_Theme_Orange; 45 | int nightOrange = R.style.Base_Theme_Dark_Orange; 46 | int deepOrange = R.style.Base_Theme_DeepOrange; 47 | int nightDeepOrange = R.style.Base_Theme_Dark_DeepOrange; 48 | int brown = R.style.Base_Theme_Brown; 49 | int nightBrown = R.style.Base_Theme_Dark_Brown; 50 | int blueGrey = R.style.Base_Theme_BlueGrey; 51 | int nightBlueGrey = R.style.Base_Theme_Dark_BlueGrey; 52 | 53 | String choice = PreferenceManager.getDefaultSharedPreferences(context) 54 | .getString(context.getString(R.string.pref_theme), String.valueOf(0)); 55 | 56 | switch (Integer.parseInt(choice)) { 57 | default: 58 | case 0: 59 | return light; 60 | case 1: 61 | return dark; 62 | case 2: 63 | return red; 64 | case 3: 65 | return nightRed; 66 | case 4: 67 | return pink; 68 | case 5: 69 | return nightPink; 70 | case 6: 71 | return purple; 72 | case 7: 73 | return nightPurple; 74 | case 8: 75 | return deepPurple; 76 | case 9: 77 | return nightDeepPurple; 78 | case 10: 79 | return indigo; 80 | case 11: 81 | return nightIndigo; 82 | case 12: 83 | return blue; 84 | case 13: 85 | return nightBlue; 86 | case 14: 87 | return lightBlue; 88 | case 15: 89 | return nightLightBlue; 90 | case 16: 91 | return cyan; 92 | case 17: 93 | return nightCyan; 94 | case 18: 95 | return teal; 96 | case 19: 97 | return nightTeal; 98 | case 20: 99 | return green; 100 | case 21: 101 | return nightGreen; 102 | case 22: 103 | return lightGreen; 104 | case 23: 105 | return nightLightGreen; 106 | case 24: 107 | return lime; 108 | case 25: 109 | return nightLime; 110 | case 26: 111 | return yellow; 112 | case 27: 113 | return nightYellow; 114 | case 28: 115 | return amber; 116 | case 29: 117 | return nightAmber; 118 | case 30: 119 | return orange; 120 | case 31: 121 | return nightOrange; 122 | case 32: 123 | return deepOrange; 124 | case 33: 125 | return nightDeepOrange; 126 | case 34: 127 | return brown; 128 | case 35: 129 | return nightBrown; 130 | case 36: 131 | return blueGrey; 132 | case 37: 133 | return nightBlueGrey; 134 | } 135 | } 136 | 137 | public static int resolveGrid(Activity activity) { 138 | 139 | int two = 2; 140 | int three = 3; 141 | int four = 4; 142 | 143 | String choice = PreferenceManager.getDefaultSharedPreferences(activity) 144 | .getString(activity.getString(R.string.pref_grid), String.valueOf(40)); 145 | switch (Integer.parseInt(choice)) { 146 | case 38: 147 | return two; 148 | default: 149 | case 39: 150 | return three; 151 | case 40: 152 | return four; 153 | 154 | } 155 | } 156 | 157 | public static void applyTheme(ContextThemeWrapper contextThemeWrapper, Context context) { 158 | int theme = Preferences.resolveTheme(context); 159 | contextThemeWrapper.setTheme(theme); 160 | } 161 | } 162 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/DeleteFileUtils.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.app.ProgressDialog; 5 | import android.content.ContentResolver; 6 | import android.content.DialogInterface; 7 | import android.content.Intent; 8 | import android.net.Uri; 9 | import android.os.AsyncTask; 10 | import android.provider.MediaStore; 11 | import android.support.v4.provider.DocumentFile; 12 | import android.support.v7.app.AlertDialog; 13 | import android.widget.Toast; 14 | 15 | import com.enrico.gallery.galleryapp.R; 16 | 17 | import java.io.File; 18 | import java.io.IOException; 19 | 20 | import static com.enrico.gallery.galleryapp.utils.PermissionUtils.rationaleDialog; 21 | 22 | public class DeleteFileUtils { 23 | 24 | private static void deleteFileFromMediaStore(final ContentResolver contentResolver, File file) { 25 | 26 | String canonicalPath; 27 | 28 | try { 29 | canonicalPath = file.getCanonicalPath(); 30 | } catch (IOException e) { 31 | canonicalPath = file.getAbsolutePath(); 32 | } 33 | final Uri uri = MediaStore.Files.getContentUri("external"); 34 | final int result = contentResolver.delete(uri, 35 | MediaStore.Files.FileColumns.DATA + "=?", new String[]{canonicalPath}); 36 | if (result == 0) { 37 | final String absolutePath = file.getAbsolutePath(); 38 | if (!absolutePath.equals(canonicalPath)) { 39 | contentResolver.delete(uri, 40 | MediaStore.Files.FileColumns.DATA + "=?", new String[]{absolutePath}); 41 | } 42 | } 43 | } 44 | 45 | private static void deleteFileSAF(String url, final Activity activity) { 46 | 47 | if (SDCardUtils.getSDCardUri(activity).isEmpty()) { 48 | 49 | PermissionUtils.askSDCardAccess(activity); 50 | 51 | } else { 52 | 53 | File file = new File(url); 54 | 55 | DocumentFile documentFile = DocumentFile.fromTreeUri(activity, Uri.parse(SDCardUtils.getSDCardUri(activity))); 56 | 57 | String[] parts = (file.getPath()).split("\\/"); 58 | 59 | for (int i = 3; i < parts.length; i++) { 60 | if (documentFile != null) { 61 | documentFile = documentFile.findFile(parts[i]); 62 | } 63 | } 64 | 65 | if (documentFile == null) { 66 | 67 | activity.runOnUiThread(new Runnable() { 68 | @Override 69 | public void run() { 70 | Toast.makeText(activity, activity.getString(R.string.notFound), Toast.LENGTH_SHORT) 71 | .show(); 72 | 73 | Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE); 74 | 75 | rationaleDialog(activity, activity.getString(R.string.sdcard), activity.getString(R.string.sdcardContent), 2, intent); 76 | } 77 | }); 78 | 79 | } else { 80 | 81 | if (documentFile.delete()) { 82 | 83 | deleteFileFromMediaStore(activity.getContentResolver(), file); 84 | 85 | } 86 | } 87 | } 88 | } 89 | 90 | private static void deleteFile(final String url, final Activity activity) { 91 | 92 | final File file = new File(url); 93 | 94 | if (file.delete()) { 95 | 96 | deleteFileFromMediaStore(activity.getContentResolver(), file); 97 | 98 | } else { 99 | 100 | deleteFileSAF(url, activity); 101 | } 102 | } 103 | 104 | public static void youSureToDelete(final Activity activity, final String url) { 105 | 106 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( 107 | activity); 108 | 109 | alertDialogBuilder.setTitle(activity.getString(R.string.uSure)); 110 | 111 | alertDialogBuilder 112 | .setMessage(activity.getString(R.string.uSureContent) + url + activity.getString(R.string.questionMark)) 113 | .setCancelable(false) 114 | .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { 115 | public void onClick(DialogInterface dialog, int id) { 116 | 117 | dialog.dismiss(); 118 | 119 | } 120 | } 121 | ) 122 | .setPositiveButton(activity.getString(R.string.delete), new DialogInterface.OnClickListener() { 123 | public void onClick(DialogInterface dialog, int id) { 124 | 125 | execute(activity, url); 126 | } 127 | }); 128 | 129 | AlertDialog alertDialog = alertDialogBuilder.create(); 130 | 131 | alertDialog.show(); 132 | 133 | } 134 | 135 | private static void execute(Activity activity, String url) { 136 | 137 | new AsyncDelete(activity, url).execute(); 138 | } 139 | 140 | private static class AsyncDelete extends AsyncTask { 141 | 142 | Activity activity; 143 | String url; 144 | ProgressDialog progressDialog; 145 | 146 | private AsyncDelete(Activity activity, String url) { 147 | this.activity = activity; 148 | this.url = url; 149 | } 150 | 151 | 152 | protected void onPreExecute() { 153 | 154 | progressDialog = new ProgressDialog(activity); 155 | progressDialog.setMessage(activity.getString(R.string.deleting)); 156 | progressDialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); 157 | progressDialog.setIndeterminate(true); 158 | progressDialog.setProgressNumberFormat(null); 159 | progressDialog.setProgressPercentFormat(null); 160 | progressDialog.setCancelable(false); 161 | progressDialog.show(); 162 | } 163 | 164 | @Override 165 | protected Void doInBackground(Void... params) { 166 | 167 | deleteFile(url, activity); 168 | return null; 169 | } 170 | 171 | @Override 172 | protected void onPostExecute(Void result) { 173 | progressDialog.dismiss(); 174 | } 175 | } 176 | } 177 | 178 | 179 | -------------------------------------------------------------------------------- /project/app/src/main/res/layout/bottom_sheet_info.xml: -------------------------------------------------------------------------------- 1 | 2 | 11 | 12 | 17 | 18 | 25 | 26 | 33 | 34 | 35 | 41 | 42 | 48 | 49 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 77 | 78 | 79 | 85 | 86 | 92 | 93 | 99 | 100 | 101 | 107 | 108 | 114 | 115 | 121 | 122 | 123 | 129 | 130 | 136 | 137 | 142 | 143 | 144 | 150 | 151 | 157 | 158 | 163 | 164 | 165 | 179 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/BottomSheetMediaActions.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.app.Activity; 4 | import android.graphics.Color; 5 | import android.net.Uri; 6 | import android.support.design.widget.BottomSheetBehavior; 7 | import android.support.v4.app.Fragment; 8 | import android.view.View; 9 | import android.widget.ImageButton; 10 | import android.widget.LinearLayout; 11 | import android.widget.TextView; 12 | 13 | import com.enrico.gallery.galleryapp.R; 14 | import com.theartofdev.edmodo.cropper.CropImage; 15 | 16 | import java.io.File; 17 | import java.util.Locale; 18 | 19 | import static com.enrico.gallery.galleryapp.albums.HeaderRecyclerViewSection.stringContainsItemFromList; 20 | 21 | public class BottomSheetMediaActions { 22 | 23 | public static void show(final Activity activity, final LinearLayout bottomSheet, final String url, final Fragment ifAny) { 24 | 25 | toggleBottomSheet(bottomSheet); 26 | 27 | activity.runOnUiThread(new Runnable() { 28 | @Override 29 | public void run() { 30 | 31 | getInfo(activity, bottomSheet, ifAny, url); 32 | 33 | } 34 | }); 35 | 36 | } 37 | 38 | private static void toggleBottomSheet(View bottomSheet) { 39 | 40 | BottomSheetBehavior bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet); 41 | 42 | int state = bottomSheetBehavior.getState(); 43 | 44 | switch (state) { 45 | case BottomSheetBehavior.STATE_COLLAPSED: 46 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_EXPANDED); 47 | break; 48 | case BottomSheetBehavior.STATE_HIDDEN: 49 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_COLLAPSED); 50 | break; 51 | case BottomSheetBehavior.STATE_EXPANDED: 52 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 53 | break; 54 | 55 | } 56 | } 57 | 58 | private static void set(final Activity activity, final String url, LinearLayout bottomView, final Fragment ifAny, String name, String path, String date, double fileSize, final String type, String fileWidth, String fileHeight) { 59 | 60 | String[] VIDEO_EXTENSIONS = {"mp4", "avi", "mpg", "mkv", "webm", "flv", "gif", 61 | "wmv", "mov", "qt", "m4p", "m4v", "mpeg", "mp2", 62 | "m2v", "3gp", "3g2", "f4v", "f4p", "f4a", "f4b"}; 63 | 64 | ImageButton share = (ImageButton) bottomView.findViewById(R.id.share); 65 | ImageButton crop = (ImageButton) bottomView.findViewById(R.id.crop); 66 | ImageButton delete = (ImageButton) bottomView.findViewById(R.id.delete); 67 | final TextView setAsWallpaper = (TextView) bottomView.findViewById(R.id.setAs); 68 | 69 | if (!stringContainsItemFromList(url, VIDEO_EXTENSIONS)) { 70 | setAsWallpaper.setVisibility(View.VISIBLE); 71 | 72 | crop.setVisibility(View.VISIBLE); 73 | crop.setOnClickListener(new View.OnClickListener() { 74 | @Override 75 | public void onClick(View v) { 76 | 77 | if (ifAny != null) { 78 | CropImage.activity(Uri.fromFile(new File(url))) 79 | .setActivityMenuIconColor(Color.BLACK) 80 | .start(activity, ifAny); 81 | } else { 82 | CropImage.activity(Uri.fromFile(new File(url))) 83 | .setActivityMenuIconColor(Color.BLACK) 84 | .start(activity); 85 | 86 | } 87 | 88 | 89 | } 90 | }); 91 | 92 | setAsWallpaper.setOnClickListener(new View.OnClickListener() { 93 | @Override 94 | public void onClick(View v) { 95 | 96 | ApplyWallpaper.execute(activity, url); 97 | } 98 | }); 99 | } 100 | 101 | share.setOnClickListener(new View.OnClickListener() { 102 | @Override 103 | public void onClick(View v) { 104 | ShareUtils.shareFile(activity, url); 105 | } 106 | }); 107 | 108 | delete.setOnClickListener(new View.OnClickListener() { 109 | @Override 110 | public void onClick(View v) { 111 | DeleteFileUtils.youSureToDelete(activity, url); 112 | } 113 | }); 114 | 115 | TextView fileName = (TextView) bottomView.findViewById(R.id.filename); 116 | TextView size = (TextView) bottomView.findViewById(R.id.size); 117 | TextView width = (TextView) bottomView.findViewById(R.id.width); 118 | TextView height = (TextView) bottomView.findViewById(R.id.height); 119 | TextView filePath = (TextView) bottomView.findViewById(R.id.path); 120 | TextView fileType = (TextView) bottomView.findViewById(R.id.type); 121 | TextView fileLastMod = (TextView) bottomView.findViewById(R.id.lastMod); 122 | 123 | fileName.setText(name); 124 | filePath.setText(path); 125 | setSize(activity, size, fileSize); 126 | fileType.setText(type); 127 | width.setText(fileWidth); 128 | height.setText(fileHeight); 129 | fileLastMod.setText(date); 130 | } 131 | 132 | private static void setSize(Activity activity, TextView textSize, double bytes) { 133 | 134 | double kilobytes = (bytes / 1024); 135 | double megabytes = (kilobytes / 1024); 136 | double gigabytes = (megabytes / 1024); 137 | 138 | String resultB = Math.round(bytes) + activity.getString(R.string.B); 139 | 140 | String resultKB = String.format(Locale.getDefault(), "%.2f", kilobytes) + activity.getString(R.string.KB); 141 | 142 | String resultMB = String.format(Locale.getDefault(), "%.2f", megabytes) + activity.getString(R.string.MB); 143 | 144 | String resultGB = String.format(Locale.getDefault(), "%.2f", gigabytes) + activity.getString(R.string.GB); 145 | 146 | if (kilobytes < 1000.000) { 147 | textSize.setText(resultKB + activity.getString(R.string.parenthesisL) + resultB + activity.getString(R.string.parenthesisR)); 148 | } else if (megabytes >= 1000.000) { 149 | textSize.setText(resultGB + activity.getString(R.string.parenthesisL) + resultB + activity.getString(R.string.parenthesisR)); 150 | } else { 151 | textSize.setText(resultMB + activity.getString(R.string.parenthesisL) + resultB + activity.getString(R.string.parenthesisR)); 152 | } 153 | } 154 | 155 | private static void getInfo(final Activity activity, LinearLayout bottomView, Fragment ifAny, final String url) { 156 | 157 | String fileName = InfoUtils.fileName(url); 158 | String filePath = InfoUtils.filePath(url); 159 | String lastModifiedDate = InfoUtils.lastModifiedDate(url); 160 | double fileSize = InfoUtils.fileSize(url); 161 | String fileWidth = InfoUtils.fileResolution(url, 0); 162 | String fileHeight = InfoUtils.fileResolution(url, 1); 163 | String fileType = InfoUtils.fileType(activity, url); 164 | 165 | BottomSheetMediaActions.set(activity, url, bottomView, ifAny, fileName, filePath, lastModifiedDate, fileSize, fileType, fileWidth, fileHeight); 166 | 167 | } 168 | 169 | } 170 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/AlbumsUtils.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | import android.app.Activity; 4 | import android.database.Cursor; 5 | import android.database.sqlite.SQLiteDatabase; 6 | import android.net.Uri; 7 | import android.provider.MediaStore; 8 | import android.support.v7.widget.GridLayoutManager; 9 | import android.support.v7.widget.RecyclerView; 10 | 11 | import com.enrico.gallery.galleryapp.settings.Preferences; 12 | 13 | import java.io.File; 14 | import java.util.ArrayList; 15 | import java.util.HashSet; 16 | import java.util.Set; 17 | 18 | import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter; 19 | 20 | import static android.content.Context.MODE_PRIVATE; 21 | 22 | public class AlbumsUtils { 23 | 24 | static ArrayList getAllAlbums(Activity activity) { 25 | 26 | Uri externalImagesUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; 27 | Uri internalImagesUri = MediaStore.Images.Media.INTERNAL_CONTENT_URI; 28 | Uri externalVideosUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; 29 | Uri internalVideosUri = MediaStore.Video.Media.INTERNAL_CONTENT_URI; 30 | String imageData = MediaStore.Images.ImageColumns.DATA; 31 | String imagePath = MediaStore.Images.ImageColumns.DISPLAY_NAME; 32 | String videoData = MediaStore.Video.VideoColumns.DATA; 33 | String videoPath = MediaStore.Video.VideoColumns.DISPLAY_NAME; 34 | 35 | ArrayList allAlbums = new ArrayList<>(); 36 | 37 | Cursor cursor; 38 | int column_index_data; 39 | 40 | String absolutePathOfAlbums; 41 | 42 | String[] ImagesProjection = {imageData, imagePath}; 43 | 44 | cursor = activity.getContentResolver().query(externalImagesUri, ImagesProjection, null, 45 | null, null); 46 | 47 | if (cursor != null) { 48 | column_index_data = cursor.getColumnIndexOrThrow(imageData); 49 | 50 | while (cursor.moveToNext()) { 51 | 52 | absolutePathOfAlbums = cursor.getString(column_index_data); 53 | 54 | Albums media = new Albums(); 55 | 56 | media.setAlbumsUrl(absolutePathOfAlbums); 57 | 58 | allAlbums.add(media); 59 | 60 | } 61 | } 62 | 63 | cursor = activity.getContentResolver().query(internalImagesUri, ImagesProjection, null, 64 | null, null); 65 | 66 | if (cursor != null) { 67 | column_index_data = cursor.getColumnIndexOrThrow(imageData); 68 | 69 | while (cursor.moveToNext()) { 70 | 71 | absolutePathOfAlbums = cursor.getString(column_index_data); 72 | 73 | Albums media = new Albums(); 74 | 75 | media.setAlbumsUrl(absolutePathOfAlbums); 76 | 77 | allAlbums.add(media); 78 | } 79 | 80 | String[] VideosProjection = {videoData, videoPath}; 81 | 82 | cursor = activity.getContentResolver().query(externalVideosUri, VideosProjection, null, 83 | null, null); 84 | 85 | if (cursor != null) { 86 | column_index_data = cursor.getColumnIndexOrThrow(videoData); 87 | 88 | while (cursor.moveToNext()) { 89 | 90 | absolutePathOfAlbums = cursor.getString(column_index_data); 91 | 92 | Albums media = new Albums(); 93 | 94 | media.setAlbumsUrl(absolutePathOfAlbums); 95 | 96 | allAlbums.add(media); 97 | 98 | } 99 | } 100 | 101 | cursor = activity.getContentResolver().query(internalVideosUri, VideosProjection, null, 102 | null, null); 103 | 104 | if (cursor != null) { 105 | column_index_data = cursor.getColumnIndexOrThrow(videoData); 106 | 107 | while (cursor.moveToNext()) { 108 | 109 | absolutePathOfAlbums = cursor.getString(column_index_data); 110 | 111 | Albums media = new Albums(); 112 | 113 | media.setAlbumsUrl(absolutePathOfAlbums); 114 | 115 | allAlbums.add(media); 116 | } 117 | cursor.close(); 118 | 119 | } 120 | } 121 | return allAlbums; 122 | } 123 | 124 | static String getFolderName(String path) { 125 | 126 | File folderName = new File(path); 127 | 128 | return folderName.getName(); 129 | 130 | } 131 | 132 | static void setupAlbums(final Activity activity, String[] veryPaths, RecyclerView recyclerView, final SectionedRecyclerViewAdapter sectionedRecyclerViewAdapter) { 133 | 134 | for (String path : veryPaths) { 135 | 136 | String[] mediaUrls = MediaFromAlbums.listMedia(path); 137 | 138 | if (mediaUrls.length != 0) { 139 | 140 | final int gridNumber = Preferences.resolveGrid(activity); 141 | 142 | GridLayoutManager glm = new GridLayoutManager(activity, gridNumber); 143 | glm.setSpanSizeLookup(new GridLayoutManager.SpanSizeLookup() { 144 | @Override 145 | public int getSpanSize(int position) { 146 | switch (sectionedRecyclerViewAdapter.getSectionItemViewType(position)) { 147 | case SectionedRecyclerViewAdapter.VIEW_TYPE_HEADER: 148 | return gridNumber; 149 | default: 150 | return 1; 151 | } 152 | } 153 | }); 154 | 155 | recyclerView.setLayoutManager(glm); 156 | 157 | HeaderRecyclerViewSection headerRecyclerViewSection = new HeaderRecyclerViewSection(activity, path, mediaUrls, sectionedRecyclerViewAdapter, gridNumber); 158 | 159 | sectionedRecyclerViewAdapter.addSection(headerRecyclerViewSection); 160 | 161 | } 162 | 163 | } 164 | 165 | } 166 | 167 | static String[] initFolders(Activity activity, ArrayList albumsList) { 168 | 169 | int mediaSize = albumsList.size(); 170 | 171 | String[] albumsPath = new String[mediaSize]; 172 | 173 | Set paths = new HashSet<>(); 174 | 175 | for (int i = 0; i < albumsList.size(); i++) { 176 | 177 | albumsPath[i] = albumsList.get(i).getAlbumsPath(); 178 | 179 | paths.add(albumsPath[i]); 180 | } 181 | 182 | ArrayList mHiddenFolders = new ArrayList<>(); 183 | 184 | SQLiteDatabase hiddenFoldersDB = activity.openOrCreateDatabase("HIDDEN", MODE_PRIVATE, null); 185 | 186 | hiddenFoldersDB.execSQL("CREATE TABLE IF NOT EXISTS foldersList (id INTEGER PRIMARY KEY AUTOINCREMENT,folder varchar);"); 187 | 188 | Cursor cursor = hiddenFoldersDB.rawQuery("SELECT * FROM foldersList;", null); 189 | 190 | if (cursor != null && cursor.moveToFirst()) { 191 | 192 | while (!cursor.isAfterLast()) { 193 | 194 | mHiddenFolders.add(cursor.getString(cursor.getColumnIndex("folder"))); 195 | cursor.moveToNext(); 196 | } 197 | cursor.close(); 198 | } 199 | 200 | 201 | if (mHiddenFolders.size() != 0) { 202 | 203 | Set veryHiddenFolders = new HashSet<>(); 204 | 205 | for (String hiddenFolders : mHiddenFolders) { 206 | 207 | veryHiddenFolders.add(hiddenFolders); 208 | } 209 | 210 | String[] mHidden = veryHiddenFolders.toArray(new String[veryHiddenFolders.size()]); 211 | 212 | for (String hiddenFolders : mHidden) { 213 | 214 | paths.remove(hiddenFolders); 215 | } 216 | } 217 | 218 | return paths.toArray(new String[paths.size()]); 219 | } 220 | } 221 | 222 | 223 | 224 | 225 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/albums/HeaderRecyclerViewSection.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.albums; 2 | 3 | import android.app.Activity; 4 | import android.content.DialogInterface; 5 | import android.content.Intent; 6 | import android.database.sqlite.SQLiteDatabase; 7 | import android.os.Bundle; 8 | import android.support.v7.app.AlertDialog; 9 | import android.support.v7.widget.RecyclerView; 10 | import android.util.TypedValue; 11 | import android.view.View; 12 | 13 | import com.bumptech.glide.Glide; 14 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 15 | import com.enrico.gallery.galleryapp.MediaActivity; 16 | import com.enrico.gallery.galleryapp.MediaObserver; 17 | import com.enrico.gallery.galleryapp.R; 18 | import com.enrico.gallery.galleryapp.utils.DeleteFileUtils; 19 | 20 | import io.github.luizgrp.sectionedrecyclerviewadapter.SectionedRecyclerViewAdapter; 21 | import io.github.luizgrp.sectionedrecyclerviewadapter.StatelessSection; 22 | 23 | import static android.content.Context.MODE_PRIVATE; 24 | 25 | public class HeaderRecyclerViewSection extends StatelessSection { 26 | 27 | private int gridNumber; 28 | private boolean expanded = true; 29 | private String title; 30 | private String[] mUrls; 31 | private Activity activity; 32 | private SectionedRecyclerViewAdapter sectionedRecyclerViewAdapter; 33 | 34 | private String[] VIDEO_EXTENSIONS = {"mp4", "avi", "mpg", "mkv", "webm", "flv", 35 | "wmv", "mov", "qt", "m4p", "m4v", "mpeg", "mp2", 36 | "m2v", "3gp", "3g2", "f4v", "f4p", "f4a", "f4b"}; 37 | 38 | HeaderRecyclerViewSection(Activity activity, String title, String[] mUrls, SectionedRecyclerViewAdapter sectionedRecyclerViewAdapter, int gridNumber) { 39 | super(R.layout.header_layout, R.layout.media_item); 40 | 41 | this.title = title; 42 | this.mUrls = mUrls; 43 | this.activity = activity; 44 | this.sectionedRecyclerViewAdapter = sectionedRecyclerViewAdapter; 45 | this.gridNumber = gridNumber; 46 | } 47 | 48 | public static boolean stringContainsItemFromList(String inputStr, String[] items) { 49 | 50 | for (String item : items) { 51 | if (inputStr.contains(item)) { 52 | return true; 53 | } 54 | } 55 | 56 | return false; 57 | } 58 | 59 | private static void youSureToHide(final Activity activity, final String url) { 60 | 61 | AlertDialog.Builder alertDialogBuilder = new AlertDialog.Builder( 62 | activity); 63 | 64 | alertDialogBuilder.setTitle(activity.getString(R.string.uSureHide)); 65 | 66 | alertDialogBuilder 67 | .setMessage(activity.getString(R.string.uSureHideContent) + url + activity.getString(R.string.questionMark)) 68 | .setCancelable(false) 69 | .setNegativeButton(android.R.string.no, new DialogInterface.OnClickListener() { 70 | public void onClick(DialogInterface dialog, int id) { 71 | 72 | dialog.dismiss(); 73 | 74 | } 75 | } 76 | ) 77 | .setPositiveButton(activity.getString(R.string.hide), new DialogInterface.OnClickListener() { 78 | public void onClick(DialogInterface dialog, int id) { 79 | 80 | SQLiteDatabase hiddenFoldersDB = activity.openOrCreateDatabase("HIDDEN", MODE_PRIVATE, null); 81 | 82 | hiddenFoldersDB.execSQL("CREATE TABLE IF NOT EXISTS foldersList (id INTEGER PRIMARY KEY AUTOINCREMENT,folder varchar);"); 83 | 84 | hiddenFoldersDB.execSQL("insert into foldersList (folder) values(?);", new String[]{url}); 85 | 86 | MediaObserver.restart(activity); 87 | } 88 | }); 89 | 90 | AlertDialog alertDialog = alertDialogBuilder.create(); 91 | 92 | alertDialog.show(); 93 | 94 | } 95 | 96 | @Override 97 | public int getContentItemsTotal() { 98 | return expanded ? mUrls.length : 0; 99 | } 100 | 101 | @Override 102 | public RecyclerView.ViewHolder getItemViewHolder(View view) { 103 | return new ItemViewHolder(view); 104 | } 105 | 106 | @Override 107 | public void onBindItemViewHolder(RecyclerView.ViewHolder holder, final int position) { 108 | final ItemViewHolder iHolder = (ItemViewHolder) holder; 109 | 110 | final String url = mUrls[position]; 111 | 112 | activity.runOnUiThread(new Runnable() { 113 | @Override 114 | public void run() { 115 | 116 | if (stringContainsItemFromList(url, VIDEO_EXTENSIONS)) { 117 | 118 | iHolder.cameraView.setVisibility(View.VISIBLE); 119 | 120 | } 121 | 122 | if (url.contains(".gif")) { 123 | iHolder.gifView.setVisibility(View.VISIBLE); 124 | } 125 | 126 | Glide.with(activity) 127 | .load(url) 128 | .asBitmap() 129 | .placeholder(R.mipmap.ic_mood) 130 | .diskCacheStrategy(DiskCacheStrategy.NONE) 131 | .into(iHolder.picView); 132 | 133 | iHolder.rootView.setOnClickListener(new View.OnClickListener() { 134 | @Override 135 | public void onClick(View v) { 136 | 137 | Intent intent = new Intent(activity, 138 | MediaActivity.class); 139 | 140 | intent.putExtra("urls", mUrls); 141 | intent.putExtra("pos", position); 142 | 143 | activity.startActivity(intent); 144 | } 145 | }); 146 | 147 | iHolder.rootView.setOnLongClickListener(new View.OnLongClickListener() { 148 | @Override 149 | public boolean onLongClick(View v) { 150 | 151 | DeleteFileUtils.youSureToDelete(activity, mUrls[position]); 152 | return false; 153 | } 154 | }); 155 | } 156 | }); 157 | 158 | } 159 | 160 | @Override 161 | public RecyclerView.ViewHolder getHeaderViewHolder(View view) { 162 | return new HeaderViewHolder(view); 163 | } 164 | 165 | @Override 166 | public void onBindHeaderViewHolder(RecyclerView.ViewHolder holder) { 167 | final HeaderViewHolder hHolder = (HeaderViewHolder) holder; 168 | 169 | String currentFolder = AlbumsUtils.getFolderName(title); 170 | 171 | hHolder.headerTitle.setText(currentFolder); 172 | 173 | switch (gridNumber) { 174 | case 2: 175 | hHolder.headerTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 20); 176 | break; 177 | case 3: 178 | hHolder.headerTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18); 179 | break; 180 | case 4: 181 | hHolder.headerTitle.setTextSize(TypedValue.COMPLEX_UNIT_SP, 16); 182 | break; 183 | } 184 | 185 | hHolder.imgArrow.setOnClickListener(new View.OnClickListener() { 186 | @Override 187 | public void onClick(View v) { 188 | expanded = !expanded; 189 | hHolder.imgArrow.setImageResource( 190 | expanded ? R.drawable.ic_arrow_up : R.drawable.ic_arrow_down 191 | ); 192 | 193 | sectionedRecyclerViewAdapter.notifyDataSetChanged(); 194 | } 195 | }); 196 | 197 | hHolder.imgVisibilty.setOnClickListener(new View.OnClickListener() { 198 | @Override 199 | public void onClick(View v) { 200 | 201 | youSureToHide(activity, title); 202 | 203 | } 204 | }); 205 | } 206 | } -------------------------------------------------------------------------------- /project/app/src/main/res/values-v23/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 11 | 12 | 20 | 21 | 29 | 30 | 38 | 39 | 47 | 48 | 56 | 57 | 65 | 66 | 74 | 75 | 83 | 84 | 92 | 93 | 101 | 102 | 110 | 111 | 119 | 120 | 128 | 129 | 137 | 138 | 146 | 147 | 155 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/MediaPagerFragment.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp; 2 | 3 | import android.content.Intent; 4 | import android.graphics.Color; 5 | import android.graphics.drawable.ColorDrawable; 6 | import android.net.Uri; 7 | import android.os.Bundle; 8 | import android.support.annotation.NonNull; 9 | import android.support.design.widget.BottomSheetBehavior; 10 | import android.support.design.widget.FloatingActionButton; 11 | import android.support.v4.app.Fragment; 12 | import android.view.LayoutInflater; 13 | import android.view.View; 14 | import android.view.ViewGroup; 15 | import android.widget.LinearLayout; 16 | 17 | import com.afollestad.easyvideoplayer.EasyVideoCallback; 18 | import com.afollestad.easyvideoplayer.EasyVideoPlayer; 19 | import com.bumptech.glide.Glide; 20 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 21 | import com.enrico.gallery.galleryapp.utils.BottomSheetMediaActions; 22 | import com.enrico.gallery.galleryapp.utils.SaveTools; 23 | import com.github.chrisbanes.photoview.PhotoView; 24 | import com.theartofdev.edmodo.cropper.CropImage; 25 | 26 | import static android.app.Activity.RESULT_OK; 27 | import static com.enrico.gallery.galleryapp.albums.HeaderRecyclerViewSection.stringContainsItemFromList; 28 | 29 | public class MediaPagerFragment extends Fragment implements EasyVideoCallback { 30 | 31 | PhotoView photoView; 32 | String[] mUrls; 33 | BottomSheetBehavior bottomSheetBehavior; 34 | 35 | int pos; 36 | FloatingActionButton fabPlay; 37 | String url; 38 | Fragment fragment; 39 | LinearLayout bottomSheet; 40 | 41 | private String[] VIDEO_EXTENSIONS = {"mp4", "avi", "mpg", "mkv", "webm", "flv", 42 | "wmv", "mov", "qt", "m4p", "m4v", "mpeg", "mp2", 43 | "m2v", "3gp", "3g2", "f4v", "f4p", "f4a", "f4b"}; 44 | 45 | private EasyVideoPlayer videoView; 46 | 47 | @Override 48 | public void onPause() { 49 | super.onPause(); 50 | 51 | videoView.pause(); 52 | } 53 | 54 | @Override 55 | public void onCreate(Bundle savedInstanceState) { 56 | 57 | super.onCreate(savedInstanceState); 58 | 59 | fragment = this; 60 | 61 | mUrls = (String[]) getActivity().getIntent().getExtras().get("urls"); 62 | 63 | pos = getArguments().getInt("pos"); 64 | 65 | url = mUrls[pos]; 66 | 67 | setRetainInstance(true); 68 | } 69 | 70 | @Override 71 | public View onCreateView(LayoutInflater inflater, ViewGroup container, 72 | Bundle savedInstanceState) { 73 | 74 | return inflater 75 | .inflate(R.layout.media_pager, container, false); 76 | 77 | } 78 | 79 | @Override 80 | public void onActivityCreated(Bundle savedInstanceState) { 81 | super.onActivityCreated(savedInstanceState); 82 | 83 | final View view = getView(); 84 | 85 | if (view != null) { 86 | 87 | getActivity().runOnUiThread(new Runnable() { 88 | @Override 89 | public void run() { 90 | initViews(view); 91 | 92 | initMediaView(); 93 | 94 | } 95 | }); 96 | 97 | } 98 | } 99 | 100 | @Override 101 | public void onPreparing(EasyVideoPlayer player) { 102 | // TODO handle if needed 103 | } 104 | 105 | @Override 106 | public void onPrepared(EasyVideoPlayer player) { 107 | // TODO handle 108 | } 109 | 110 | @Override 111 | public void onBuffering(int percent) { 112 | // TODO handle if needed 113 | } 114 | 115 | @Override 116 | public void onError(EasyVideoPlayer player, Exception e) { 117 | // TODO handle 118 | } 119 | 120 | @Override 121 | public void onCompletion(EasyVideoPlayer player) { 122 | // TODO handle if needed 123 | 124 | fabPlay.show(new FloatingActionButton.OnVisibilityChangedListener() { 125 | @Override 126 | public void onShown(FloatingActionButton fab) { 127 | photoView.setVisibility(View.VISIBLE); 128 | videoView.setVisibility(View.GONE); 129 | 130 | } 131 | }); 132 | } 133 | 134 | @Override 135 | public void onRetry(EasyVideoPlayer player, Uri source) { 136 | // TODO handle if used 137 | } 138 | 139 | @Override 140 | public void onSubmit(EasyVideoPlayer player, Uri source) { 141 | // TODO handle if used 142 | } 143 | 144 | @Override 145 | public void onStarted(EasyVideoPlayer player) { 146 | // TODO handle if needed 147 | } 148 | 149 | @Override 150 | public void onPaused(EasyVideoPlayer player) { 151 | // TODO handle if needed 152 | } 153 | 154 | @Override 155 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 156 | 157 | if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) { 158 | CropImage.ActivityResult result = CropImage.getActivityResult(data); 159 | if (resultCode == RESULT_OK) { 160 | Uri resultUri = result.getUri(); 161 | 162 | SaveTools.saveCrop(getActivity(), resultUri, url); 163 | } 164 | } 165 | } 166 | 167 | private void initViews(View view) { 168 | 169 | bottomSheet = (LinearLayout) view.findViewById(R.id.bottom_sheet_media); 170 | 171 | bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet); 172 | 173 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 174 | 175 | photoView = (PhotoView) view.findViewById(R.id.photoView); 176 | 177 | videoView = (EasyVideoPlayer) view.findViewById(R.id.videoView); 178 | 179 | fabPlay = (FloatingActionButton) view.findViewById(R.id.fab_play); 180 | 181 | } 182 | 183 | private void initMediaView() { 184 | 185 | if (stringContainsItemFromList(url, VIDEO_EXTENSIONS)) { 186 | 187 | videoView.setCallback(this); 188 | 189 | videoView.setSource(Uri.parse(url)); 190 | 191 | fabPlay.show(); 192 | fabPlay.setOnClickListener(new View.OnClickListener() { 193 | @Override 194 | public void onClick(View v) { 195 | videoView.setVisibility(View.VISIBLE); 196 | photoView.setVisibility(View.GONE); 197 | 198 | if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) { 199 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 200 | } 201 | 202 | fabPlay.hide(new FloatingActionButton.OnVisibilityChangedListener() { 203 | @Override 204 | public void onHidden(FloatingActionButton fab) { 205 | 206 | videoView.start(); 207 | 208 | } 209 | }); 210 | } 211 | }); 212 | 213 | photoView.setOnLongClickListener(new View.OnLongClickListener() { 214 | @Override 215 | public boolean onLongClick(View v) { 216 | 217 | BottomSheetMediaActions.show(getActivity(), bottomSheet, url, fragment); 218 | 219 | bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 220 | @Override 221 | public void onStateChanged(@NonNull View bottomSheet, int newState) { 222 | 223 | switch (newState) { 224 | case BottomSheetBehavior.STATE_EXPANDED: 225 | 226 | fabPlay.hide(); 227 | break; 228 | case BottomSheetBehavior.STATE_COLLAPSED: 229 | 230 | fabPlay.show(); 231 | break; 232 | 233 | case BottomSheetBehavior.STATE_HIDDEN: 234 | 235 | if (!videoView.isShown()) { 236 | fabPlay.show(); 237 | } 238 | } 239 | } 240 | 241 | @Override 242 | public void onSlide(@NonNull View bottomSheet, float slideOffset) { 243 | 244 | } 245 | }); 246 | 247 | return false; 248 | } 249 | }); 250 | } else { 251 | 252 | photoView.setOnLongClickListener(new View.OnLongClickListener() { 253 | @Override 254 | public boolean onLongClick(View v) { 255 | 256 | BottomSheetMediaActions.show(getActivity(), bottomSheet, url, fragment); 257 | return false; 258 | } 259 | }); 260 | } 261 | 262 | ColorDrawable transparentDrawable = new ColorDrawable(Color.TRANSPARENT); 263 | 264 | Glide.with(getActivity()) 265 | .load(url) 266 | .crossFade() 267 | .placeholder(transparentDrawable) 268 | .diskCacheStrategy(DiskCacheStrategy.NONE) 269 | .into(photoView); 270 | } 271 | } 272 | -------------------------------------------------------------------------------- /project/app/src/main/java/com/enrico/gallery/galleryapp/utils/MediaBrowser.java: -------------------------------------------------------------------------------- 1 | package com.enrico.gallery.galleryapp.utils; 2 | 3 | import android.content.Intent; 4 | import android.database.Cursor; 5 | import android.graphics.Color; 6 | import android.graphics.drawable.ColorDrawable; 7 | import android.net.Uri; 8 | import android.os.Bundle; 9 | import android.provider.MediaStore; 10 | import android.support.annotation.NonNull; 11 | import android.support.design.widget.BottomSheetBehavior; 12 | import android.support.design.widget.FloatingActionButton; 13 | import android.support.v7.app.AppCompatActivity; 14 | import android.support.v7.view.ContextThemeWrapper; 15 | import android.view.View; 16 | import android.widget.LinearLayout; 17 | 18 | import com.afollestad.easyvideoplayer.EasyVideoCallback; 19 | import com.afollestad.easyvideoplayer.EasyVideoPlayer; 20 | import com.bumptech.glide.Glide; 21 | import com.bumptech.glide.load.engine.DiskCacheStrategy; 22 | import com.enrico.gallery.galleryapp.ImmersiveMode; 23 | import com.enrico.gallery.galleryapp.R; 24 | import com.enrico.gallery.galleryapp.settings.Preferences; 25 | import com.github.chrisbanes.photoview.PhotoView; 26 | import com.theartofdev.edmodo.cropper.CropImage; 27 | 28 | public class MediaBrowser extends AppCompatActivity implements EasyVideoCallback { 29 | 30 | PhotoView photoView; 31 | 32 | BottomSheetBehavior bottomSheetBehavior; 33 | 34 | FloatingActionButton fabPlay; 35 | 36 | String url; 37 | 38 | LinearLayout bottomSheet; 39 | 40 | ContextThemeWrapper contextThemeWrapper; 41 | String type; 42 | private EasyVideoPlayer videoView; 43 | 44 | @Override 45 | public void onPause() { 46 | super.onPause(); 47 | 48 | videoView.pause(); 49 | } 50 | 51 | @Override 52 | public void onCreate(Bundle savedInstanceState) { 53 | 54 | super.onCreate(savedInstanceState); 55 | 56 | runOnUiThread(new Runnable() { 57 | @Override 58 | public void run() { 59 | 60 | contextThemeWrapper = new ContextThemeWrapper(getBaseContext(), MediaBrowser.this.getTheme()); 61 | 62 | Preferences.applyTheme(contextThemeWrapper, getBaseContext()); 63 | 64 | ImmersiveMode.On(MediaBrowser.this); 65 | 66 | } 67 | }); 68 | 69 | setContentView(R.layout.media_pager); 70 | 71 | Intent intent = getIntent(); 72 | String action = intent.getAction(); 73 | type = intent.getType(); 74 | 75 | if (Intent.ACTION_VIEW.equals(action) && type != null) { 76 | 77 | if (type.startsWith("image/") || type.startsWith("video/")) { 78 | 79 | Uri imageUri = intent.getData(); 80 | 81 | url = convertMediaUriToPath(imageUri); 82 | 83 | } 84 | 85 | } 86 | 87 | runOnUiThread(new Runnable() { 88 | @Override 89 | public void run() { 90 | 91 | initViews(); 92 | 93 | initMediaView(); 94 | 95 | } 96 | }); 97 | 98 | } 99 | 100 | @Override 101 | public void onPreparing(EasyVideoPlayer player) { 102 | // TODO handle if needed 103 | } 104 | 105 | @Override 106 | public void onPrepared(EasyVideoPlayer player) { 107 | // TODO handle 108 | } 109 | 110 | @Override 111 | public void onBuffering(int percent) { 112 | // TODO handle if needed 113 | } 114 | 115 | @Override 116 | public void onError(EasyVideoPlayer player, Exception e) { 117 | // TODO handle 118 | } 119 | 120 | @Override 121 | public void onCompletion(EasyVideoPlayer player) { 122 | // TODO handle if needed 123 | 124 | fabPlay.show(new FloatingActionButton.OnVisibilityChangedListener() { 125 | @Override 126 | public void onShown(FloatingActionButton fab) { 127 | photoView.setVisibility(View.VISIBLE); 128 | videoView.setVisibility(View.GONE); 129 | 130 | } 131 | }); 132 | } 133 | 134 | @Override 135 | public void onRetry(EasyVideoPlayer player, Uri source) { 136 | // TODO handle if used 137 | } 138 | 139 | @Override 140 | public void onSubmit(EasyVideoPlayer player, Uri source) { 141 | // TODO handle if used 142 | } 143 | 144 | @Override 145 | public void onStarted(EasyVideoPlayer player) { 146 | // TODO handle if needed 147 | } 148 | 149 | @Override 150 | public void onPaused(EasyVideoPlayer player) { 151 | // TODO handle if needed 152 | } 153 | 154 | @Override 155 | public void onActivityResult(int requestCode, int resultCode, Intent data) { 156 | 157 | if (requestCode == CropImage.CROP_IMAGE_ACTIVITY_REQUEST_CODE) { 158 | CropImage.ActivityResult result = CropImage.getActivityResult(data); 159 | if (resultCode == RESULT_OK) { 160 | final Uri resultUri = result.getUri(); 161 | 162 | SaveTools.saveCrop(MediaBrowser.this, resultUri, url); 163 | 164 | } 165 | } 166 | } 167 | 168 | private void initViews() { 169 | 170 | bottomSheet = (LinearLayout) findViewById(R.id.bottom_sheet_media); 171 | 172 | bottomSheetBehavior = BottomSheetBehavior.from(bottomSheet); 173 | 174 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 175 | 176 | photoView = (PhotoView) findViewById(R.id.photoView); 177 | 178 | videoView = (EasyVideoPlayer) findViewById(R.id.videoView); 179 | 180 | fabPlay = (FloatingActionButton) findViewById(R.id.fab_play); 181 | 182 | } 183 | 184 | private void initMediaView() { 185 | 186 | if (url.contains(type)) { 187 | 188 | videoView.setCallback(this); 189 | 190 | videoView.setSource(Uri.parse(url)); 191 | 192 | fabPlay.show(); 193 | fabPlay.setOnClickListener(new View.OnClickListener() { 194 | @Override 195 | public void onClick(View v) { 196 | videoView.setVisibility(View.VISIBLE); 197 | photoView.setVisibility(View.GONE); 198 | 199 | if (bottomSheetBehavior.getState() == BottomSheetBehavior.STATE_COLLAPSED) { 200 | bottomSheetBehavior.setState(BottomSheetBehavior.STATE_HIDDEN); 201 | } 202 | 203 | fabPlay.hide(new FloatingActionButton.OnVisibilityChangedListener() { 204 | @Override 205 | public void onHidden(FloatingActionButton fab) { 206 | 207 | videoView.start(); 208 | 209 | } 210 | }); 211 | } 212 | }); 213 | 214 | photoView.setOnLongClickListener(new View.OnLongClickListener() { 215 | @Override 216 | public boolean onLongClick(View v) { 217 | 218 | BottomSheetMediaActions.show(MediaBrowser.this, bottomSheet, url, null); 219 | 220 | bottomSheetBehavior.setBottomSheetCallback(new BottomSheetBehavior.BottomSheetCallback() { 221 | @Override 222 | public void onStateChanged(@NonNull View bottomSheet, int newState) { 223 | 224 | switch (newState) { 225 | case BottomSheetBehavior.STATE_EXPANDED: 226 | 227 | fabPlay.hide(); 228 | break; 229 | case BottomSheetBehavior.STATE_COLLAPSED: 230 | 231 | fabPlay.show(); 232 | break; 233 | 234 | case BottomSheetBehavior.STATE_HIDDEN: 235 | 236 | if (!videoView.isShown()) { 237 | fabPlay.show(); 238 | } 239 | } 240 | } 241 | 242 | @Override 243 | public void onSlide(@NonNull View bottomSheet, float slideOffset) { 244 | 245 | } 246 | }); 247 | 248 | return false; 249 | } 250 | }); 251 | } else { 252 | 253 | photoView.setOnLongClickListener(new View.OnLongClickListener() { 254 | @Override 255 | public boolean onLongClick(View v) { 256 | 257 | BottomSheetMediaActions.show(MediaBrowser.this, bottomSheet, url, null); 258 | return false; 259 | } 260 | }); 261 | } 262 | 263 | ColorDrawable transparentDrawable = new ColorDrawable(Color.TRANSPARENT); 264 | 265 | Glide.with(this) 266 | .load(url) 267 | .crossFade() 268 | .placeholder(transparentDrawable) 269 | .diskCacheStrategy(DiskCacheStrategy.NONE) 270 | .into(photoView); 271 | } 272 | 273 | protected String convertMediaUriToPath(Uri uri) { 274 | 275 | String filePath = ""; 276 | 277 | Cursor cursor = this.getContentResolver().query(uri, new String[]{MediaStore.MediaColumns.DATA}, null, null, null); 278 | 279 | if (cursor != null) { 280 | cursor.moveToFirst(); 281 | filePath = cursor.getString(0); 282 | cursor.close(); 283 | } 284 | 285 | return filePath; 286 | } 287 | } 288 | --------------------------------------------------------------------------------