From 178d19ad3a8a6659215d9aa868e17b55eb954a48 Mon Sep 17 00:00:00 2001 From: fajarnandagusti Date: Sat, 3 Oct 2020 04:16:51 +0700 Subject: [PATCH] added Catalogue Movie from TMDB with SQLite Fav Movie --- .../CatalogueMovieSqLiteFavorite/.gitignore | 9 + .../.idea/caches/build_file_checksums.ser | Bin 0 -> 596 bytes .../.idea/codeStyles/Project.xml | 29 +++ .../.idea/gradle.xml | 19 ++ .../.idea/misc.xml | 44 ++++ .../.idea/modules.xml | 10 + .../.idea/runConfigurations.xml | 12 + .../app/.gitignore | 1 + .../app/build.gradle | 54 +++++ .../app/proguard-rules.pro | 21 ++ .../ExampleInstrumentedTest.java | 26 ++ .../app/src/main/AndroidManifest.xml | 74 ++++++ .../activity/DetailMovieActivity.java | 151 ++++++++++++ .../activity/FavoriteActivity.java | 98 ++++++++ .../activity/MainActivity.java | 224 ++++++++++++++++++ .../activity/NowPlayingActivity.java | 119 ++++++++++ .../activity/SettingActivity.java | 143 +++++++++++ .../activity/UpcomingActivity.java | 129 ++++++++++ .../adapter/FavoriteAdapter.java | 129 ++++++++++ .../adapter/MovieAdapter.java | 118 +++++++++ .../cataloguemoviefinal/api/ApiService.java | 29 +++ .../cataloguemoviefinal/api/Client.java | 29 +++ .../cataloguemoviefinal/api/Server.java | 13 + .../database/DatabaseContract.java | 37 +++ .../database/DatabaseHelper.java | 55 +++++ .../database/FavoriteHelper.java | 137 +++++++++++ .../cataloguemoviefinal/model/Favorite.java | 127 ++++++++++ .../cataloguemoviefinal/model/Movies.java | 113 +++++++++ .../model/ResponseMovie.java | 48 ++++ .../provider/MovieProvider.java | 127 ++++++++++ .../scheduler/DailyReminderReceiver.java | 72 ++++++ .../scheduler/NotificationHelper.java | 59 +++++ .../scheduler/ReleaseReminderReceiver.java | 113 +++++++++ .../scheduler/ReminderPreference.java | 38 +++ .../cataloguemoviefinal/utils/DateFormat.java | 27 +++ .../cataloguemoviefinal/utils/Utility.java | 52 ++++ .../widget/ImageBannerWidget.java | 99 ++++++++ .../widget/StackRemoteViewFactory.java | 126 ++++++++++ .../widget/StackWidgetService.java | 15 ++ .../example_appwidget_preview.png | Bin 0 -> 3522 bytes .../main/res/drawable-v21/ic_menu_camera.xml | 12 + .../main/res/drawable-v21/ic_menu_gallery.xml | 9 + .../main/res/drawable-v21/ic_menu_manage.xml | 9 + .../main/res/drawable-v21/ic_menu_send.xml | 9 + .../main/res/drawable-v21/ic_menu_share.xml | 9 + .../res/drawable-v21/ic_menu_slideshow.xml | 9 + .../drawable-v24/ic_launcher_foreground.xml | 34 +++ .../drawable/baseline_av_timer_black_24dp.png | Bin 0 -> 624 bytes ...aseline_play_circle_outline_black_24dp.png | Bin 0 -> 632 bytes .../app/src/main/res/drawable/bg.jpeg | Bin 0 -> 61016 bytes .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++ .../res/drawable/ic_search_white_24px.xml | 5 + .../src/main/res/drawable/ic_star_checked.xml | 5 + .../main/res/drawable/ic_star_unchecked.xml | 5 + .../main/res/drawable/ic_stars_black_24dp.xml | 9 + .../app/src/main/res/drawable/ph.png | Bin 0 -> 265 bytes .../src/main/res/drawable/side_nav_bar.xml | 9 + .../app/src/main/res/drawable/tmdb.png | Bin 0 -> 6043 bytes .../main/res/layout/activity_detail_movie.xml | 77 ++++++ .../src/main/res/layout/activity_favorite.xml | 17 ++ .../app/src/main/res/layout/activity_main.xml | 25 ++ .../main/res/layout/activity_now_playing.xml | 23 ++ .../src/main/res/layout/activity_setting.xml | 51 ++++ .../src/main/res/layout/activity_upcoming.xml | 22 ++ .../app/src/main/res/layout/app_bar_main.xml | 25 ++ .../app/src/main/res/layout/content_main.xml | 17 ++ .../main/res/layout/image_banner_widget.xml | 50 ++++ .../app/src/main/res/layout/list_movies.xml | 109 +++++++++ .../src/main/res/layout/nav_header_main.xml | 35 +++ .../app/src/main/res/layout/widget_items.xml | 23 ++ .../main/res/menu/activity_main_drawer.xml | 23 ++ .../app/src/main/res/menu/main.xml | 14 ++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes .../app/src/main/res/values-in/strings.xml | 37 +++ .../app/src/main/res/values-v14/dimens.xml | 10 + .../app/src/main/res/values-v21/styles.xml | 8 + .../app/src/main/res/values/colors.xml | 6 + .../app/src/main/res/values/dimens.xml | 14 ++ .../app/src/main/res/values/drawables.xml | 8 + .../app/src/main/res/values/strings.xml | 37 +++ .../app/src/main/res/values/styles.xml | 20 ++ .../main/res/xml/image_banner_widget_info.xml | 9 + .../cataloguemoviefinal/ExampleUnitTest.java | 17 ++ .../CatalogueMovieSqLiteFavorite/build.gradle | 27 +++ .../filmfavoritku/.gitignore | 1 + .../filmfavoritku/build.gradle | 55 +++++ .../filmfavoritku/proguard-rules.pro | 21 ++ .../ExampleInstrumentedTest.java | 26 ++ .../src/main/AndroidManifest.xml | 28 +++ .../filmfavoritku/DetailActivity.java | 75 ++++++ .../filmfavoritku/MainActivity.java | 62 +++++ .../filmfavoritku/adapter/MovieAdapter.java | 81 +++++++ .../filmfavoritku/db/DatabaseContract.java | 37 +++ .../filmfavoritku/model/MovieItem.java | 127 ++++++++++ .../filmfavoritku/utils/Utility.java | 10 + .../drawable-v24/ic_launcher_foreground.xml | 34 +++ .../src/main/res/drawable/bg.jpeg | Bin 0 -> 61016 bytes .../res/drawable/ic_launcher_background.xml | 170 +++++++++++++ .../src/main/res/drawable/ic_star_checked.xml | 5 + .../main/res/drawable/ic_star_unchecked.xml | 5 + .../src/main/res/drawable/ph.png | Bin 0 -> 265 bytes .../src/main/res/layout/activity_detail.xml | 64 +++++ .../src/main/res/layout/activity_main.xml | 18 ++ .../src/main/res/layout/list_favorite.xml | 113 +++++++++ .../res/mipmap-anydpi-v26/ic_launcher.xml | 5 + .../mipmap-anydpi-v26/ic_launcher_round.xml | 5 + .../src/main/res/mipmap-hdpi/ic_launcher.png | Bin 0 -> 3056 bytes .../res/mipmap-hdpi/ic_launcher_round.png | Bin 0 -> 5024 bytes .../src/main/res/mipmap-mdpi/ic_launcher.png | Bin 0 -> 2096 bytes .../res/mipmap-mdpi/ic_launcher_round.png | Bin 0 -> 2858 bytes .../src/main/res/mipmap-xhdpi/ic_launcher.png | Bin 0 -> 4569 bytes .../res/mipmap-xhdpi/ic_launcher_round.png | Bin 0 -> 7098 bytes .../main/res/mipmap-xxhdpi/ic_launcher.png | Bin 0 -> 6464 bytes .../res/mipmap-xxhdpi/ic_launcher_round.png | Bin 0 -> 10676 bytes .../main/res/mipmap-xxxhdpi/ic_launcher.png | Bin 0 -> 9250 bytes .../res/mipmap-xxxhdpi/ic_launcher_round.png | Bin 0 -> 15523 bytes .../src/main/res/values/colors.xml | 6 + .../src/main/res/values/strings.xml | 6 + .../src/main/res/values/styles.xml | 11 + .../filmfavoritku/ExampleUnitTest.java | 17 ++ .../gradle.properties | 17 ++ .../gradle/wrapper/gradle-wrapper.jar | Bin 0 -> 53636 bytes .../gradle/wrapper/gradle-wrapper.properties | 6 + .../CatalogueMovieSqLiteFavorite/gradlew | 160 +++++++++++++ .../CatalogueMovieSqLiteFavorite/gradlew.bat | 90 +++++++ .../settings.gradle | 1 + 137 files changed, 4990 insertions(+) create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.gitignore create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.idea/caches/build_file_checksums.ser create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.idea/codeStyles/Project.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.idea/gradle.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.idea/misc.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.idea/modules.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/.idea/runConfigurations.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/.gitignore create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/build.gradle create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/proguard-rules.pro create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/androidTest/java/com/fajarnandagusti/cataloguemoviefinal/ExampleInstrumentedTest.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/AndroidManifest.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/DetailMovieActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/FavoriteActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/MainActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/NowPlayingActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/SettingActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/UpcomingActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/FavoriteAdapter.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/MovieAdapter.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/ApiService.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Client.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Server.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseContract.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseHelper.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/FavoriteHelper.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Favorite.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Movies.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/ResponseMovie.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/provider/MovieProvider.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/DailyReminderReceiver.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/NotificationHelper.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReleaseReminderReceiver.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReminderPreference.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/DateFormat.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/Utility.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/ImageBannerWidget.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackRemoteViewFactory.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackWidgetService.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-nodpi/example_appwidget_preview.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_camera.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_gallery.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_manage.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_send.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_share.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_slideshow.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/baseline_av_timer_black_24dp.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/baseline_play_circle_outline_black_24dp.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/bg.jpeg create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_launcher_background.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_search_white_24px.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_checked.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_unchecked.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_stars_black_24dp.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ph.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/side_nav_bar.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/tmdb.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_detail_movie.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_favorite.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_main.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_now_playing.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_setting.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_upcoming.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/app_bar_main.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/content_main.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/image_banner_widget.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/list_movies.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/nav_header_main.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/widget_items.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/menu/activity_main_drawer.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/menu/main.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values-in/strings.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values-v14/dimens.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values-v21/styles.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values/colors.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values/dimens.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values/drawables.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values/strings.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/values/styles.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/xml/image_banner_widget_info.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/app/src/test/java/com/fajarnandagusti/cataloguemoviefinal/ExampleUnitTest.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/build.gradle create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/.gitignore create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/build.gradle create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/proguard-rules.pro create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/androidTest/java/com/fajarnandagusti/filmfavoritku/ExampleInstrumentedTest.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/AndroidManifest.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/java/com/fajarnandagusti/filmfavoritku/DetailActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/java/com/fajarnandagusti/filmfavoritku/MainActivity.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/java/com/fajarnandagusti/filmfavoritku/adapter/MovieAdapter.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/java/com/fajarnandagusti/filmfavoritku/db/DatabaseContract.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/java/com/fajarnandagusti/filmfavoritku/model/MovieItem.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/java/com/fajarnandagusti/filmfavoritku/utils/Utility.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/drawable-v24/ic_launcher_foreground.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/drawable/bg.jpeg create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/drawable/ic_launcher_background.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/drawable/ic_star_checked.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/drawable/ic_star_unchecked.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/drawable/ph.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/layout/activity_detail.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/layout/activity_main.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/layout/list_favorite.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-anydpi-v26/ic_launcher.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-hdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-hdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-mdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-mdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-xhdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-xhdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-xxhdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-xxhdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-xxxhdpi/ic_launcher.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/values/colors.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/values/strings.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/main/res/values/styles.xml create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/filmfavoritku/src/test/java/com/fajarnandagusti/filmfavoritku/ExampleUnitTest.java create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/gradle.properties create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/gradle/wrapper/gradle-wrapper.jar create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/gradle/wrapper/gradle-wrapper.properties create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/gradlew create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/gradlew.bat create mode 100644 Android Projects/CatalogueMovieSqLiteFavorite/settings.gradle diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.gitignore b/Android Projects/CatalogueMovieSqLiteFavorite/.gitignore new file mode 100644 index 00000000..39fb081a --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/.gitignore @@ -0,0 +1,9 @@ +*.iml +.gradle +/local.properties +/.idea/workspace.xml +/.idea/libraries +.DS_Store +/build +/captures +.externalNativeBuild diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.idea/caches/build_file_checksums.ser b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/caches/build_file_checksums.ser new file mode 100644 index 0000000000000000000000000000000000000000..ea6617a021c1df4f5ef51dbf8e2b3f584a1e5113 GIT binary patch literal 596 zcmZ4UmVvdnh`~NNKUXg?FQq6yGexf?KR>5fFEb@IQ7^qHF(oHeub?PDD>b=9F91S2 zm1gFoxMk*~I%lLNXBU^|7Q2L-Ts|(GuF1r}Q#7BMhIJFWRF{)3Gp0X*3x%g4V z!lv}=DiuKIAhoC@Gqt!Bu9%InZs(5}59gB^s+)oj9p6~OpyO;66Iz^F zR2<`8T3nKuSe}>{19eOcB91T&x+2?iv!7uT%gYAN8E<|#)s-+vrDf*irX`l;7iE@Y ym!bv--2Ppcw>|m)Lc>8fPyLow5TA4jgCHJDY7J)!WbIXtYX7A#Z~uSenhF5nP10ci literal 0 HcmV?d00001 diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.idea/codeStyles/Project.xml b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/codeStyles/Project.xml new file mode 100644 index 00000000..30aa626c --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/codeStyles/Project.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.idea/gradle.xml b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/gradle.xml new file mode 100644 index 00000000..2bf9ae92 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/gradle.xml @@ -0,0 +1,19 @@ + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.idea/misc.xml b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/misc.xml new file mode 100644 index 00000000..9e762bbd --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/misc.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.idea/modules.xml b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/modules.xml new file mode 100644 index 00000000..2a5ac026 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/modules.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/.idea/runConfigurations.xml b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/runConfigurations.xml new file mode 100644 index 00000000..7f68460d --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/.idea/runConfigurations.xml @@ -0,0 +1,12 @@ + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/.gitignore b/Android Projects/CatalogueMovieSqLiteFavorite/app/.gitignore new file mode 100644 index 00000000..796b96d1 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/.gitignore @@ -0,0 +1 @@ +/build diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/build.gradle b/Android Projects/CatalogueMovieSqLiteFavorite/app/build.gradle new file mode 100644 index 00000000..4cfe34ae --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/build.gradle @@ -0,0 +1,54 @@ +apply plugin: 'com.android.application' + +android { + compileSdkVersion 26 + defaultConfig { + applicationId "com.fajarnandagusti.cataloguemoviefinal" + minSdkVersion 19 + targetSdkVersion 26 + versionCode 1 + versionName "1.0" + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + } + buildTypes { + release { + minifyEnabled false + proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro' + } + } + buildTypes.each { + it.buildConfigField 'String', 'API_KEY', ApiKey + } +} +ext { + butterknifeVersion = "8.8.1" +} + +dependencies { + implementation fileTree(dir: 'libs', include: ['*.jar']) + implementation 'com.android.support:appcompat-v7:26.1.0' + implementation 'com.android.support:design:26.1.0' + implementation 'com.android.support.constraint:constraint-layout:1.1.3' + implementation 'com.android.support:support-v4:26.1.0' + testImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.2' + androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' + implementation 'com.android.support:support-annotations:27.1.1' + + implementation 'com.android.support:recyclerview-v7:26.1.0' + implementation 'com.android.support:cardview-v7:26.1.0' + + implementation 'com.github.bumptech.glide:glide:3.7.0' + + implementation 'com.squareup.retrofit2:retrofit:2.1.0' + implementation 'com.squareup.retrofit2:converter-gson:2.1.0' + implementation 'com.google.code.gson:gson:2.8.0' + implementation 'com.google.code.gson:gson:2.6.2' + + implementation 'com.squareup.retrofit2:retrofit:2.0.2' + implementation 'com.squareup.retrofit2:converter-gson:2.0.2' + implementation 'com.squareup.okhttp3:logging-interceptor:3.4.1' + implementation "com.jakewharton:butterknife:$butterknifeVersion" + annotationProcessor "com.jakewharton:butterknife-compiler:$butterknifeVersion" + +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/proguard-rules.pro b/Android Projects/CatalogueMovieSqLiteFavorite/app/proguard-rules.pro new file mode 100644 index 00000000..f1b42451 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/proguard-rules.pro @@ -0,0 +1,21 @@ +# Add project specific ProGuard rules here. +# You can control the set of applied configuration files using the +# proguardFiles setting in build.gradle. +# +# For more details, see +# http://developer.android.com/guide/developing/tools/proguard.html + +# If your project uses WebView with JS, uncomment the following +# and specify the fully qualified class name to the JavaScript interface +# class: +#-keepclassmembers class fqcn.of.javascript.interface.for.webview { +# public *; +#} + +# Uncomment this to preserve the line number information for +# debugging stack traces. +#-keepattributes SourceFile,LineNumberTable + +# If you keep the line number information, uncomment this to +# hide the original source file name. +#-renamesourcefileattribute SourceFile diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/androidTest/java/com/fajarnandagusti/cataloguemoviefinal/ExampleInstrumentedTest.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/androidTest/java/com/fajarnandagusti/cataloguemoviefinal/ExampleInstrumentedTest.java new file mode 100644 index 00000000..bcc27ac9 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/androidTest/java/com/fajarnandagusti/cataloguemoviefinal/ExampleInstrumentedTest.java @@ -0,0 +1,26 @@ +package com.fajarnandagusti.cataloguemoviefinal; + +import android.content.Context; +import android.support.test.InstrumentationRegistry; +import android.support.test.runner.AndroidJUnit4; + +import org.junit.Test; +import org.junit.runner.RunWith; + +import static org.junit.Assert.*; + +/** + * Instrumented test, which will execute on an Android device. + * + * @see Testing documentation + */ +@RunWith(AndroidJUnit4.class) +public class ExampleInstrumentedTest { + @Test + public void useAppContext() throws Exception { + // Context of the app under test. + Context appContext = InstrumentationRegistry.getTargetContext(); + + assertEquals("com.fajarnandagusti.cataloguemoviefinal", appContext.getPackageName()); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/AndroidManifest.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/AndroidManifest.xml new file mode 100644 index 00000000..d76ad502 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/AndroidManifest.xml @@ -0,0 +1,74 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/DetailMovieActivity.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/DetailMovieActivity.java new file mode 100644 index 00000000..561d8d12 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/DetailMovieActivity.java @@ -0,0 +1,151 @@ +package com.fajarnandagusti.cataloguemoviefinal.activity; + +import android.content.ContentValues; +import android.database.Cursor; +import android.net.Uri; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.MenuItem; +import android.view.View; +import android.widget.ImageView; +import android.widget.LinearLayout; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract; +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +import java.util.Objects; + +import butterknife.BindView; +import butterknife.ButterKnife; + +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.CONTENT_URI; + +public class DetailMovieActivity extends AppCompatActivity { + @BindView(R.id.detPoster) + ImageView detPoster; + @BindView(R.id.detJudul) + TextView detJudul; + @BindView(R.id.detTgl) + TextView detTgl; + @BindView(R.id.detPopular) + TextView detPopular; + @BindView(R.id.detDesc) + TextView detDesc; + @BindView(R.id.fav) + ImageView btnFav; + @BindView(R.id.linear) + LinearLayout linearLayout; + + String image, judul, tgl, popular, desc; + private long id; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_detail_movie); + + ButterKnife.bind(this); + + getParcel(); + bindMovie(); + setFavorite(); + + Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + private void getParcel() { + image = getIntent().getStringExtra("poster_path"); + judul = getIntent().getStringExtra("title"); + tgl = getIntent().getStringExtra("release_date"); + popular = getIntent().getStringExtra("popularity"); + desc = getIntent().getStringExtra("overview"); + } + + private void bindMovie() { + Glide.with(getApplicationContext()) + .load(Utility.URL+image) + .placeholder(R.drawable.ph) + .error(R.drawable.bg) + .into(detPoster); + + detJudul.setText(judul); + detTgl.setText(tgl); + detPopular.setText(popular); + detDesc.setText(desc); + btnFav.setImageResource(R.drawable.ic_star_unchecked); + } + + public void clickFav(View view){ + if (setFavorite()){ + Uri uri = Uri.parse(CONTENT_URI+"/"+id); + getContentResolver().delete(uri, null, null); + btnFav.setImageResource(R.drawable.ic_star_unchecked); + }else { + + ContentValues contentValues = new ContentValues(); + + contentValues.put(DatabaseContract.FavoriteColumn.POSTER, image); + contentValues.put(DatabaseContract.FavoriteColumn.TITLE, judul); + contentValues.put(DatabaseContract.FavoriteColumn.RELEASE, tgl); + contentValues.put(DatabaseContract.FavoriteColumn.POPULARITY, popular); + contentValues.put(DatabaseContract.FavoriteColumn.OVERVIEW, desc); + + getContentResolver().insert(CONTENT_URI, contentValues); + setResult(101); + + btnFav.setImageResource(R.drawable.ic_star_checked); + + showSnackbarMessage(R.string.addto); + } + } + + private void showSnackbarMessage(int message) { + Snackbar.make(linearLayout, message, Snackbar.LENGTH_SHORT).show(); + } + + + private boolean setFavorite() { + Uri uri = Uri.parse(CONTENT_URI + ""); + boolean favorite = false; + Cursor cursor = getContentResolver().query(uri, null, null, null, null); + + String getTitle; + + assert cursor != null; + if (cursor.moveToFirst()) { + do { + id = cursor.getLong(0); + getTitle = cursor.getString(1); + if (getTitle.equals(getIntent().getStringExtra("title"))) { + btnFav.setImageResource(R.drawable.ic_star_checked); + favorite = true; + } + } while (cursor.moveToNext()); + + } + return favorite; + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()){ + case android.R.id.home : { + finish(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + break; + } + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/FavoriteActivity.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/FavoriteActivity.java new file mode 100644 index 00000000..c64c3521 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/FavoriteActivity.java @@ -0,0 +1,98 @@ +package com.fajarnandagusti.cataloguemoviefinal.activity; + +import android.database.Cursor; +import android.os.AsyncTask; +import android.support.design.widget.CoordinatorLayout; +import android.support.design.widget.Snackbar; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.MenuItem; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.adapter.FavoriteAdapter; + +import java.util.Objects; + +import butterknife.BindView; +import butterknife.ButterKnife; + +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.CONTENT_URI; + +public class FavoriteActivity extends AppCompatActivity { + @BindView(R.id.recycler_movie) + RecyclerView recyclerView; + + @BindView(R.id.Favorite) + CoordinatorLayout favoriteLayout; + + private FavoriteAdapter favoriteAdapter; + private Cursor cursor; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_favorite); + ButterKnife.bind(this); + + recyclerView.setLayoutManager(new LinearLayoutManager(this)); + recyclerView.setHasFixedSize(true); + favoriteAdapter = new FavoriteAdapter(this); + favoriteAdapter.setFavoriteList(cursor); + recyclerView.setAdapter(favoriteAdapter); + + new LoadFavoriteMovie().execute(); + + Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + + } + + private class LoadFavoriteMovie extends AsyncTask { + @Override + protected Cursor doInBackground(Void... voids) { + return getContentResolver().query(CONTENT_URI, null, null, null, null); + } + + @Override + protected void onPreExecute(){ + + } + + @Override + protected void onPostExecute(Cursor favorite){ + super.onPostExecute(favorite); + + cursor = favorite; + favoriteAdapter.setFavoriteList(cursor); + favoriteAdapter.notifyDataSetChanged(); + + if (cursor.getCount() == 0){ + showSnackbarMessage(R.string.Empty); + } + } + } + + private void showSnackbarMessage(int message) { + Snackbar.make(favoriteLayout, message, Snackbar.LENGTH_SHORT).show(); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()){ + case android.R.id.home : { + finish(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + break; + } + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/MainActivity.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/MainActivity.java new file mode 100644 index 00000000..9617cd2b --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/MainActivity.java @@ -0,0 +1,224 @@ +package com.fajarnandagusti.cataloguemoviefinal.activity; + +import android.app.ProgressDialog; +import android.content.Intent; +import android.os.Bundle; +import android.support.v4.app.Fragment; +import android.support.design.widget.NavigationView; +import android.support.v4.view.GravityCompat; + +import android.support.v4.view.MenuItemCompat; +import android.support.v4.widget.DrawerLayout; +import android.support.v7.app.ActionBarDrawerToggle; +import android.support.v7.app.AppCompatActivity; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.support.v7.widget.Toolbar; +import android.text.TextUtils; +import android.view.Menu; +import android.view.MenuItem; +import android.widget.SearchView; +import android.widget.Toast; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.adapter.MovieAdapter; +import com.fajarnandagusti.cataloguemoviefinal.api.ApiService; +import com.fajarnandagusti.cataloguemoviefinal.api.Server; +import com.fajarnandagusti.cataloguemoviefinal.model.Movies; +import com.fajarnandagusti.cataloguemoviefinal.model.ResponseMovie; +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +import java.util.ArrayList; +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class MainActivity extends AppCompatActivity + implements NavigationView.OnNavigationItemSelectedListener { + + @BindView(R.id.recycler_movie) + RecyclerView recyclerView; + + ApiService API; + ProgressDialog loading; + List listMovies; + private MovieAdapter movieAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_main); + Toolbar toolbar = findViewById(R.id.toolbar); + setSupportActionBar(toolbar); + + ButterKnife.bind(this); + API = Server.getAPIService(); + + preload(); + + if (savedInstanceState == null) { + load(); + }else{ + listMovies = savedInstanceState.getParcelableArrayList(Utility.KEY_PARCELABLE); + movieAdapter = new MovieAdapter(getApplicationContext(), listMovies); + recyclerView.setAdapter(movieAdapter); + } + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + ActionBarDrawerToggle toggle = new ActionBarDrawerToggle( + this, drawer, toolbar, R.string.navigation_drawer_open, R.string.navigation_drawer_close); + drawer.addDrawerListener(toggle); + toggle.syncState(); + + NavigationView navigationView = findViewById(R.id.nav_view); + navigationView.setNavigationItemSelectedListener(this); + } + + protected void onSaveInstanceState(Bundle outState) { + outState.putParcelableArrayList(Utility.KEY_PARCELABLE, new ArrayList<>(listMovies)); + super.onSaveInstanceState(outState); + } + + private void preload() { + movieAdapter = new MovieAdapter(getApplicationContext(), listMovies); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + recyclerView.setAdapter(movieAdapter); + } + + private void load() { + loading = ProgressDialog.show(this, null, "Loading...", true, false); + + API.getAllMovies(Utility.API_KEY).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + loading.dismiss(); + listMovies = response.body().getMovies(); + recyclerView.setAdapter(new MovieAdapter(getApplicationContext(), listMovies)); + + movieAdapter.notifyDataSetChanged(); //ini penting, kalau gak ada, data gak tampil + + }else { + loading.dismiss(); + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + loading.dismiss(); + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_SHORT).show(); + } + }); + } + + + @Override + public void onBackPressed() { + DrawerLayout drawer = findViewById(R.id.drawer_layout); + if (drawer.isDrawerOpen(GravityCompat.START)) { + drawer.closeDrawer(GravityCompat.START); + } else { + super.onBackPressed(); + } + } + + @Override + public boolean onCreateOptionsMenu(Menu menu) { + getMenuInflater().inflate(R.menu.main, menu); + + SearchView searchView = (SearchView) MenuItemCompat.getActionView(menu.findItem(R.id.search)); + searchView.setQueryHint(getResources().getString(R.string.search)); + + searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() { + + @Override + public boolean onQueryTextSubmit(String query) { + cariFilm(query); + return true; + } + + @Override + public boolean onQueryTextChange(String newText) { + if (TextUtils.isEmpty(newText)){ + load(); + } + return false; + } + }); + + return true; + } + + private void cariFilm(String query) { + API.getSearchMovie(Utility.API_KEY, Utility.LANGUAGE, query, Utility.page, Utility.include_adult) + .enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + listMovies = response.body().getMovies(); + recyclerView.setAdapter(new MovieAdapter(getApplicationContext(), listMovies)); + movieAdapter.notifyDataSetChanged(); + } + else { + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_LONG).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + Toast.makeText(getApplicationContext(), getString(R.string.internet), Toast.LENGTH_SHORT).show(); + } + }); + } + + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + // Handle action bar item clicks here. The action bar will + // automatically handle clicks on the Home/Up button, so long + // as you specify a parent activity in AndroidManifest.xml. + int id = item.getItemId(); + + //noinspection SimplifiableIfStatement + if (id == R.id.action_settings) { + Intent setting = new Intent(getApplicationContext(), SettingActivity.class); + startActivity(setting); + return true; + } + + return super.onOptionsItemSelected(item); + } + + @SuppressWarnings("StatementWithEmptyBody") + @Override + public boolean onNavigationItemSelected(MenuItem item) { + // Handle navigation view item clicks here. + int id = item.getItemId(); + + if (id == R.id.now_playing) { + Intent now = new Intent(getApplicationContext(), NowPlayingActivity.class); + startActivity(now); + Toast.makeText(getApplicationContext(), "Show Now Playing Movies", Toast.LENGTH_SHORT).show(); + + } else if (id == R.id.upcoming) { + Intent up = new Intent(getApplicationContext(), UpcomingActivity.class); + startActivity(up); + Toast.makeText(getApplicationContext(), "Show Upcoming Movies", Toast.LENGTH_SHORT).show(); + + } else if (id == R.id.favorite) { + Intent fav = new Intent(getApplicationContext(), FavoriteActivity.class); + startActivity(fav); + Toast.makeText(getApplicationContext(), "Show Favorite Movies", Toast.LENGTH_SHORT).show(); + } + + DrawerLayout drawer = findViewById(R.id.drawer_layout); + drawer.closeDrawer(GravityCompat.START); + return true; + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/NowPlayingActivity.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/NowPlayingActivity.java new file mode 100644 index 00000000..bd95cc9d --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/NowPlayingActivity.java @@ -0,0 +1,119 @@ +package com.fajarnandagusti.cataloguemoviefinal.activity; + +import android.app.ProgressDialog; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.MenuItem; +import android.widget.Toast; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.adapter.MovieAdapter; +import com.fajarnandagusti.cataloguemoviefinal.api.ApiService; +import com.fajarnandagusti.cataloguemoviefinal.api.Server; +import com.fajarnandagusti.cataloguemoviefinal.model.Movies; +import com.fajarnandagusti.cataloguemoviefinal.model.ResponseMovie; +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import butterknife.BindView; +import butterknife.ButterKnife; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class NowPlayingActivity extends AppCompatActivity { + @BindView(R.id.recycler_movie) + RecyclerView recyclerView; + + ApiService API; + ProgressDialog loading; + List listMovies; + private MovieAdapter movieAdapter; + + public final String KEY_PARCELABLE ="key_parcelable"; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_now_playing); + + ButterKnife.bind(this); + API = Server.getAPIService(); + + preload(); + + if (savedInstanceState == null) { + load(); + }else{ + listMovies = savedInstanceState.getParcelableArrayList(Utility.KEY_PARCELABLE); + movieAdapter = new MovieAdapter(getApplicationContext(), listMovies); + recyclerView.setAdapter(movieAdapter); + } + + Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + protected void onSaveInstanceState(Bundle outState) { + outState.putParcelableArrayList(Utility.KEY_PARCELABLE, new ArrayList<>(listMovies)); + super.onSaveInstanceState(outState); + + } + + private void preload() { + movieAdapter = new MovieAdapter(getApplicationContext(), listMovies); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + recyclerView.setAdapter(movieAdapter); + } + + private void load() { + + loading = ProgressDialog.show(this, null, "Loading...", true, false); + + API.getNowPlayingMovie(Utility.API_KEY).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + loading.dismiss(); + listMovies = response.body().getMovies(); + recyclerView.setAdapter(new MovieAdapter(getApplicationContext(), listMovies)); + movieAdapter.notifyDataSetChanged(); + + }else { + loading.dismiss(); + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + loading.dismiss(); + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_SHORT).show(); + } + }); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()){ + case android.R.id.home : { + finish(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + break; + } + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/SettingActivity.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/SettingActivity.java new file mode 100644 index 00000000..24378864 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/SettingActivity.java @@ -0,0 +1,143 @@ +package com.fajarnandagusti.cataloguemoviefinal.activity; + +import android.content.Intent; +import android.content.SharedPreferences; +import android.content.res.Configuration; +import android.provider.Settings; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.view.View; +import android.widget.Switch; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.scheduler.DailyReminderReceiver; +import com.fajarnandagusti.cataloguemoviefinal.scheduler.ReleaseReminderReceiver; +import com.fajarnandagusti.cataloguemoviefinal.scheduler.ReminderPreference; + +import butterknife.BindView; +import butterknife.ButterKnife; +import butterknife.OnCheckedChanged; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_FIELD_DAILY_REMINDER; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_FIELD_UPCOMING_REMINDER; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_HEADER_DAILY_REMINDER; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_HEADER_UPCOMING_REMINDER; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.TYPE_REMINDER_PREF; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.TYPE_REMINDER_RECIEVE; + +public class SettingActivity extends AppCompatActivity { + @BindView(R.id.dailyReminder) + Switch dailyReminder; + @BindView(R.id.releaseReminder) + Switch releaseReminder; + + public DailyReminderReceiver dailyReminderReceiver; + public ReleaseReminderReceiver releaseReminderReceiver; + public ReminderPreference reminderPreference; + public SharedPreferences sReleaseReminder, sDailyReminder; + public SharedPreferences.Editor editorReleaseReminder, editorDailyReminder; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_setting); + + ButterKnife.bind(this); + + dailyReminderReceiver = new DailyReminderReceiver(); + releaseReminderReceiver = new ReleaseReminderReceiver(); + reminderPreference = new ReminderPreference(this); + setPreference(); + + getSupportActionBar().setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setHomeButtonEnabled(true); + getSupportActionBar().setTitle("Settings"); + } + + private void setPreference() { + sReleaseReminder = getSharedPreferences(KEY_HEADER_UPCOMING_REMINDER, MODE_PRIVATE); + sDailyReminder = getSharedPreferences(KEY_HEADER_DAILY_REMINDER, MODE_PRIVATE); + boolean checkSwUpcomingReminder = sReleaseReminder.getBoolean(KEY_FIELD_UPCOMING_REMINDER, false); + releaseReminder.setChecked(checkSwUpcomingReminder); + boolean checkSwDailyReminder = sDailyReminder.getBoolean(KEY_FIELD_DAILY_REMINDER, false); + dailyReminder.setChecked(checkSwDailyReminder); + } + + @Override + public void onConfigurationChanged(Configuration newConfig) { + super.onConfigurationChanged(newConfig); + } + + @OnCheckedChanged(R.id.dailyReminder) + public void setDailyRemind(boolean isChecked){ + editorDailyReminder = sDailyReminder.edit(); + if (isChecked) { + editorDailyReminder.putBoolean(KEY_FIELD_DAILY_REMINDER, true); + editorDailyReminder.commit(); + dailyReminderOn(); + } else { + editorDailyReminder.putBoolean(KEY_FIELD_DAILY_REMINDER, false); + editorDailyReminder.commit(); + dailyReminderOff(); + } + } + + private void dailyReminderOff() { + dailyReminderReceiver.cancelReminder(SettingActivity.this); + } + + private void dailyReminderOn() { + String time = "07:00"; + String message = getResources().getString(R.string.daily_reminder_message); + reminderPreference.setReminderDailyTime(time); + reminderPreference.setReminderDailyMessage(message); + dailyReminderReceiver.setReminder(SettingActivity.this, TYPE_REMINDER_RECIEVE, time, message); + } + + @OnCheckedChanged(R.id.releaseReminder) + public void setReleaseRemind(boolean isChecked){ + editorReleaseReminder = sReleaseReminder.edit(); + if (isChecked) { + editorReleaseReminder.putBoolean(KEY_FIELD_UPCOMING_REMINDER, true); + editorReleaseReminder.commit(); + releaseReminderOn(); + } else { + editorReleaseReminder.putBoolean(KEY_FIELD_UPCOMING_REMINDER, false); + editorReleaseReminder.commit(); + releaseReminderOff(); + } + } + + private void releaseReminderOff() { + releaseReminderReceiver.cancelReminder(SettingActivity.this); + } + + private void releaseReminderOn() { + String time = "08:00"; + String message = getResources().getString(R.string.release_movie_message); + reminderPreference.setReminderReleaseTime(time); + reminderPreference.setReminderReleaseMessage(message); + releaseReminderReceiver.setReminder(SettingActivity.this, TYPE_REMINDER_PREF, time, message); + + } + + public void setBahasa(View view){ + Intent mIntent = new Intent(Settings.ACTION_LOCALE_SETTINGS); + startActivity(mIntent); + } + + @Override + public boolean onSupportNavigateUp() { + Intent intent = new Intent(getApplicationContext(), MainActivity.class); + startActivity(intent); + return true; + } + + @Override + public void onBackPressed() { + Intent intent = new Intent(getApplicationContext(), MainActivity.class); + startActivity(intent); + } + + +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/UpcomingActivity.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/UpcomingActivity.java new file mode 100644 index 00000000..bc9529f6 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/activity/UpcomingActivity.java @@ -0,0 +1,129 @@ +package com.fajarnandagusti.cataloguemoviefinal.activity; + +import android.app.ProgressDialog; +import android.support.v7.app.AppCompatActivity; +import android.os.Bundle; +import android.support.v7.widget.LinearLayoutManager; +import android.support.v7.widget.RecyclerView; +import android.view.MenuItem; +import android.view.View; +import android.widget.ProgressBar; +import android.widget.Toast; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.adapter.MovieAdapter; +import com.fajarnandagusti.cataloguemoviefinal.api.ApiService; +import com.fajarnandagusti.cataloguemoviefinal.api.Server; +import com.fajarnandagusti.cataloguemoviefinal.model.Movies; +import com.fajarnandagusti.cataloguemoviefinal.model.ResponseMovie; +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +import java.util.ArrayList; +import java.util.List; +import java.util.Objects; + +import butterknife.BindView; +import butterknife.ButterKnife; +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +public class UpcomingActivity extends AppCompatActivity { + + @BindView(R.id.recycler_movie) + RecyclerView recyclerView; + + @BindView(R.id.progress_bar) + ProgressBar progressBar; + + ApiService API; + List listMovies; + private MovieAdapter movieAdapter; + + @Override + protected void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.activity_upcoming); + + ButterKnife.bind(this); + API = Server.getAPIService(); + + preload(); + + if (savedInstanceState == null) { + load(); + }else{ + listMovies = savedInstanceState.getParcelableArrayList(Utility.KEY_PARCELABLE); + movieAdapter = new MovieAdapter(getApplicationContext(), listMovies); + recyclerView.setAdapter(movieAdapter); + } + + Objects.requireNonNull(getSupportActionBar()).setDisplayHomeAsUpEnabled(true); + getSupportActionBar().setDisplayShowHomeEnabled(true); + } + + protected void onSaveInstanceState(Bundle outState) { + outState.putParcelableArrayList(Utility.KEY_PARCELABLE, new ArrayList<>(listMovies)); + super.onSaveInstanceState(outState); + + } + + private void preload() { + movieAdapter = new MovieAdapter(getApplicationContext(), listMovies); + recyclerView.setHasFixedSize(true); + recyclerView.setLayoutManager(new LinearLayoutManager(getApplicationContext())); + recyclerView.setAdapter(movieAdapter); + } + + private void load() { + showProgressBar(); + + API.getUpComingMovie(Utility.API_KEY).enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + if (response.isSuccessful()){ + hideProgressBar(); + listMovies = response.body().getMovies(); + recyclerView.setAdapter(new MovieAdapter(getApplicationContext(), listMovies)); + movieAdapter.notifyDataSetChanged(); + + }else { + hideProgressBar(); + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_SHORT).show(); + } + } + + @Override + public void onFailure(Call call, Throwable t) { + hideProgressBar(); + Toast.makeText(getApplicationContext(), getString(R.string.error), Toast.LENGTH_SHORT).show(); + } + }); + } + + void showProgressBar() { + progressBar.setVisibility(View.VISIBLE); + } + + void hideProgressBar() { + progressBar.setVisibility(View.GONE); + } + + @Override + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()){ + case android.R.id.home : { + finish(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + break; + } + } + return super.onOptionsItemSelected(item); + } + + @Override + public void onBackPressed() { + super.onBackPressed(); + overridePendingTransition(android.R.anim.slide_in_left, android.R.anim.slide_out_right); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/FavoriteAdapter.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/FavoriteAdapter.java new file mode 100644 index 00000000..432dd204 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/FavoriteAdapter.java @@ -0,0 +1,129 @@ +package com.fajarnandagusti.cataloguemoviefinal.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.activity.DetailMovieActivity; +import com.fajarnandagusti.cataloguemoviefinal.model.Favorite; +import com.fajarnandagusti.cataloguemoviefinal.utils.DateFormat; +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +import butterknife.BindView; +import butterknife.ButterKnife; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class FavoriteAdapter extends RecyclerView.Adapter{ + private Context context; + private Cursor listFavorite; + + public FavoriteAdapter(Context context){ + this.context = context; + } + + public void setFavoriteList(Cursor listFavorite){ + this.listFavorite = listFavorite; + } + + public class ViewHolder extends RecyclerView.ViewHolder { + @BindView(R.id.img_cv) + ImageView poster; + @BindView(R.id.movie_title) + TextView judul; + @BindView(R.id.movie_date) + TextView tanggal; + @BindView(R.id.movie_desc) + TextView sinopsis; + @BindView(R.id.popularity) + TextView popular; + @BindView(R.id.btn_detail) + Button btnDetail; + @BindView(R.id.btn_share) + Button btnShare; + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + + } + } + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View view = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_movies, null, false); + RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + view.setLayoutParams(layoutParams); + + return new ViewHolder(view); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + final Favorite favorite = getItem(position); + + Glide.with(context) + .load(Utility.URL+favorite.getPosterPath()) + .placeholder(R.drawable.ph) + .error(R.drawable.bg) + .into(holder.poster); + holder.judul.setText(favorite.getTitle()); + holder.tanggal.setText(DateFormat.dateConverter(favorite.getReleaseDate())); + holder.popular.setText(favorite.getPopularity()); + holder.sinopsis.setText(favorite.getOverview()); + + holder.btnDetail.setOnClickListener(new View.OnClickListener(){ + + @Override + public void onClick(View v) { + Intent intent = new Intent(context, DetailMovieActivity.class); + intent.putExtra("title", favorite.getTitle()); + intent.putExtra("overview", favorite.getOverview()); + intent.putExtra("poster_path", favorite.getPosterPath()); + intent.putExtra("release_date", favorite.getReleaseDate()); + intent.putExtra("popularity", favorite.getPopularity()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + + } + }); + + holder.btnShare.setOnClickListener(new View.OnClickListener() { + @SuppressLint({"StringFormatInvalid", "ResourceType"}) + @Override + public void onClick(View v) { + Intent i = new Intent(); + i.setAction(Intent.ACTION_SEND); + i.putExtra(Intent.EXTRA_TEXT, + context.getString(R.string.share, favorite.getTitle())); + i.setType("text/plain"); + context.startActivity(i); + } + }); + } + + @Override + public int getItemCount() { + if (listFavorite == null) return 0; + return listFavorite.getCount(); + } + + private Favorite getItem(int position){ + if (!listFavorite.moveToPosition(position)) { + throw new IllegalStateException("Position invalid"); + } + return new Favorite(listFavorite); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/MovieAdapter.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/MovieAdapter.java new file mode 100644 index 00000000..d9f8e6c6 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/adapter/MovieAdapter.java @@ -0,0 +1,118 @@ +package com.fajarnandagusti.cataloguemoviefinal.adapter; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.content.Intent; +import android.support.v7.widget.RecyclerView; +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.TextView; + +import com.bumptech.glide.Glide; +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.activity.DetailMovieActivity; +import com.fajarnandagusti.cataloguemoviefinal.model.Movies; +import com.fajarnandagusti.cataloguemoviefinal.utils.DateFormat; + +import java.util.List; + +import butterknife.BindView; +import butterknife.ButterKnife; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.URL; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class MovieAdapter extends RecyclerView.Adapter{ + public final static String EXTRA_MOVIE = "movie"; + private Context context; + private List listMovies; + + public MovieAdapter(Context context, List listMovies){ + this.context = context; + this.listMovies = listMovies; + } + + + @Override + public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { + View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.list_movies, null, false); + RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); + v.setLayoutParams(layoutParams); + return new ViewHolder(v); + } + + @Override + public void onBindViewHolder(ViewHolder holder, int position) { + final Movies movies = listMovies.get(position); + Glide.with(context) + .load(URL+movies.getPosterPath()) + .placeholder(R.drawable.ph) + .error(R.drawable.bg) + .into(holder.poster); + holder.judul.setText(movies.getTitle()); + holder.sinopsis.setText(movies.getOverview()); + holder.tanggal.setText(DateFormat.dateConverter(movies.getReleaseDate())); + holder.popular.setText(movies.getPopularity()); + + holder.btnDetail.setOnClickListener(new View.OnClickListener() { + @Override + public void onClick(View v) { + Intent intent = new Intent(context, DetailMovieActivity.class); + intent.putExtra("title", movies.getTitle()); + intent.putExtra("overview", movies.getOverview()); + intent.putExtra("poster_path", movies.getPosterPath()); + intent.putExtra("release_date", DateFormat.dateConverter(movies.getReleaseDate())); + intent.putExtra("popularity", movies.getPopularity()); + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + context.startActivity(intent); + } + }); + + holder.btnShare.setOnClickListener(new View.OnClickListener() { + @SuppressLint("StringFormatInvalid") + @Override + public void onClick(View v) { + Intent sendIntent = new Intent(); + sendIntent.setAction(Intent.ACTION_SEND); + sendIntent.putExtra(Intent.EXTRA_TEXT, + context.getString(R.string.share, movies.getTitle())); + sendIntent.setType("text/plain"); + } + }); + + } + @Override + public int getItemCount() { + if (listMovies == null) return 0; + return listMovies.size(); + } + + public class ViewHolder extends RecyclerView.ViewHolder { + + @BindView(R.id.img_cv) + ImageView poster; + @BindView(R.id.movie_title) + TextView judul; + @BindView(R.id.movie_date) + TextView tanggal; + @BindView(R.id.movie_desc) + TextView sinopsis; + @BindView(R.id.popularity) + TextView popular; + @BindView(R.id.btn_detail) + Button btnDetail; + @BindView(R.id.btn_share) + Button btnShare; + + public ViewHolder(View itemView) { + super(itemView); + ButterKnife.bind(this, itemView); + } + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/ApiService.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/ApiService.java new file mode 100644 index 00000000..98ff4ec7 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/ApiService.java @@ -0,0 +1,29 @@ +package com.fajarnandagusti.cataloguemoviefinal.api; + +import com.fajarnandagusti.cataloguemoviefinal.model.ResponseMovie; + +import retrofit2.Call; +import retrofit2.http.GET; +import retrofit2.http.Query; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public interface ApiService { + @GET("3/discover/movie") + Call getAllMovies(@Query("api_key") String api_key); + + @GET("/3/search/movie") + Call getSearchMovie(@Query("api_key") String api_key, + @Query("language") String language, + @Query("query") String query, + @Query("page") String page, + @Query("include_adult") String include_adult); + + @GET("/3/movie/now_playing") + Call getNowPlayingMovie(@Query("api_key") String api_key); + + @GET("/3/movie/upcoming") + Call getUpComingMovie(@Query("api_key") String api_key); +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Client.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Client.java new file mode 100644 index 00000000..b48b7724 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Client.java @@ -0,0 +1,29 @@ +package com.fajarnandagusti.cataloguemoviefinal.api; + +import okhttp3.OkHttpClient; +import okhttp3.logging.HttpLoggingInterceptor; +import retrofit2.Retrofit; +import retrofit2.converter.gson.GsonConverterFactory; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class Client { + private static Retrofit retrofit = null; + + public static Retrofit getClient(String baseUrl){ + HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor(); + interceptor.setLevel(HttpLoggingInterceptor.Level.BODY); + OkHttpClient client = new OkHttpClient.Builder().addInterceptor(interceptor).build(); + + if (retrofit == null){ + retrofit = new Retrofit.Builder() + .baseUrl(baseUrl) + .addConverterFactory(GsonConverterFactory.create()) + .client(client) + .build(); + } + return retrofit; + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Server.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Server.java new file mode 100644 index 00000000..04165324 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/api/Server.java @@ -0,0 +1,13 @@ +package com.fajarnandagusti.cataloguemoviefinal.api; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.BASE_URL_API; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class Server { + public static ApiService getAPIService(){ + return Client.getClient(BASE_URL_API).create(ApiService.class); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseContract.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseContract.java new file mode 100644 index 00000000..c24e0bd1 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseContract.java @@ -0,0 +1,37 @@ +package com.fajarnandagusti.cataloguemoviefinal.database; + +import android.database.Cursor; +import android.net.Uri; +import android.provider.BaseColumns; + +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class DatabaseContract { + public static String TABLE_FAVORITE = "favorite"; + + public static final class FavoriteColumn implements BaseColumns { + public static String POSTER = "posterPath"; + public static String TITLE = "title"; + public static String RELEASE = "releaseDate"; + public static String POPULARITY = "popularity"; + public static String OVERVIEW = "overview"; + + public static final Uri CONTENT_URI = new Uri.Builder() + .scheme(Utility.SCHEME) + .authority(Utility.AUTHORITY) + .appendPath(TABLE_FAVORITE) + .build(); + } + + public static String getColumnString(Cursor cursor, String columnName) { + return cursor.getString( cursor.getColumnIndex(columnName) ); + } + + public static int getColumnInt(Cursor cursor, String columnName) { + return cursor.getInt( cursor.getColumnIndex(columnName) ); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseHelper.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseHelper.java new file mode 100644 index 00000000..40e2f21e --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/DatabaseHelper.java @@ -0,0 +1,55 @@ +package com.fajarnandagusti.cataloguemoviefinal.database; + +import android.content.Context; +import android.database.sqlite.SQLiteDatabase; +import android.database.sqlite.SQLiteOpenHelper; + +import static android.provider.BaseColumns._ID; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.OVERVIEW; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.POPULARITY; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.POSTER; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.RELEASE; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.TITLE; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.TABLE_FAVORITE; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class DatabaseHelper extends SQLiteOpenHelper { + private static String DATABASE_NAME = "dbmoviefav"; + private static final int DATABASE_VERSION = 1; + + public static final String CREATE_TABLE_FAV = String.format("CREATE TABLE %s" + + " (%s INTEGER PRIMARY KEY AUTOINCREMENT," + + " %s TEXT NOT NULL," + + " %s TEXT NOT NULL," + + " %s TEXT NOT NULL," + + " %s TEXT NOT NULL," + + " %s TEXT NOT NULL)", + TABLE_FAVORITE, + _ID, + TITLE, + POSTER, + RELEASE, + POPULARITY, + OVERVIEW + + ); + + public DatabaseHelper(Context context){ + super(context, DATABASE_NAME, null, DATABASE_VERSION); + } + + @Override + public void onCreate(SQLiteDatabase db) { + db.execSQL(CREATE_TABLE_FAV); + } + + @Override + public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) { + db.execSQL("DROP TABLE IF EXISTS "+ TABLE_FAVORITE); + onCreate(db); + } + +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/FavoriteHelper.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/FavoriteHelper.java new file mode 100644 index 00000000..79c696f3 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/database/FavoriteHelper.java @@ -0,0 +1,137 @@ +package com.fajarnandagusti.cataloguemoviefinal.database; + +import android.content.ContentValues; +import android.content.Context; +import android.database.Cursor; +import android.database.SQLException; +import android.database.sqlite.SQLiteDatabase; + +import com.fajarnandagusti.cataloguemoviefinal.model.Favorite; + +import java.util.ArrayList; + +import static android.provider.BaseColumns._ID; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.OVERVIEW; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.POPULARITY; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.POSTER; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.RELEASE; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.TITLE; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.TABLE_FAVORITE; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class FavoriteHelper { + private static String DATABASE_TABLE = TABLE_FAVORITE; + private Context context; + private DatabaseHelper databaseHelper; + private SQLiteDatabase database; + + + public FavoriteHelper(Context context){ + this.context = context; + } + + public FavoriteHelper open() throws SQLException { + databaseHelper = new DatabaseHelper(context); + database = databaseHelper.getWritableDatabase(); + return this; + } + public void close(){ + databaseHelper.close(); + } + + public ArrayList getAllData(){ + ArrayList arrayList = new ArrayList<>(); + Cursor cursor = database.query(DATABASE_TABLE, + null, + null, + null, + null, + null, + _ID +" ASC", + null); + cursor.moveToFirst(); + Favorite favorite; + + if (cursor.getCount()>0) { + do{ + favorite = new Favorite(); + favorite.setId(cursor.getInt(cursor.getColumnIndexOrThrow(_ID))); + favorite.setTitle(cursor.getString(cursor.getColumnIndexOrThrow(TITLE))); + favorite.setPosterPath(cursor.getString(cursor.getColumnIndexOrThrow(POSTER))); + favorite.setOverview(cursor.getString(cursor.getColumnIndexOrThrow(OVERVIEW))); + favorite.setReleaseDate(cursor.getString(cursor.getColumnIndexOrThrow(RELEASE))); + favorite.setPopularity(cursor.getString(cursor.getColumnIndexOrThrow(POPULARITY))); + + arrayList.add(favorite); + cursor.moveToNext(); + + }while (!cursor.isAfterLast()); + } + cursor.close(); + return arrayList; + } + + public long insert(Favorite favorite){ + ContentValues initialValues = new ContentValues(); + initialValues.put(POSTER, favorite.getPosterPath()); + initialValues.put(TITLE, favorite.getTitle()); + initialValues.put(OVERVIEW, favorite.getOverview()); + initialValues.put(RELEASE, favorite.getReleaseDate()); + initialValues.put(POPULARITY, favorite.getPopularity()); + return database.insert(DATABASE_TABLE, null, initialValues); + } + + public int update(Favorite favorite){ + ContentValues args = new ContentValues(); + args.put(POSTER, favorite.getPosterPath()); + args.put(TITLE, favorite.getTitle()); + args.put(OVERVIEW, favorite.getOverview()); + args.put(RELEASE, favorite.getReleaseDate()); + args.put(POPULARITY, favorite.getPopularity()); + return database.update(DATABASE_TABLE, args, _ID + "= '"+ favorite.getId() + "'", null); + } + + public int delete(int id){ + return database.delete(DATABASE_TABLE, _ID + " = '" +id+ "'", null); + } + + + + public Cursor queryProvider(){ + return database.query( + DATABASE_TABLE, + null, + null, + null, + null, + null, + _ID + " DESC" + ); + } + + public Cursor queryByIdProvider(String id){ + return database.query(DATABASE_TABLE + ,null + , _ID + " = ?" + ,new String[]{id} + ,null + ,null + ,null + ,null); + } + + public long insertProvider (ContentValues values){ + return database.insert(DATABASE_TABLE, null, values); + } + + public int updateProvider (String id, ContentValues values){ + return database.update(DATABASE_TABLE, values, _ID +" = ?", new String[]{id}); + } + + public int deleteProvider (String id){ + return database.delete(DATABASE_TABLE, _ID + " = ?", new String[]{id}); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Favorite.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Favorite.java new file mode 100644 index 00000000..f41e785d --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Favorite.java @@ -0,0 +1,127 @@ +package com.fajarnandagusti.cataloguemoviefinal.model; + +import android.database.Cursor; +import android.os.Parcel; +import android.os.Parcelable; + +import static android.provider.BaseColumns._ID; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.OVERVIEW; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.POPULARITY; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.POSTER; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.RELEASE; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.TITLE; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.getColumnInt; +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.getColumnString; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class Favorite implements Parcelable { + private int id; + private String posterPath; + private String title; + private String releaseDate; + private String popularity; + private String overview; + + + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public String getPosterPath() { + return posterPath; + } + + public void setPosterPath(String posterPath) { + this.posterPath = posterPath; + } + + public String getTitle() { + return title; + } + + public void setTitle(String title) { + this.title = title; + } + + public String getReleaseDate() { + return releaseDate; + } + + public void setReleaseDate(String releaseDate) { + this.releaseDate = releaseDate; + } + + public String getPopularity() { + return popularity; + } + + public void setPopularity(String popularity) { + this.popularity = popularity; + } + + public String getOverview() { + return overview; + } + + public void setOverview(String overview) { + this.overview = overview; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(posterPath); + dest.writeString(title); + dest.writeString(releaseDate); + dest.writeString(popularity); + dest.writeString(overview); + } + + protected Favorite(Parcel in) { + id = in.readInt(); + posterPath = in.readString(); + title = in.readString(); + releaseDate = in.readString(); + popularity = in.readString(); + overview = in.readString(); + } + + public Favorite(Cursor cursor){ + this.id = getColumnInt(cursor, _ID); + this.posterPath = getColumnString(cursor, POSTER); + this.title = getColumnString(cursor, TITLE); + this.overview = getColumnString(cursor, OVERVIEW); + this.releaseDate = getColumnString(cursor, RELEASE); + this.popularity = getColumnString(cursor, POPULARITY); + } + + public Favorite() { + + } + + public static final Creator CREATOR = new Creator() { + @Override + public Favorite createFromParcel(Parcel in) { + return new Favorite(in); + } + + @Override + public Favorite[] newArray(int size) { + return new Favorite[size]; + } + }; + +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Movies.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Movies.java new file mode 100644 index 00000000..098d02b5 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/Movies.java @@ -0,0 +1,113 @@ +package com.fajarnandagusti.cataloguemoviefinal.model; + +import android.os.Parcel; +import android.os.Parcelable; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class Movies implements Parcelable { + @SerializedName("id") + @Expose + private int id; + + @SerializedName("title") + @Expose + private String title; + + @SerializedName("poster_path") + @Expose + private String posterPath; + + @SerializedName("overview") + @Expose + private String overview; + + @SerializedName("release_date") + @Expose + private String releaseDate; + + @SerializedName("popularity") + @Expose + private String popularity; + + public Movies( int id, String title, String posterPath, String overview, String releaseDate, String popularity) { + this.id = id; + this.title = title; + this.posterPath = posterPath; + this.overview = overview; + this.releaseDate = releaseDate; + this.popularity = popularity; + } + + protected Movies(Parcel in) { + + id = in.readInt(); + title = in.readString(); + posterPath = in.readString(); + overview = in.readString(); + releaseDate = in.readString(); + popularity = in.readString(); + + } + + public Movies(){ + + } + + public int getId() { + return id; + } + + public String getTitle() { + return title; + } + + public String getPosterPath() { + return posterPath; + } + + public String getOverview() { + return overview; + } + + public String getReleaseDate() { + return releaseDate; + } + + public String getPopularity(){ + return popularity; + } + + + public static final Creator CREATOR = new Creator() { + @Override + public Movies createFromParcel(Parcel in) { + return new Movies(in); + } + + @Override + public Movies[] newArray(int size) { + return new Movies[size]; + } + }; + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeInt(id); + dest.writeString(title); + dest.writeString(posterPath); + dest.writeString(overview); + dest.writeString(releaseDate); + dest.writeString(popularity); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/ResponseMovie.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/ResponseMovie.java new file mode 100644 index 00000000..81c963a2 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/model/ResponseMovie.java @@ -0,0 +1,48 @@ +package com.fajarnandagusti.cataloguemoviefinal.model; + +import com.google.gson.annotations.Expose; +import com.google.gson.annotations.SerializedName; + +import java.util.List; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class ResponseMovie { + @SerializedName("page") + @Expose + private int page; + @SerializedName("total_results") + @Expose + private int totalResults; + @SerializedName("total_pages") + @Expose + private int totalPages; + @SerializedName("results") + @Expose + private List movies = null; + + public ResponseMovie(int page, int totalResults, int totalPages, List movies) { + this.page = page; + this.totalResults = totalResults; + this.totalPages = totalPages; + this.movies = movies; + } + + public int getPage() { + return page; + } + + public int getTotalResults() { + return totalResults; + } + + public int getTotalPages() { + return totalPages; + } + + public List getMovies() { + return movies; + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/provider/MovieProvider.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/provider/MovieProvider.java new file mode 100644 index 00000000..e936d54e --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/provider/MovieProvider.java @@ -0,0 +1,127 @@ +package com.fajarnandagusti.cataloguemoviefinal.provider; + +import android.content.ContentProvider; +import android.content.ContentValues; +import android.content.UriMatcher; +import android.database.Cursor; +import android.net.Uri; +import android.support.annotation.NonNull; +import android.support.annotation.Nullable; + +import com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract; +import com.fajarnandagusti.cataloguemoviefinal.database.FavoriteHelper; + +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.CONTENT_URI; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.AUTHORITY; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class MovieProvider extends ContentProvider { + private static final int MOVIE = 1; + private static final int MOVIE_ID = 2; + + private static final UriMatcher sUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); + + static { + sUriMatcher.addURI(AUTHORITY, DatabaseContract.TABLE_FAVORITE, MOVIE); + + sUriMatcher.addURI(AUTHORITY, DatabaseContract.TABLE_FAVORITE+ "/#", + MOVIE_ID); + } + + private FavoriteHelper favoriteHelper; + + + @Override + public boolean onCreate() { + favoriteHelper = new FavoriteHelper(getContext()); + favoriteHelper.open(); + return true; + } + + @Nullable + @Override + public Cursor query(@NonNull Uri uri, String[] strings, String s, String[] strings1, String s1) { + Cursor cursor; + switch (sUriMatcher.match(uri)){ + case MOVIE: + cursor = favoriteHelper.queryProvider(); + break; + case MOVIE_ID: + cursor = favoriteHelper.queryByIdProvider(uri.getLastPathSegment()); + break; + default: + cursor=null; + break; + } + + if (cursor != null){ + cursor.setNotificationUri(getContext().getContentResolver(), uri); + } + return cursor; + } + + + @Override + public String getType(@NonNull Uri uri) { + return null; + } + + @Nullable + @Override + public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) { + long added; + switch (sUriMatcher.match(uri)){ + case MOVIE: + added = favoriteHelper.insertProvider(contentValues); + break; + default: + added = 0 ; + break; + } + + if (added > 0 ){ + getContext().getContentResolver().notifyChange(uri, null); + } + return Uri.parse(CONTENT_URI + "/" + added); + } + + @Override + public int delete(@NonNull Uri uri, String s, String[] strings) { + int deleted; + switch (sUriMatcher.match(uri)){ + case MOVIE_ID: + deleted = favoriteHelper.deleteProvider(uri.getLastPathSegment()); + break; + default: + deleted = 0; + break; + } + + if (deleted > 0){ + getContext().getContentResolver().notifyChange(uri, null); + } + return deleted; + } + + @Override + public int update(@NonNull Uri uri, ContentValues contentValues, String s, String[] strings) { + int update; + switch (sUriMatcher.match(uri)){ + case MOVIE_ID: + update = favoriteHelper.updateProvider(uri.getLastPathSegment(), contentValues); + break; + default: + update = 0 ; + break; + } + + if (update > 0){ + getContext().getContentResolver().notifyChange(uri, null); + + } + return update; + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/DailyReminderReceiver.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/DailyReminderReceiver.java new file mode 100644 index 00000000..af982d27 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/DailyReminderReceiver.java @@ -0,0 +1,72 @@ +package com.fajarnandagusti.cataloguemoviefinal.scheduler; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.support.v4.app.TaskStackBuilder; +import android.widget.Toast; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.activity.MainActivity; + +import java.util.Calendar; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.EXTRA_MESSAGE_PREF; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.EXTRA_TYPE_PREF; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class DailyReminderReceiver extends BroadcastReceiver { + private final int NOTIF_ID_REMINDER = 1; + + public DailyReminderReceiver(){ + + } + + @Override + public void onReceive(Context context, Intent intent) { + String message = intent.getStringExtra(EXTRA_MESSAGE_PREF); + String title = "Daily Reminder"; + int notifId = NOTIF_ID_REMINDER; + + showReminderNotification(context,title,message,notifId); + } + + private void showReminderNotification(Context context, String title, String message, int notifId) { + Intent intent = new Intent(context, MainActivity.class); + PendingIntent pendingIntent = TaskStackBuilder.create(context) + .addNextIntent(intent) + .getPendingIntent(NOTIF_ID_REMINDER, PendingIntent.FLAG_UPDATE_CURRENT); + + NotificationHelper notificationHelper = new NotificationHelper(context); + notificationHelper.createNotification(title, message); + } + + public void setReminder(Context context, String type, String time, String message){ + AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(context, DailyReminderReceiver.class); + intent.putExtra(EXTRA_MESSAGE_PREF,message); + intent.putExtra(EXTRA_TYPE_PREF,type); + String timeArray[] = time.split(":"); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArray[0])); + calendar.set(Calendar.MINUTE, Integer.parseInt(timeArray[1])); + calendar.set(Calendar.SECOND,0); + + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIF_ID_REMINDER,intent,0); + alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); + + Toast.makeText(context, R.string.dailyReminderSaved, Toast.LENGTH_SHORT).show(); + } + public void cancelReminder(Context context){ + AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(context, DailyReminderReceiver.class); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIF_ID_REMINDER,intent,0); + alarmManager.cancel(pendingIntent); + Toast.makeText(context, R.string.dailyReminderCanceled, Toast.LENGTH_SHORT).show(); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/NotificationHelper.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/NotificationHelper.java new file mode 100644 index 00000000..df2dfbaf --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/NotificationHelper.java @@ -0,0 +1,59 @@ +package com.fajarnandagusti.cataloguemoviefinal.scheduler; + +import android.app.NotificationChannel; +import android.app.NotificationManager; +import android.app.PendingIntent; +import android.content.Context; +import android.content.Intent; +import android.graphics.Color; +import android.provider.Settings; +import android.support.v4.app.NotificationCompat; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.activity.MainActivity; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.NOTIFICATION_CHANNEL_ID; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class NotificationHelper { + private Context mContext; + + public NotificationHelper(Context context) { + mContext = context; + } + + public void createNotification(String title, String message){ + Intent resultIntent = new Intent(mContext, MainActivity.class); + resultIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + PendingIntent resultPendingIntent = PendingIntent.getActivity(mContext, + 0 , resultIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + NotificationCompat.Builder mBuilder = new NotificationCompat.Builder(mContext); + mBuilder.setSmallIcon(R.mipmap.ic_launcher); + mBuilder.setContentTitle(title) + .setContentText(message) + .setAutoCancel(false) + .setSound(Settings.System.DEFAULT_NOTIFICATION_URI) + .setContentIntent(resultPendingIntent); + + NotificationManager mNotificationManager = (NotificationManager) mContext.getSystemService(Context.NOTIFICATION_SERVICE); + if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O) { + int importance = NotificationManager.IMPORTANCE_HIGH; + NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "NOTIFICATION_CHANNEL_NAME", importance); + notificationChannel.enableLights(true); + notificationChannel.setLightColor(Color.RED); + notificationChannel.enableVibration(true); + notificationChannel.setVibrationPattern(new long[]{100, 200, 300, 400, 500, 400, 300, 200, 400}); + assert mNotificationManager != null; + mBuilder.setChannelId(NOTIFICATION_CHANNEL_ID); + mNotificationManager.createNotificationChannel(notificationChannel); + } + assert mNotificationManager != null; + mNotificationManager.notify(0, mBuilder.build()); + + } + +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReleaseReminderReceiver.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReleaseReminderReceiver.java new file mode 100644 index 00000000..56e7ae69 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReleaseReminderReceiver.java @@ -0,0 +1,113 @@ +package com.fajarnandagusti.cataloguemoviefinal.scheduler; + +import android.app.AlarmManager; +import android.app.PendingIntent; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; +import android.util.Log; +import android.widget.Toast; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.activity.DetailMovieActivity; +import com.fajarnandagusti.cataloguemoviefinal.api.ApiService; +import com.fajarnandagusti.cataloguemoviefinal.api.Client; +import com.fajarnandagusti.cataloguemoviefinal.model.Movies; +import com.fajarnandagusti.cataloguemoviefinal.model.ResponseMovie; + +import java.util.ArrayList; +import java.util.Calendar; +import java.util.List; +import java.util.Random; + +import retrofit2.Call; +import retrofit2.Callback; +import retrofit2.Response; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.API_KEY; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.BASE_URL_API; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.EXTRA_MESSAGE_RECIEVE; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.EXTRA_TYPE_RECIEVE; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.LANGUAGE; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class ReleaseReminderReceiver extends BroadcastReceiver { + + public List listMovie = new ArrayList<>(); + private final int NOTIF_ID_RELEASE = 21; + + public ReleaseReminderReceiver() { + + } + + public void setReminder(Context context, String type, String time, String message){ + AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(context, ReleaseReminderReceiver.class); + intent.putExtra(EXTRA_MESSAGE_RECIEVE,message); + intent.putExtra(EXTRA_TYPE_RECIEVE,type); + String timeArray[] = time.split(":"); + Calendar calendar = Calendar.getInstance(); + calendar.set(Calendar.HOUR_OF_DAY, Integer.parseInt(timeArray[0])); + calendar.set(Calendar.MINUTE, Integer.parseInt(timeArray[1])); + calendar.set(Calendar.SECOND,0); + + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIF_ID_RELEASE,intent,0); + alarmManager.setInexactRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), AlarmManager.INTERVAL_DAY, pendingIntent); + + Toast.makeText(context, R.string.reminderSave, Toast.LENGTH_SHORT).show(); + } + + public void cancelReminder(Context context){ + AlarmManager alarmManager = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE); + Intent intent = new Intent(context,ReleaseReminderReceiver.class); + PendingIntent pendingIntent = PendingIntent.getBroadcast(context, NOTIF_ID_RELEASE,intent,0); + alarmManager.cancel(pendingIntent); + Toast.makeText(context,R.string.reminderCancel, Toast.LENGTH_SHORT).show(); + } + + @Override + public void onReceive(Context context, Intent intent) { + getUpcomingMovie(context); + } + + private void getUpcomingMovie(final Context context) { + ApiService service = Client.getClient(BASE_URL_API).create(ApiService.class); + Call call = service.getUpComingMovie(API_KEY); + call.enqueue(new Callback() { + @Override + public void onResponse(Call call, Response response) { + listMovie = response.body().getMovies(); + List items = response.body().getMovies(); + int index = new Random().nextInt(items.size()); + Movies item = items.get(index); + int notifId = 200; + String title = items.get(index).getTitle(); + String message = items.get(index).getOverview(); + showNotification(context, title, message, notifId, item); + } + + @Override + public void onFailure(Call call, Throwable t) { + Log.d("getUpCommingMovie", "onFailure: " + t.toString()); + } + }); + } + + private void showNotification(Context context, String title, String message, int notifId, Movies item) { + + Intent i = new Intent(context, DetailMovieActivity.class); + i.putExtra("title", item.getTitle()); + i.putExtra("poster_path", item.getPosterPath()); + i.putExtra("overview", item.getOverview()); + i.putExtra("release_date", item.getReleaseDate()); + PendingIntent pendingIntent = PendingIntent.getActivity(context, notifId, i, PendingIntent.FLAG_UPDATE_CURRENT); + + + NotificationHelper notificationHelper = new NotificationHelper(context); + + notificationHelper.createNotification(title, message); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReminderPreference.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReminderPreference.java new file mode 100644 index 00000000..281cd5bc --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/scheduler/ReminderPreference.java @@ -0,0 +1,38 @@ +package com.fajarnandagusti.cataloguemoviefinal.scheduler; + +import android.content.Context; +import android.content.SharedPreferences; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_REMINDER_DAILY; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_REMINDER_MESSAGE_DAILY; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.KEY_REMINDER_MESSAGE_RELEASE; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.PREF_NAME; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class ReminderPreference { + public SharedPreferences sharedPreferences; + public SharedPreferences.Editor editor; + + public ReminderPreference(Context context) { + sharedPreferences = context.getSharedPreferences(PREF_NAME, Context.MODE_PRIVATE); + editor = sharedPreferences.edit(); + } + + public void setReminderReleaseTime(String time){ + editor.putString(KEY_REMINDER_DAILY,time); + editor.commit(); + } + public void setReminderReleaseMessage (String message){ + editor.putString(KEY_REMINDER_MESSAGE_RELEASE,message); + } + public void setReminderDailyTime(String time){ + editor.putString(KEY_REMINDER_DAILY,time); + editor.commit(); + } + public void setReminderDailyMessage(String message){ + editor.putString(KEY_REMINDER_MESSAGE_DAILY,message); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/DateFormat.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/DateFormat.java new file mode 100644 index 00000000..5bca1d61 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/DateFormat.java @@ -0,0 +1,27 @@ +package com.fajarnandagusti.cataloguemoviefinal.utils; + +import android.util.Log; + +import java.text.ParseException; +import java.text.SimpleDateFormat; +import java.util.Date; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class DateFormat { + public static String dateConverter(String dateString){ + java.text.DateFormat currentDate = new SimpleDateFormat("yyyy-MM-dd"); + java.text.DateFormat newDate = new SimpleDateFormat("EEEE, dd MMMM yyyy"); + + try { + Date date = currentDate.parse(dateString); + return newDate.format(date); + }catch (ParseException e){ + Log.e("Date Format", e.toString()); + } + + return ""; + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/Utility.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/Utility.java new file mode 100644 index 00000000..b70a0170 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/utils/Utility.java @@ -0,0 +1,52 @@ +package com.fajarnandagusti.cataloguemoviefinal.utils; + +import com.fajarnandagusti.cataloguemoviefinal.BuildConfig; + +/** + * Created by Gustiawan on 11/16/2018. + */ + +public class Utility { + public final static String EXTRA_MOVIE = "movie"; + public final static String URL = "http://image.tmdb.org/t/p/w500"; + public final static String API_KEY = BuildConfig.API_KEY; + + public static final String BASE_URL_API = "https://api.themoviedb.org/"; + + public final static String KEY_PARCELABLE ="key_parcelable"; + + public final static String include_adult = "false"; + public final static String page = "1"; + + public static final String AUTHORITY = "com.fajarnandagusti.cataloguemoviefinal"; + public static final String SCHEME = "content"; + + + public static final String KEY_HEADER_UPCOMING_REMINDER = "upcomingReminder"; + public static final String KEY_HEADER_DAILY_REMINDER = "dailyReminder"; + + public static final String KEY_FIELD_UPCOMING_REMINDER = "checkedUpcoming"; + public static final String KEY_FIELD_DAILY_REMINDER = "checkedDaily"; + + public final static String PREF_NAME = "reminderPreferences"; + public static final String LANGUAGE = "en-US"; + + public final static String KEY_REMINDER_DAILY = "DailyTime"; + public final static String KEY_REMINDER_MESSAGE_RELEASE = "reminderMessageRelease"; + public final static String KEY_REMINDER_MESSAGE_DAILY = "reminderMessageDaily"; + public static final String EXTRA_MESSAGE_PREF = "message"; + public static final String EXTRA_TYPE_PREF = "type"; + public static final String TYPE_REMINDER_PREF = "reminderAlarm"; + public static final String EXTRA_MESSAGE_RECIEVE = "messageRelease"; + public static final String EXTRA_TYPE_RECIEVE = "typeRelease"; + public static final String TYPE_REMINDER_RECIEVE = "reminderAlarmRelease"; + + public static final String NOTIFICATION_CHANNEL_ID = "10001"; + + public final static int NOTIFICATION_ID = 501; + public final static int NOTIFICATION_ID_ = 21; + + public static final String TOAST_ACTION = "com.fajarnandagusti.cataloguemoviefinal.TOAST_ACTION"; + public static final String EXTRA_ITEM = "com.fajarnandagusti.cataloguemoviefinal.EXTRA_ITEM"; + public static final String ON_CLICK_FAVORITE_ACTION = "com.fajarnandagusti.cataloguemoviefinal.ON_CLICK_FAVORITE_ACTION"; +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/ImageBannerWidget.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/ImageBannerWidget.java new file mode 100644 index 00000000..dcf155ba --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/ImageBannerWidget.java @@ -0,0 +1,99 @@ +package com.fajarnandagusti.cataloguemoviefinal.widget; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProvider; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.net.Uri; +import android.util.Log; +import android.widget.RemoteViews; +import android.widget.Toast; + +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.adapter.MovieAdapter; + +import java.util.Objects; + +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.EXTRA_ITEM; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.ON_CLICK_FAVORITE_ACTION; +import static com.fajarnandagusti.cataloguemoviefinal.utils.Utility.TOAST_ACTION; + +/** + * Implementation of App Widget functionality. + */ +public class ImageBannerWidget extends AppWidgetProvider { + + int appWidgetId, viewIndex; + + static void updateAppWidget(Context context, AppWidgetManager appWidgetManager, + int appWidgetId) { + + Intent intent = new Intent(context, StackWidgetService.class); + intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + + // Construct the RemoteViews object + RemoteViews views = new RemoteViews(context.getPackageName(), R.layout.image_banner_widget); + views.setRemoteAdapter(R.id.stack_view, intent); + views.setEmptyView(R.id.stack_view, R.id.empty_view); + + Intent toastIntent = new Intent(context, ImageBannerWidget.class); + toastIntent.setAction(TOAST_ACTION); + toastIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId); + intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME))); + + PendingIntent toastPendingIntent = PendingIntent.getBroadcast(context, 0, toastIntent, + PendingIntent.FLAG_UPDATE_CURRENT); + views.setPendingIntentTemplate(R.id.stack_view, toastPendingIntent); + + // Instruct the widget manager to update the widget + appWidgetManager.updateAppWidget(appWidgetId, views); + } + + @Override + public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) { + // There may be multiple widgets active, so update all of them + for (int appWidgetId : appWidgetIds) { + updateAppWidget(context, appWidgetManager, appWidgetId); + } + } + + @Override + public void onEnabled(Context context) { + // Enter relevant functionality for when the first widget is created + } + + @Override + public void onDisabled(Context context) { + // Enter relevant functionality for when the last widget is disabled + } + + @Override + public void onReceive(Context context, Intent intent) { + AppWidgetManager mgr = AppWidgetManager.getInstance(context); + + switch (Objects.requireNonNull(intent.getAction())) { + case TOAST_ACTION: + appWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + viewIndex = intent.getIntExtra(EXTRA_ITEM, 0); + String title = intent.getStringExtra(MovieAdapter.EXTRA_MOVIE); + + Toast.makeText(context, title, Toast.LENGTH_SHORT).show(); + break; + case ON_CLICK_FAVORITE_ACTION: { + Log.d("TAG", "onReceive: " + "RECEIVED"); + int widgetIDs[] = mgr.getAppWidgetIds(new ComponentName(context, ImageBannerWidget.class)); + onUpdate(context, mgr, widgetIDs); + mgr.notifyAppWidgetViewDataChanged(widgetIDs, R.id.stack_view); + break; + + } + } + + super.onReceive(context, intent); + } +} + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackRemoteViewFactory.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackRemoteViewFactory.java new file mode 100644 index 00000000..863acaf6 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackRemoteViewFactory.java @@ -0,0 +1,126 @@ +package com.fajarnandagusti.cataloguemoviefinal.widget; + +import android.appwidget.AppWidgetManager; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.drawable.ColorDrawable; +import android.os.Binder; +import android.os.Bundle; +import android.util.Log; +import android.widget.RemoteViews; +import android.widget.RemoteViewsService; + +import com.bumptech.glide.Glide; +import com.bumptech.glide.request.target.Target; +import com.fajarnandagusti.cataloguemoviefinal.R; +import com.fajarnandagusti.cataloguemoviefinal.adapter.MovieAdapter; +import com.fajarnandagusti.cataloguemoviefinal.model.Favorite; +import com.fajarnandagusti.cataloguemoviefinal.utils.Utility; + +import java.util.ArrayList; +import java.util.concurrent.ExecutionException; + +import static com.fajarnandagusti.cataloguemoviefinal.database.DatabaseContract.FavoriteColumn.CONTENT_URI; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class StackRemoteViewFactory implements RemoteViewsService.RemoteViewsFactory { + private ArrayList mWidgetItems = new ArrayList<>(); + private Context mContext; + + public StackRemoteViewFactory(Context applicationContext, Intent intent) { + mContext = applicationContext; + int mAppWidgetId = intent.getIntExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, + AppWidgetManager.INVALID_APPWIDGET_ID); + } + + @Override + public void onCreate() { + + } + + @Override + public void onDataSetChanged() { + mWidgetItems.clear(); + final long identityToken = Binder.clearCallingIdentity(); + Cursor cursor = mContext.getContentResolver().query(CONTENT_URI, null, null, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + do { + Favorite favorite = new Favorite(cursor); + mWidgetItems.add(favorite); + cursor.moveToNext(); + } + while (!cursor.isAfterLast()); + } + + if (cursor != null) { + cursor.close(); + } + Binder.restoreCallingIdentity(identityToken); + + } + + @Override + public void onDestroy() { + + } + + @Override + public int getCount() { + return mWidgetItems.size(); + } + + @Override + public RemoteViews getViewAt(int position) { + Favorite currentMovieFavorite ; + Bundle extras = new Bundle(); + Bitmap bmp = null; + String releaseDate = null; + try { + currentMovieFavorite = mWidgetItems.get(position); + bmp = Glide.with(mContext) + .load(Utility.URL + currentMovieFavorite.getPosterPath()).asBitmap() + .error(new ColorDrawable(mContext.getResources().getColor(R.color.colorPrimaryDark))) + .into(Target.SIZE_ORIGINAL, Target.SIZE_ORIGINAL).get(); + + releaseDate = currentMovieFavorite.getReleaseDate(); + extras.putString(MovieAdapter.EXTRA_MOVIE,currentMovieFavorite.getTitle()); + + } catch (InterruptedException | ExecutionException | IndexOutOfBoundsException e) { + Log.d("Error loading", "error"); + } + + RemoteViews rv = new RemoteViews(mContext.getPackageName(), R.layout.widget_items); + rv.setImageViewBitmap(R.id.imgWidget, bmp); + rv.setTextViewText(R.id.txtDate, releaseDate); + Intent fillInIntent = new Intent(); + fillInIntent.putExtras(extras); + + rv.setOnClickFillInIntent(R.id.imgWidget, fillInIntent); + return rv; + } + + @Override + public RemoteViews getLoadingView() { + return null; + } + + @Override + public int getViewTypeCount() { + return 1; + } + + @Override + public long getItemId(int position) { + return 0; + } + + @Override + public boolean hasStableIds() { + return false; + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackWidgetService.java b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackWidgetService.java new file mode 100644 index 00000000..c4a16da2 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/java/com/fajarnandagusti/cataloguemoviefinal/widget/StackWidgetService.java @@ -0,0 +1,15 @@ +package com.fajarnandagusti.cataloguemoviefinal.widget; + +import android.content.Intent; +import android.widget.RemoteViewsService; + +/** + * Created by Gustiawan on 11/17/2018. + */ + +public class StackWidgetService extends RemoteViewsService { + @Override + public RemoteViewsFactory onGetViewFactory(Intent intent) { + return new StackRemoteViewFactory(this.getApplicationContext(), intent); + } +} diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-nodpi/example_appwidget_preview.png b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-nodpi/example_appwidget_preview.png new file mode 100644 index 0000000000000000000000000000000000000000..894b069a4907d258f60b1b2406b90f5a0fe1c35b GIT binary patch literal 3522 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 + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_gallery.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_gallery.xml new file mode 100644 index 00000000..f6872c40 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_gallery.xml @@ -0,0 +1,9 @@ + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_manage.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_manage.xml new file mode 100644 index 00000000..c1be60b3 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_manage.xml @@ -0,0 +1,9 @@ + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_send.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_send.xml new file mode 100644 index 00000000..00c668c6 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_send.xml @@ -0,0 +1,9 @@ + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_share.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_share.xml new file mode 100644 index 00000000..a28fb9e2 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_share.xml @@ -0,0 +1,9 @@ + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_slideshow.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_slideshow.xml new file mode 100644 index 00000000..209aa643 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v21/ic_menu_slideshow.xml @@ -0,0 +1,9 @@ + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v24/ic_launcher_foreground.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v24/ic_launcher_foreground.xml new file mode 100644 index 00000000..c7bd21db --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable-v24/ic_launcher_foreground.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/baseline_av_timer_black_24dp.png b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/baseline_av_timer_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..f646df0e5c230ca9b01d9b07ee23e06b2e686555 GIT binary patch literal 624 zcmV-$0+0QPP)N+qP|+o5pFJBC5j%wT-BXYPVr++qP|6lbf4nX7wX_=lSh-_bdk_NM#cI z4w&snxHkUS|N(2p-{pmmA~{9+brZeEB192TSc2y!d4K@=nc!C%kcRo9com>%#dnkJg)di3Yykj7 zP%JaKo%m2oR#ycqiW<17&X2#TALPTyaO;trD~cDsio+(=A15nKWF*8;j5C=PI5}q` zt-wc789VJvVh>K9m`GW`DM1 z%T!vTlf>bqsqTxDd~zL?BPwN0>v$*^{&;VVW-s8Aq0~ozM1^?yH=5(&61x$DAKZ3N*>eAcGn8s zcpQD$0=c-#PkF4S2sVnaD#pM|cKnbk{=`;>(S)*OCmUsH#xS<@pkl+{cGvoKo)1(Ig0000< KMNUMnLSTXv8WoHH literal 0 HcmV?d00001 diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/baseline_play_circle_outline_black_24dp.png b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/baseline_play_circle_outline_black_24dp.png new file mode 100644 index 0000000000000000000000000000000000000000..216dc9131a6a470049e883a5b7754f21b88b51f8 GIT binary patch literal 632 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 N*MC{!_#clg{x5OnsLTKW literal 0 HcmV?d00001 diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_launcher_background.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_launcher_background.xml new file mode 100644 index 00000000..d5fccc53 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_launcher_background.xml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_search_white_24px.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_search_white_24px.xml new file mode 100644 index 00000000..be5ad99c --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_search_white_24px.xml @@ -0,0 +1,5 @@ + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_checked.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_checked.xml new file mode 100644 index 00000000..4e69e5a2 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_checked.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_unchecked.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_unchecked.xml new file mode 100644 index 00000000..e021e3d6 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_star_unchecked.xml @@ -0,0 +1,5 @@ + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_stars_black_24dp.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_stars_black_24dp.xml new file mode 100644 index 00000000..61c5d7ac --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ic_stars_black_24dp.xml @@ -0,0 +1,9 @@ + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ph.png b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/ph.png new file mode 100644 index 0000000000000000000000000000000000000000..f2535763bc7d5963eacf82899b9fb7894b0c6e6e GIT binary patch literal 265 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1quc!Fir8jv*f2Zzo3cIT#4I?iQM+oEWWh>M_6c zK|Y;^>Xj~1vo7`=X`ejj%fxM;SNyDOmMi=HMK)?R*QK21)sxazM_t|CnaG=N?G`YV zO;26Y#fx!f#J;t84;qUZ)-9DO-&=l%%S*#Ggt0o#QSQl#f9&&JugFd3@w+xfTFyoO zjnSdUo7wX!I95H-bGVQkzCoAg&~f3sh^AW~S+;W3H5h6q*V+p3?%q%hbSZ + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/tmdb.png b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/drawable/tmdb.png new file mode 100644 index 0000000000000000000000000000000000000000..799d0b8042207ad7a332c6da7fa6976d1c927e07 GIT binary patch literal 6043 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 V3KM)%*`zxM%GBDV(%2*ZKLAP1ZQ=j` literal 0 HcmV?d00001 diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_detail_movie.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_detail_movie.xml new file mode 100644 index 00000000..59fb953f --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_detail_movie.xml @@ -0,0 +1,77 @@ + + + + + + + + + + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_favorite.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_favorite.xml new file mode 100644 index 00000000..d9cfdf5d --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_favorite.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_main.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_main.xml new file mode 100644 index 00000000..a61d8a63 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_main.xml @@ -0,0 +1,25 @@ + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_now_playing.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_now_playing.xml new file mode 100644 index 00000000..552a962c --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_now_playing.xml @@ -0,0 +1,23 @@ + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_setting.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_setting.xml new file mode 100644 index 00000000..7501c491 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_setting.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_upcoming.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_upcoming.xml new file mode 100644 index 00000000..11a8b158 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/activity_upcoming.xml @@ -0,0 +1,22 @@ + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/app_bar_main.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/app_bar_main.xml new file mode 100644 index 00000000..381854e9 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/app_bar_main.xml @@ -0,0 +1,25 @@ + + + + + + + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/content_main.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/content_main.xml new file mode 100644 index 00000000..aa7d53ef --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/content_main.xml @@ -0,0 +1,17 @@ + + + + + + diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/image_banner_widget.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/image_banner_widget.xml new file mode 100644 index 00000000..a8f06829 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/image_banner_widget.xml @@ -0,0 +1,50 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/list_movies.xml b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/list_movies.xml new file mode 100644 index 00000000..5ddb4e79 --- /dev/null +++ b/Android Projects/CatalogueMovieSqLiteFavorite/app/src/main/res/layout/list_movies.xml @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + +