Full Code of owncloud/News-Android-App for AI

master 3e68d436222c cached
480 files
2.3 MB
641.3k tokens
1531 symbols
1 requests
Download .txt
Showing preview only (2,635K chars total). Download the full file or copy to clipboard to get everything.
Repository: owncloud/News-Android-App
Branch: master
Commit: 3e68d436222c
Files: 480
Total size: 2.3 MB

Directory structure:
gitextract_ye9_lomr/

├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── analysis.yml
│       ├── ci.yml
│       └── codeql.yml
├── .gitignore
├── .tx/
│   └── config
├── CHANGELOG.md
├── COPYING-AGPL.md
├── COPYING-README.md
├── Gemfile
├── NEWS-POLICY.md
├── News-Android-App/
│   ├── .gitignore
│   ├── build.gradle
│   ├── config/
│   │   └── detekt/
│   │       └── detekt.yml
│   ├── proguard-rules.pro
│   ├── proguard-test.pro
│   ├── remove_invalid_languages.sh
│   └── src/
│       ├── androidTest/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       ├── de/
│       │       │   └── luhmer/
│       │       │       └── owncloudnewsreader/
│       │       │           ├── CustomTestRunner.java
│       │       │           ├── TestApplication.java
│       │       │           ├── di/
│       │       │           │   ├── TestApiModule.java
│       │       │           │   ├── TestApiProvider.java
│       │       │           │   └── TestComponent.java
│       │       │           ├── helper/
│       │       │           │   └── Utils.java
│       │       │           └── tests/
│       │       │               ├── DownloadWebPageServiceTest.java
│       │       │               ├── NewFeedTests.java
│       │       │               ├── NewsReaderListActivityUiTests.java
│       │       │               └── NightModeTest.java
│       │       ├── helper/
│       │       │   ├── CustomMatchers.java
│       │       │   ├── OrientationChangeAction.java
│       │       │   └── RecyclerViewAssertions.java
│       │       └── screengrab/
│       │           └── ScreenshotTest.java
│       ├── dev/
│       │   └── res/
│       │       ├── drawable/
│       │       │   └── ic_launcher_foreground.xml
│       │       └── values/
│       │           └── strings.xml
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/
│       │   │   └── web.css
│       │   ├── icon.xcf
│       │   ├── java/
│       │   │   ├── com/
│       │   │   │   └── bumptech/
│       │   │   │       └── glide/
│       │   │   │           └── samples/
│       │   │   │               └── svg/
│       │   │   │                   ├── SvgDecoder.kt
│       │   │   │                   └── SvgDrawableTranscoder.kt
│       │   │   └── de/
│       │   │       └── luhmer/
│       │   │           └── owncloudnewsreader/
│       │   │               ├── AddFolderDialogFragment.java
│       │   │               ├── Constants.java
│       │   │               ├── DirectoryChooserActivity.java
│       │   │               ├── FolderOptionsDialogFragment.java
│       │   │               ├── LazyLoadingLinearLayoutManager.kt
│       │   │               ├── ListView/
│       │   │               │   ├── BlockingExpandableListView.java
│       │   │               │   ├── PodcastArrayAdapter.java
│       │   │               │   ├── PodcastFeedArrayAdapter.java
│       │   │               │   └── SubscriptionExpandableListAdapter.java
│       │   │               ├── LoginDialogActivity.java
│       │   │               ├── NewFeedActivity.java
│       │   │               ├── NewsDetailActivity.java
│       │   │               ├── NewsDetailFragment.java
│       │   │               ├── NewsDetailImageDialogFragment.java
│       │   │               ├── NewsReaderApplication.java
│       │   │               ├── NewsReaderDetailFragment.java
│       │   │               ├── NewsReaderListActivity.java
│       │   │               ├── NewsReaderListDialogFragment.java
│       │   │               ├── NewsReaderListFragment.java
│       │   │               ├── NewsReaderOPMLImportDialogFragment.java
│       │   │               ├── PiPVideoPlaybackActivity.java
│       │   │               ├── PodcastFragment.java
│       │   │               ├── PodcastFragmentActivity.java
│       │   │               ├── SettingsActivity.java
│       │   │               ├── SettingsFragment.java
│       │   │               ├── VersionInfoDialogFragment.java
│       │   │               ├── adapter/
│       │   │               │   ├── HasId.kt
│       │   │               │   ├── NewsListRecyclerAdapter.java
│       │   │               │   ├── ProgressBarWebChromeClient.kt
│       │   │               │   ├── ProgressViewHolder.kt
│       │   │               │   ├── RecyclerItemClickListener.kt
│       │   │               │   ├── RssItemCardViewHolder.kt
│       │   │               │   ├── RssItemFullTextViewHolder.kt
│       │   │               │   ├── RssItemHeadlineThumbnailViewHolder.kt
│       │   │               │   ├── RssItemHeadlineViewHolder.kt
│       │   │               │   ├── RssItemTextViewHolder.kt
│       │   │               │   ├── RssItemThumbnailViewHolder.kt
│       │   │               │   ├── RssItemViewHolder.java
│       │   │               │   └── RssItemWebViewHolder.kt
│       │   │               ├── async_tasks/
│       │   │               │   ├── DownloadChangelogTask.java
│       │   │               │   ├── DownloadImageHandler.java
│       │   │               │   └── RssItemToHtmlTask.java
│       │   │               ├── authentication/
│       │   │               │   ├── AccountGeneral.java
│       │   │               │   ├── OwnCloudAccountAuthenticator.java
│       │   │               │   └── OwnCloudSyncAdapter.java
│       │   │               ├── chrometabs/
│       │   │               │   └── KeepAliveService.kt
│       │   │               ├── database/
│       │   │               │   ├── DatabaseConnectionOrm.java
│       │   │               │   ├── DatabaseHelperOrm.java
│       │   │               │   ├── generator/
│       │   │               │   │   ├── DatabaseOrmGenerator.java
│       │   │               │   │   ├── LastestVersion.java
│       │   │               │   │   └── SchemaVersion.java
│       │   │               │   └── model/
│       │   │               │       ├── CurrentRssItemView.java
│       │   │               │       ├── CurrentRssItemViewDao.java
│       │   │               │       ├── DaoMaster.java
│       │   │               │       ├── DaoSession.java
│       │   │               │       ├── Feed.java
│       │   │               │       ├── FeedDao.java
│       │   │               │       ├── Folder.java
│       │   │               │       ├── FolderDao.java
│       │   │               │       ├── RssItem.java
│       │   │               │       └── RssItemDao.java
│       │   │               ├── di/
│       │   │               │   ├── ApiModule.java
│       │   │               │   ├── ApiProvider.java
│       │   │               │   └── AppComponent.java
│       │   │               ├── events/
│       │   │               │   └── podcast/
│       │   │               │       ├── CollapsePodcastView.java
│       │   │               │       ├── ExitPlayback.java
│       │   │               │       ├── ExpandPodcastView.java
│       │   │               │       ├── NewPodcastPlaybackListener.java
│       │   │               │       ├── PodcastCompletedEvent.java
│       │   │               │       ├── PodcastFeedClicked.kt
│       │   │               │       ├── RegisterVideoOutput.java
│       │   │               │       ├── SeekPodcast.java
│       │   │               │       ├── SpeedPodcast.java
│       │   │               │       ├── StartDownloadPodcast.kt
│       │   │               │       ├── TogglePlayerStateEvent.java
│       │   │               │       └── WindPodcast.java
│       │   │               ├── helper/
│       │   │               │   ├── AppCompatPreferenceActivity.java
│       │   │               │   ├── AsyncTaskHelper.java
│       │   │               │   ├── AutoResizeTextView.java
│       │   │               │   ├── ColorHelper.java
│       │   │               │   ├── DatabaseUtils.kt
│       │   │               │   ├── DateTimeFormatter.java
│       │   │               │   ├── FavIconHandler.java
│       │   │               │   ├── FavIconUtils.java
│       │   │               │   ├── ForegroundListener.kt
│       │   │               │   ├── GsonConfig.java
│       │   │               │   ├── ImageDownloadFinished.java
│       │   │               │   ├── ImageHandler.java
│       │   │               │   ├── NetworkConnection.java
│       │   │               │   ├── NewsFileUtils.java
│       │   │               │   ├── NextcloudGlideModule.kt
│       │   │               │   ├── NotificationActionReceiver.java
│       │   │               │   ├── NotificationActionReceiverDownloadWebPage.java
│       │   │               │   ├── OpmlXmlParser.java
│       │   │               │   ├── PostDelayHandler.java
│       │   │               │   ├── Search.java
│       │   │               │   ├── StopWatch.java
│       │   │               │   ├── ThemeChooser.java
│       │   │               │   ├── ThemeUtils.java
│       │   │               │   └── URLConnectionReader.kt
│       │   │               ├── interfaces/
│       │   │               │   ├── ExpListTextClicked.java
│       │   │               │   └── IPlayPausePodcastClicked.java
│       │   │               ├── model/
│       │   │               │   ├── AbstractItem.java
│       │   │               │   ├── ConcreteFeedItem.java
│       │   │               │   ├── CurrentRssViewDataHolder.java
│       │   │               │   ├── FolderSubscribtionItem.java
│       │   │               │   ├── MediaItem.java
│       │   │               │   ├── NextcloudNewsVersion.java
│       │   │               │   ├── NextcloudStatus.java
│       │   │               │   ├── OcsUser.java
│       │   │               │   ├── PodcastFeedItem.java
│       │   │               │   ├── PodcastItem.java
│       │   │               │   ├── TTSItem.java
│       │   │               │   └── Tuple.java
│       │   │               ├── notification/
│       │   │               │   └── NextcloudNotificationManager.java
│       │   │               ├── providers/
│       │   │               │   └── OwnCloudSyncProvider.kt
│       │   │               ├── reader/
│       │   │               │   ├── FeedItemTags.java
│       │   │               │   ├── InsertIntoDatabase.java
│       │   │               │   ├── OnAsyncTaskCompletedListener.java
│       │   │               │   └── nextcloud/
│       │   │               │       ├── IHandleJsonObject.java
│       │   │               │       ├── InsertRssItemIntoDatabase.java
│       │   │               │       ├── ItemIds.java
│       │   │               │       ├── ItemMap.java
│       │   │               │       ├── ItemStateSync.java
│       │   │               │       ├── NewsAPI.java
│       │   │               │       ├── NextcloudNewsDeserializer.java
│       │   │               │       ├── NextcloudServerDeserializer.java
│       │   │               │       ├── OcsAPI.java
│       │   │               │       ├── RssItemObservable.java
│       │   │               │       └── Types.java
│       │   │               ├── services/
│       │   │               │   ├── DownloadImagesService.java
│       │   │               │   ├── DownloadWebPageService.java
│       │   │               │   ├── OwnCloudAuthenticatorService.kt
│       │   │               │   ├── OwnCloudSyncService.java
│       │   │               │   ├── PodcastDownloadService.java
│       │   │               │   ├── PodcastPlaybackService.java
│       │   │               │   ├── SyncItemStateService.java
│       │   │               │   ├── events/
│       │   │               │   │   ├── StopWebArchiveDownloadEvent.kt
│       │   │               │   │   ├── SyncFailedEvent.kt
│       │   │               │   │   ├── SyncFinishedEvent.kt
│       │   │               │   │   └── SyncStartedEvent.kt
│       │   │               │   └── podcast/
│       │   │               │       ├── MediaPlayerPlaybackService.java
│       │   │               │       ├── PlaybackService.java
│       │   │               │       └── TTSPlaybackService.java
│       │   │               ├── ssl/
│       │   │               │   ├── MTMDecision.java
│       │   │               │   ├── MemorizingDialogFragment.java
│       │   │               │   ├── MemorizingTrustManager.java
│       │   │               │   ├── OkHttpSSLClient.java
│       │   │               │   └── TLSSocketFactory.kt
│       │   │               ├── view/
│       │   │               │   ├── AnimatingProgressBar.java
│       │   │               │   ├── ChangeLogFileListView.kt
│       │   │               │   ├── PodcastNotification.java
│       │   │               │   └── PodcastSlidingUpPanelLayout.java
│       │   │               └── widget/
│       │   │                   ├── WidgetNewsViewsFactory.java
│       │   │                   ├── WidgetProvider.java
│       │   │                   └── WidgetService.kt
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── all_read_success.xml
│       │       │   ├── slide_in_left.xml
│       │       │   ├── slide_in_right.xml
│       │       │   ├── slide_out_left.xml
│       │       │   └── slide_out_right.xml
│       │       ├── color/
│       │       │   ├── options_menu_item.xml
│       │       │   └── options_menu_item_night.xml
│       │       ├── drawable/
│       │       │   ├── background_with_shadow.xml
│       │       │   ├── checkbox_background_holo_dark.xml
│       │       │   ├── cursor.xml
│       │       │   ├── custom_progress.xml
│       │       │   ├── fa_all_read_target.xml
│       │       │   ├── fa_all_read_target_success.xml
│       │       │   ├── fa_bg.xml
│       │       │   ├── feed_icon.xml
│       │       │   ├── ic_action_delete_24.xml
│       │       │   ├── ic_action_delete_24_theme_aware.xml
│       │       │   ├── ic_action_download_24.xml
│       │       │   ├── ic_action_expand_less_24.xml
│       │       │   ├── ic_action_open_in_browser_24.xml
│       │       │   ├── ic_action_open_in_browser_24_theme_aware.xml
│       │       │   ├── ic_action_pause_24.xml
│       │       │   ├── ic_add_black_24dp.xml
│       │       │   ├── ic_baseline_account_circle_24.xml
│       │       │   ├── ic_baseline_create_new_folder_24_black.xml
│       │       │   ├── ic_baseline_folder_24.xml
│       │       │   ├── ic_baseline_play_arrow_24.xml
│       │       │   ├── ic_baseline_play_arrow_24_theme_aware.xml
│       │       │   ├── ic_checkbox_black.xml
│       │       │   ├── ic_checkbox_outline_black.xml
│       │       │   ├── ic_checkbox_outline_theme_aware.xml
│       │       │   ├── ic_checkbox_outline_white.xml
│       │       │   ├── ic_checkbox_theme_aware.xml
│       │       │   ├── ic_checkbox_white.xml
│       │       │   ├── ic_done_all.xml
│       │       │   ├── ic_forward_30_24.xml
│       │       │   ├── ic_launcher_background.xml
│       │       │   ├── ic_launcher_foreground.xml
│       │       │   ├── ic_replay_10_24.xml
│       │       │   ├── ic_search_24dp_theme_aware.xml
│       │       │   ├── ic_settings_black_24dp.xml
│       │       │   ├── ic_share_theme_aware.xml
│       │       │   ├── ic_share_white.xml
│       │       │   ├── ic_slow_motion_video_24.xml
│       │       │   ├── ic_star_24_theme_aware.xml
│       │       │   ├── ic_star_black_24dp.xml
│       │       │   ├── ic_star_border_24dp_theme_aware.xml
│       │       │   ├── ic_star_white_24.xml
│       │       │   ├── ic_visibility_24.xml
│       │       │   ├── incognito.xml
│       │       │   ├── rounded_rectangle.xml
│       │       │   ├── shadow.xml
│       │       │   ├── swipe_markasread.xml
│       │       │   ├── swipe_openinbrowser.xml
│       │       │   ├── swipe_setstarred.xml
│       │       │   ├── swipe_share.xml
│       │       │   └── widget_background.xml
│       │       ├── layout/
│       │       │   ├── activity_login_dialog.xml
│       │       │   ├── activity_new_feed.xml
│       │       │   ├── activity_news_detail.xml
│       │       │   ├── activity_newsreader.xml
│       │       │   ├── activity_pip_video_playback.xml
│       │       │   ├── activity_settings.xml
│       │       │   ├── dialog_list_folder.xml
│       │       │   ├── dialog_version_info.xml
│       │       │   ├── empty_content_view.xml
│       │       │   ├── fragment_dialog_add_folder.xml
│       │       │   ├── fragment_dialog_feedoptions.xml
│       │       │   ├── fragment_dialog_folderoptions.xml
│       │       │   ├── fragment_dialog_image.xml
│       │       │   ├── fragment_dialog_listviewitem.xml
│       │       │   ├── fragment_dialog_opml_import.xml
│       │       │   ├── fragment_news_detail.xml
│       │       │   ├── fragment_newsreader_detail.xml
│       │       │   ├── fragment_newsreader_list.xml
│       │       │   ├── fragment_newsreader_list_footer.xml
│       │       │   ├── fragment_podcast.xml
│       │       │   ├── podcast_feed_row.xml
│       │       │   ├── podcast_row.xml
│       │       │   ├── progressbar_item.xml
│       │       │   ├── subscription_detail_list_item_card_view.xml
│       │       │   ├── subscription_detail_list_item_headline.xml
│       │       │   ├── subscription_detail_list_item_headline_thumbnail.xml
│       │       │   ├── subscription_detail_list_item_podcast_wrapper.xml
│       │       │   ├── subscription_detail_list_item_text.xml
│       │       │   ├── subscription_detail_list_item_thumbnail.xml
│       │       │   ├── subscription_detail_list_item_web_layout.xml
│       │       │   ├── subscription_list_item.xml
│       │       │   ├── subscription_list_sub_item.xml
│       │       │   ├── toolbar_layout.xml
│       │       │   ├── widget_fastactions_detailview.xml
│       │       │   ├── widget_item.xml
│       │       │   └── widget_layout.xml
│       │       ├── layout-sw600dp-land/
│       │       │   └── activity_newsreader.xml
│       │       ├── menu/
│       │       │   ├── list_footer_menu.xml
│       │       │   ├── news_detail.xml
│       │       │   └── news_reader.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       ├── values/
│       │       │   ├── attrs.xml
│       │       │   ├── booleans.xml
│       │       │   ├── colors.xml
│       │       │   ├── config.xml
│       │       │   ├── dimens.xml
│       │       │   ├── integers.xml
│       │       │   ├── isrighttoleft.xml
│       │       │   ├── strings.xml
│       │       │   ├── styles.xml
│       │       │   └── themes.xml
│       │       ├── values-ar/
│       │       │   └── strings.xml
│       │       ├── values-ast/
│       │       │   └── strings.xml
│       │       ├── values-bg-rBG/
│       │       │   └── strings.xml
│       │       ├── values-ca/
│       │       │   └── strings.xml
│       │       ├── values-cs-rCZ/
│       │       │   └── strings.xml
│       │       ├── values-da/
│       │       │   └── strings.xml
│       │       ├── values-de/
│       │       │   └── strings.xml
│       │       ├── values-el/
│       │       │   └── strings.xml
│       │       ├── values-en-rGB/
│       │       │   └── strings.xml
│       │       ├── values-es/
│       │       │   └── strings.xml
│       │       ├── values-es-rCL/
│       │       │   └── strings.xml
│       │       ├── values-es-rCO/
│       │       │   └── strings.xml
│       │       ├── values-es-rCR/
│       │       │   └── strings.xml
│       │       ├── values-es-rDO/
│       │       │   └── strings.xml
│       │       ├── values-es-rEC/
│       │       │   └── strings.xml
│       │       ├── values-es-rGT/
│       │       │   └── strings.xml
│       │       ├── values-es-rHN/
│       │       │   └── strings.xml
│       │       ├── values-es-rMX/
│       │       │   └── strings.xml
│       │       ├── values-es-rNI/
│       │       │   └── strings.xml
│       │       ├── values-es-rPA/
│       │       │   └── strings.xml
│       │       ├── values-es-rPE/
│       │       │   └── strings.xml
│       │       ├── values-es-rPR/
│       │       │   └── strings.xml
│       │       ├── values-es-rPY/
│       │       │   └── strings.xml
│       │       ├── values-es-rSV/
│       │       │   └── strings.xml
│       │       ├── values-es-rUS/
│       │       │   └── strings.xml
│       │       ├── values-es-rUY/
│       │       │   └── strings.xml
│       │       ├── values-et-rEE/
│       │       │   └── strings.xml
│       │       ├── values-eu/
│       │       │   └── strings.xml
│       │       ├── values-fa/
│       │       │   └── strings.xml
│       │       ├── values-fi-rFI/
│       │       │   └── strings.xml
│       │       ├── values-fr/
│       │       │   └── strings.xml
│       │       ├── values-ga/
│       │       │   └── strings.xml
│       │       ├── values-gl/
│       │       │   └── strings.xml
│       │       ├── values-he/
│       │       │   └── strings.xml
│       │       ├── values-hr/
│       │       │   └── strings.xml
│       │       ├── values-hu-rHU/
│       │       │   └── strings.xml
│       │       ├── values-id/
│       │       │   └── strings.xml
│       │       ├── values-is/
│       │       │   └── strings.xml
│       │       ├── values-it/
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP/
│       │       │   └── strings.xml
│       │       ├── values-ka-rGE/
│       │       │   └── strings.xml
│       │       ├── values-ko/
│       │       │   └── strings.xml
│       │       ├── values-large/
│       │       │   ├── refs.xml
│       │       │   └── styles.xml
│       │       ├── values-ldrtl/
│       │       │   └── isrighttoleft.xml
│       │       ├── values-lo/
│       │       │   └── strings.xml
│       │       ├── values-lt-rLT/
│       │       │   └── strings.xml
│       │       ├── values-nb-rNO/
│       │       │   └── strings.xml
│       │       ├── values-night/
│       │       │   ├── booleans.xml
│       │       │   └── colors.xml
│       │       ├── values-nl/
│       │       │   └── strings.xml
│       │       ├── values-oc/
│       │       │   └── strings.xml
│       │       ├── values-pl/
│       │       │   └── strings.xml
│       │       ├── values-pt-rBR/
│       │       │   └── strings.xml
│       │       ├── values-pt-rPT/
│       │       │   └── strings.xml
│       │       ├── values-ro/
│       │       │   └── strings.xml
│       │       ├── values-ru/
│       │       │   └── strings.xml
│       │       ├── values-sc/
│       │       │   └── strings.xml
│       │       ├── values-sk-rSK/
│       │       │   └── strings.xml
│       │       ├── values-sl/
│       │       │   └── strings.xml
│       │       ├── values-sq/
│       │       │   └── strings.xml
│       │       ├── values-sr/
│       │       │   └── strings.xml
│       │       ├── values-sr-rSP/
│       │       │   └── strings.xml
│       │       ├── values-sv/
│       │       │   └── strings.xml
│       │       ├── values-sw/
│       │       │   └── strings.xml
│       │       ├── values-sw600dp/
│       │       │   └── config.xml
│       │       ├── values-sw720dp-land/
│       │       │   └── dimens.xml
│       │       ├── values-th-rTH/
│       │       │   └── strings.xml
│       │       ├── values-tr/
│       │       │   └── strings.xml
│       │       ├── values-ug/
│       │       │   └── strings.xml
│       │       ├── values-uk/
│       │       │   └── strings.xml
│       │       ├── values-v23/
│       │       │   └── themes.xml
│       │       ├── values-v27/
│       │       │   └── themes.xml
│       │       ├── values-vi/
│       │       │   └── strings.xml
│       │       ├── values-w820dp/
│       │       │   └── dimens.xml
│       │       ├── values-zh-rCN/
│       │       │   └── strings.xml
│       │       ├── values-zh-rHK/
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW/
│       │       │   └── strings.xml
│       │       └── xml/
│       │           ├── account_preferences.xml
│       │           ├── authenticator.xml
│       │           ├── automotive_app_desc.xml
│       │           ├── file_provider_paths.xml
│       │           ├── pref_about.xml
│       │           ├── pref_data_sync.xml
│       │           ├── pref_display.xml
│       │           ├── pref_general.xml
│       │           ├── syncadapter.xml
│       │           └── widget_info.xml
│       └── test/
│           ├── java/
│           │   └── de/
│           │       └── luhmer/
│           │           └── owncloudnewsreader/
│           │               ├── asynctasks/
│           │               │   └── RssItemToHtmlTaskTest.kt
│           │               └── junit_tests/
│           │                   ├── ImageHandlerTest.java
│           │                   └── TestDbTest.java
│           └── resources/
│               └── org.robolectric.Config.properties
├── PRIVACY.md
├── README.md
├── Screengrabfile
├── build.gradle
├── config/
│   └── detekt/
│       └── detekt.yml
├── docker-nextcloud-test-instances/
│   ├── .gitignore
│   ├── README.md
│   └── docker-compose.yaml
├── executeScreengrab.sh
├── fastlane/
│   ├── Fastfile
│   ├── README.md
│   └── metadata/
│       └── android/
│           ├── de-DE/
│           │   ├── changelogs/
│           │   │   ├── 166.txt
│           │   │   ├── 167.txt
│           │   │   ├── 168.txt
│           │   │   ├── 170.txt
│           │   │   ├── 171.txt
│           │   │   ├── 172.txt
│           │   │   ├── 173.txt
│           │   │   ├── 174.txt
│           │   │   ├── 175.txt
│           │   │   ├── 176.txt
│           │   │   ├── 177.txt
│           │   │   ├── 178.txt
│           │   │   ├── 179.txt
│           │   │   ├── 180.txt
│           │   │   ├── 181.txt
│           │   │   ├── 182.txt
│           │   │   ├── 183.txt
│           │   │   ├── 184.txt
│           │   │   ├── 185.txt
│           │   │   ├── 186.txt
│           │   │   ├── 189.txt
│           │   │   ├── 190.txt
│           │   │   ├── 191.txt
│           │   │   ├── 192.txt
│           │   │   ├── 193.txt
│           │   │   ├── 194.txt
│           │   │   ├── 195.txt
│           │   │   └── 196.txt
│           │   ├── full_description.txt
│           │   ├── short_description.txt
│           │   ├── title.txt
│           │   └── video.txt
│           └── en-US/
│               ├── changelogs/
│               │   ├── 166.txt
│               │   ├── 167.txt
│               │   ├── 168.txt
│               │   ├── 170.txt
│               │   ├── 171.txt
│               │   ├── 172.txt
│               │   ├── 173.txt
│               │   ├── 174.txt
│               │   ├── 175.txt
│               │   ├── 176.txt
│               │   ├── 177.txt
│               │   ├── 178.txt
│               │   ├── 179.txt
│               │   ├── 180.txt
│               │   ├── 181.txt
│               │   ├── 182.txt
│               │   ├── 183.txt
│               │   ├── 184.txt
│               │   ├── 185.txt
│               │   ├── 186.txt
│               │   ├── 189.txt
│               │   ├── 190.txt
│               │   ├── 191.txt
│               │   ├── 192.txt
│               │   ├── 193.txt
│               │   ├── 194.txt
│               │   ├── 195.txt
│               │   └── 196.txt
│               ├── full_description.txt
│               ├── short_description.txt
│               ├── title.txt
│               └── video.txt
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── security/
│   └── GHSL-2021-1033_Nextcloud_News_for_Android.md
└── settings.gradle

================================================
FILE CONTENTS
================================================

================================================
FILE: .editorconfig
================================================
[*.{kt,kts}]
max_line_length = 120


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

custom: https://www.paypal.com/donate?hosted_button_id=5TJ6LTEVTDF5J


================================================
FILE: .github/dependabot.yml
================================================
version: 2
updates:
- package-ecosystem: gradle
  directory: "/"
  schedule:
    interval: daily
  open-pull-requests-limit: 5
- package-ecosystem: github-actions
  directory: "/"
  schedule:
    interval: daily
  open-pull-requests-limit: 5


================================================
FILE: .github/workflows/analysis.yml
================================================
name: Analysis

# Declare default permissions as read only.
permissions: read-all

on: [push, pull_request]
jobs:
  detekt:
    name: detekt
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    steps:
      - uses: actions/checkout@v6
      - name: set up JDK 21
        uses: actions/setup-java@v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
      - name: Run detekt
        run: bash ./gradlew detekt
  spotless:
    name: Spotless (ktlint)
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    steps:
      - uses: actions/checkout@v6
      - name: set up JDK 21
        uses: actions/setup-java@v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
      - name: Run spotless
        run: bash ./gradlew spotlessCheck


================================================
FILE: .github/workflows/ci.yml
================================================
name: Android CI

on: [push, pull_request]
jobs:
  validation:
    name: Validate Gradle Wrapper
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    steps:
      - uses: actions/checkout@v6
      - uses: gradle/actions/wrapper-validation@v6

  lint:
    name: Run Lint Checks
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    steps:
      - uses: actions/checkout@v6
      - name: set up JDK 21
        uses: actions/setup-java@v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
      - name: Lint
        run: bash ./gradlew lint

  test:
    name: Run Unit Tests
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    steps:
      - uses: actions/checkout@v6
      - name: set up JDK 21
        uses: actions/setup-java@v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
      - name: Unit tests
        run: bash ./gradlew test --stacktrace

  apk:
    name: Generate APK
    runs-on: ubuntu-latest
    if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
    steps:
      - uses: actions/checkout@v6
      - name: set up JDK 21
        uses: actions/setup-java@v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
      - name: Build debug APK
        run: bash ./gradlew assembleDev --stacktrace
      - name: Upload APK
        uses: actions/upload-artifact@v7
        with:
          name: app-dev-debug
          path: News-Android-App/build/outputs/apk/dev/debug/News-Android-App-dev-debug.apk


================================================
FILE: .github/workflows/codeql.yml
================================================
name: CodeQL

on:
  push:
    branches-ignore:
      - 'dependabot/**'
  pull_request:
jobs:
  codeql:
    name: CodeQL security scan
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v6
      - name: set up JDK 21
        uses: actions/setup-java@v5.2.0
        with:
          distribution: 'temurin'
          java-version: 21
      - name: Initialize CodeQL
        uses: github/codeql-action/init@v4
        with:
          languages: java
      - name: Build debug APK
        run: bash ./gradlew assembleDev
      - name: Perform CodeQL Analysis
        uses: github/codeql-action/analyze@v4


================================================
FILE: .gitignore
================================================
/local.properties
/.idea/workspace.xml
.DS_Store

# built application files
*.apk
*.ap_

# files for the dex VM
*.dex

# Java class files
*.class

# generated files
bin/
gen/

# Local configuration file (sdk path, etc)
local.properties

# Eclipse project files
.classpath
.project
.settings

# Android Studio
.idea/
.gradle
/*/local.properties
/*/out
/*/*/build
build/*
/*/*/production
*.iml
*.iws
*.ipr
*~
*.swp
News-Android-App/out.map
News-Android-App/extra/release/*
News-Android-App/oss/release/*
fastlane/Appfile
fastlane/report.xml
gradle/verification-keyring.gpg


================================================
FILE: .tx/config
================================================
[main]
host = https://www.transifex.com

[o:nextcloud:p:nextcloud:r:android-news]
file_filter = News-Android-App/src/main/res/values-<lang>/strings.xml
source_file = News-Android-App/src/main/res/values/strings.xml
source_lang = en
type        = ANDROID
lang_map    = ar_YE: ar-rYE, es_CL: es-rCL, ii_CN: ii-rCN, lt_LT: lt-rLT, pt_BR: pt-rBR, nso_ZA: nso-rZA, rw_RW: rw-rRW, sr_RS: sr-rRS, bo_CN: bo-rCN, en_MY: en-rMY, tg_TJ: tg-rTJ, de_LI: de-rLI, en_JM: en-rJM, en_NZ: en-rNZ, pa_IN: pa-rIN, tr_TR: tr-rTR, en_DE: en-rDE, en_IN: en-rIN, es_DO: es-rDO, hu_HU: hu-rHU, ml_IN: ml-rIN, fo_FO: fo-rFO, gl_ES: gl-rES, smj_SE: smj-rSE, ar_LB: ar-rLB, es_CO: es-rCO, et_EE: et-rEE, ha_NG: ha-rNG, as_IN: as-rIN, es_MX: es-rMX, iu_CA: iu-rCA, fr_LU: fr-rLU, mt_MT: mt-rMT, quz_PE: quz-rPE, se_NO: se-rNO, ca@valencia: ca-rXV, id_ID: id-rID, mi_NZ: mi-rNZ, uk_UA: uk-rUA, kl_GL: kl-rGL, smn_FI: smn-rFI, ar_AE: ar-rAE, arn_CL: arn-rCL, ka_GE: ka-rGE, ca_ES: ca-rES, es_HN: es-rHN, ar_QA: ar-rQA, gu_IN: gu-rIN, ar_SY: ar-rSY, bg_BG: bg-rBG, da_DK: da-rDK, se_SE: se-rSE, sma_SE: sma-rSE, sr_BA: sr-rBA, ar_EG: ar-rEG, fi_FI: fi-rFI, gd_GB: gd-rGB, sr_ME: sr-rME, en@pirate: en-rXP, lv_LV: lv-rLV, sv_SE: sv-rSE, de_CH: de-rCH, fa_IR: fa-rIR, mn_MN: mn-rMN, sms_FI: sms-rFI, ur_PK: ur-rPK, zh_HK: zh-rHK, tn_ZA: tn-rZA, ar_LY: ar-rLY, fil_PH: fil-rPH, ku_IQ: ku-rIQ, nn_NO: nn-rNO, sah_RU: sah-rRU, ta_LK: ta-rLK, en_ZW: en-rZW, ro_RO: ro-rRO, en_TT: en-rTT, br_FR: br-rFR, es_BO: es-rBO, tk_TM: tk-rTM, es_419: es-rUS, qut_GT: qut-rGT, bn_BD: bn-rBD, en_AU: en-rAU, hsb_DE: hsb-rDE, en_IE: en-rIE, kk_KZ: kk-rKZ, mr_IN: mr-rIN, ar_BH: ar-rBH, ru_RU: ru-rRU, be_BY: be-rBY, es_CR: es-rCR, es_PY: es-rPY, mk_MK: mk-rMK, prs_AF: prs-rAF, it_CH: it-rCH, ps_AF: ps-rAF, ar_DZ: ar-rDZ, hr_HR: hr-rHR, zh_CN.GB2312: zh-rBG, pl_PL: pl-rPL, sr_CS: sr-rCS, vi_VN: vi-rVN, mn_CN: mn-rCN, es_PA: es-rPA, hr_BA: hr-rBA, ja_JP: ja-rJP, en_CA: en-rCA, en_US: en-rUS, he_IL: he-rIL, wo_SN: wo-rSN, sq_AL: sq-rAL, ar_KW: ar-rKW, ar_TN: ar-rTN, de_DE: de-rDE, or_IN: or-rIN, rm_CH: rm-rCH, ba_RU: ba-rRU, en_ZA: en-rZA, es_ES: es-rES, bs_BA: bs-rBA, cy_GB: cy-rGB, en_GB: en-rGB, moh_CA: moh-rCA, ms_MY: ms-rMY, syr_SY: syr-rSY, zh_MO: zh-rMO, dv_MV: dv-rMV, se_FI: se-rFI, it_IT: it-rIT, quz_BO: quz-rBO, de_AT: de-rAT, kok_IN: kok-rIN, fy_NL: fy-rNL, ig_NG: ig-rNG, ko_KR: ko-rKR, fr_MC: fr-rMC, zh_TW: zh-rTW, am_ET: am-rET, ar_OM: ar-rOM, es_VE: es-rVE, oc_FR: oc-rFR, co_FR: co-rFR, nl_NL: nl-rNL, pt_PT: pt-rPT, lb_LU: lb-rLU, ar_JO: ar-rJO, cs_CZ: cs-rCZ, es_PE: es-rPE, es_PR: es-rPR, ga_IE: ga-rIE, tzm_DZ: tzm-rDZ, yo_NG: yo-rNG, hy_AM: hy-rAM, az_AZ: az-rAZ, de_LU: de-rLU, es_GT: es-rGT, nl_BE: nl-rBE, fr_CA: fr-rCA, smj_NO: smj-rNO, en_PH: en-rPH, es_UY: es-rUY, km_KH: km-rKH, sl_SI: sl-rSI, sa_IN: sa-rIN, si_LK: si-rLK, tt_RU: tt-rRU, zh_CN: zh-rCN, af_ZA: af-rZA, en_BZ: en-rBZ, fr_CH: fr-rCH, nb_NO: nb-rNO, sma_NO: sma-rNO, is_IS: is-rIS, kn_IN: kn-rIN, ky_KG: ky-rKG, my_MM: my, sr@latin: sr-rSP, gsw_FR: gsw-rFR, uz_UZ: uz-rUZ, zh_SG: zh-rSG, zu_ZA: zu-rZA, fr_BE: fr-rBE, lo_LA: lo-rLA, ms_BN: ms-rBN, ar_SA: ar-rSA, sw_KE: sw-rKE, ar_MA: ar-rMA, xh_ZA: xh-rZA, en_SG: en-rSG, es_EC: es-rEC, fr_FR: fr-rFR, ug_CN: ug-rCN, el_GR: el-rGR, quz_EC: quz-rEC, sv_FI: sv-rFI, th_TH: th-rTH, ar_IQ: ar-rIQ, es_NI: es-rNI, es_SV: es-rSV, sk_SK: sk-rSK, tl_PH: tl-rPH, bn_IN: bn-rIN, es_AR: es-rAR, hi_IN: hi-rIN, ta_IN: ta-rIN, te_IN: te-rIN, eu_ES: eu-rES, dsb_DE: dsb-rDE, ne_NP: ne-rNP



================================================
FILE: CHANGELOG.md
================================================
0.9.9.95
---------------------
- Dependency updates
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1628">!1637 - Fix bug in "Mark all unread items as read" feature (thanks to @Unpublished)</a>

0.9.9.94
---------------------
- Dependency updates
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1628">!1628 - Make syncing when reaching the bottom optional (thanks to @DoHe)</a>

0.9.9.93
---------------------
- Dependency updates
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1612">!1612 - Streamline FAB-aware
  Snackbar usage (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1609">!1609 - Only mark unread
  items as read</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1620">#1620 - Fix broken
  changelog</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1618">#1618 - Fixed broken sync
  when tapping nextcloud logo</a>

0.9.9.92
---------------------
- Dependency updates
- Added - <a href="https://github.com/nextcloud/news-android/pull/1603">!1603 - Automatically
  trigger sync when bottom is reached</a>
- Added - <a href="https://github.com/nextcloud/news-android/issues/1367">#1367 - Add Pinch to zoom
  for images (thanks to @DoHe)</a>
- Added - <a href="https://github.com/nextcloud/news-android/pull/1531">!1531 - Show snackbar after
  batch marking items as read (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1590">#1590 - Fixed broken
  widget</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1591">#1591 - Handle URL
  encoding when reading mediaThumbnail from body (thanks to @DoHe)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1576">#1576 - Import opml do not
  work at all</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1510">#1510 - Client sends form
  data when POSTing instead of JSON</a>
- Many smaller changes under the hood

0.9.9.91
---------------------
- Dependency updates
- Added - <a href="https://github.com/nextcloud/news-android/issues/1490">#1490 - Option to Increase Text Size in Detail View for Accessibility</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1456">#1456 - Bullet points in unsorted item list look all of the same level</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1428">#1428 - Font size a lot smaller when language set to other than English (superseded by #1490) (@thanks to @cemrich)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1498">!1498 - Fix crash when clearing cache</a>

0.9.9.90
---------------------
- Dependency updates
- Added - <a href="https://github.com/nextcloud/news-android/pull/1273">!1273 - Add "remove podcast" in toolbar and "Downloaded podcasts" special folder (thanks to @mkanilsson)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1400">!1400 - Code section shows the same listing in some code posts (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1410">!1410 - Changing theme (light/dark) caused favicons to display in wrong color (thanks to @Unpublished / @DoHe)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1035">#1035 - Widget opens wrong article / #1355 Clicking on the widget jumps to a previously opened article (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1381">#1381 - Crash when opening downloaded podcasts (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1368">#1368 - Images not shown in Details view of specific feeds</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1382">#1382 - Reduced apk size by 8% (thanks to @connyduck)</a>

0.9.9.85
---------------------
- Dependency updates
- Fix crash when playing video podcasts on Android Auto
- Add Google News Policy / Contact Us page

0.9.9.84
---------------------
- Dependency updates
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1332">!1332 - Typo in selected browser preference usage (thanks to @thebaztet)</a>

0.9.9.83
---------------------
- Dependency updates
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1315">!1315 - Fixed crash when reporting errors (API 33 and below) (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1311">!1311 - Fixed flickering of toolbar (thanks to @cemrich)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1306">!1306 - Fix avatar placeholder renders white on white in light theme (thanks to @cemrich)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1303">!1303 - Fix app crashing when streaming or downloading podcasts (thanks to @cemrich)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1304">!1304 - Back button preference and functionality to open sidebar (thanks to @mentalinc)</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1307">!1307 - Enable androids autofill service in login mask (thanks to @cemrich)</a>

0.9.9.82
---------------------
- Note: Due to changes to the database schema the data will be cleared when upgrading
- Note: What a release! Thank you for the endless contributions from the community! 
- Added - <a href="https://github.com/nextcloud/news-android/pull/1262">!1262 - Add shortcut to "Show only unread articles" in the toolbar (thanks to @mkanilsson)</a>
- Added - <a href="https://github.com/nextcloud/news-android/pull/1264">!1264 - Add share to swipe option (thanks to @mkanilsson)</a>
- Added - <a href="https://github.com/nextcloud/news-android/pull/1266">!1266 - per-feed open-in settings (thanks to @mkanilsson)</a>
- Added - <a href="https://github.com/nextcloud/news-android/pull/1265">!1265 - Allow searching both title and body at the same time (thanks to @mkanilsson)</a>
- Added - <a href="https://github.com/nextcloud/news-android/pull/1271">!1271 - Enable support for predictive back gestures (thanks to @KingOfDog)</a>
- Added - <a href="https://github.com/nextcloud/news-android/pull/1286">!1286 - Show changelog after update of app</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1256">!1256 - Fix starred items not obeying sort order (thanks to @mkanilsson)</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1186">!1186 - Material 3 Theme (thanks to @stefan-niedermann)</a>
- Changed - Dependency updates
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1255">!1255 - add line-height for h1 tags (thanks to @mkanilsson)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1257">!1257 - Seeking in podcast player doesn't work (thanks to @annasoin)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1272">!1272 - Fix weird formatting in articles (thanks to @mkanilsson)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1276">#1276 - active toggles lack color</a>

0.9.9.81
---------------------
- Changed - Updated SSO lib

0.9.9.80
---------------------
- Changed - Internal dependency updates
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1212">!1212 - Nextcloud Single-Sign-On updates</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1200">!1200 - Bail out early on generating unread rss items notifications (thanks to @Unpublished)</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1199">!1199 - Housekeeping / Remove unused classes (thanks to @Unpublished)</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1195">!1195 - Migrate some classes to Kotlin (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1214">!1214 - Text formatting is a bit weird</a>

0.9.9.79
---------------------
- Changed - Internal dependency updates
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1171">!1171 - Allow selecting feed URL in options dialog (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1187">!1187 - Fix crash related when trying to move a feed (thanks to @Unpublished)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1184">!1184 - Prevent podcast view from showing up on every app start (thanks to @Unpublished)</a>

0.9.9.78
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/pull/1134">!1134 - Fix broken Notifications on Android 13 (thanks to @Unpublished)</a>

0.9.9.77
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1111">#1111 - Fix incorrect height of listview rows</a>
- Changed - <a href="https://github.com/nextcloud/news-android/pull/1115">!1115 - Switched from Universal-Image-Loader to Glide as image loading library</a>
- Added - Added support for SVG favicons
- Added - <a href="https://github.com/nextcloud/news-android/pull/1130">!1130 - Added support for external media players (thanks to @JFronny)</a>

0.9.9.76
---------------------
- Security related fixes (only F-Droid users affected): [#1109](https://github.com/nextcloud/news-android/issues/1109) / [fdroid/fdroiddata#2753](https://gitlab.com/fdroid/fdroiddata/-/issues/2753)

0.9.9.75
---------------------
- Fixed crash when relative links in articles are clicked
- Support Material You Theming with App Icon (thanks to @salixor)

0.9.9.74
---------------------
- Fixed incompatibility issues with Nextcloud News 18.1.0

0.9.9.73 (Beta)
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1061">#1061 App sometimes crashes on long tap on detail view</a>
- Fixed database crashed by reducing the number of loaded items per page
- Fixed crash when long tapping folders in navigation drawer
- Fixed app crash when ui updates
- Fixed crashes caused by swiping on articles in list view

0.9.9.72 (Beta)
---------------------
- Added - <a href="https://github.com/nextcloud/news-android/pull/1066">!1066 Support for Folder Management (Rename, Remove, Create) (thanks @proninyaroslav)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1075">#1075 Feed name update not updating in RSS items (thanks @proninyaroslav)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1064">#1064 Add button to exit audio/podcast player once it's open</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1048">#1048 Fix broken podcast time scrolling</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1053">#1053 Podcast player disappears after rotating device</a>

0.9.9.71 (Beta)
---------------------
- Added - <a href="https://github.com/nextcloud/news-android/issues/1060">#1060 Always show incognito mode icon if incognito mode is enabled</a>

0.9.9.70 (Beta)
---------------------
- Fixed - Try to fix more app crashes during sync (reduce number of items per sync)
- Fixed - Speedup detail view by not storing instance state of webview

0.9.9.69
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1055">#1055 App crashes during sync (OutOfMemory Error)</a>

0.9.9.68 (Beta)
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1012">#1012 Loadingbar is visible even though page is done loading</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1029">#1029 Unread list does not actualize after manual update (Only when using legacy login)</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1046">#1046 "No notification" setting still generates notifications in separate notification channel</a>
- Fixed - Fix missing images if webview has been restored (e.g. after app has been in background)
- Fixed - News App is broken after restoring it from a backup (when using SSO)

0.9.9.67 (Beta)
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1044">#1044 Colors/Theme sometimes not applied</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1042">#1042 Relative image links/URLs don't open correctly</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1039">#1039 SSO not working with Beta Version of Files App</a>

0.9.9.66 (Beta)
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1036">#1036 Fixed crashes on Android 12 devices</a> (#1032 / #1037)

0.9.9.65 (Beta)
---------------------
- Fixed - Fix broken sync due to incompatibility between latest nextcloud files app and Single Sign On Library

0.9.9.64 (Beta)
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1006">#1006 Refactor and fix sync issues</a>
- Changed - Improve OPML import dialog
- Changed - Increase the soft limit of articles in the app from 1500 to 5000 articles

0.9.9.63 (Beta)
---------------------
- Added - <a href="https://github.com/nextcloud/news-android/issues/1002">#1002 support for more granular notification settings</a>
- Changed - added file extension to downloaded/exported images
- Changed - allow clicks on notification after an image has been saved/downloaded from detail view
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/1018">#1018 Item state sync is not working correctly when many items have been changed</a>
- Fix security issue GHSL-2021-1033 (Thanks to GitHub Security Lab - with special thanks to Tony Torralba and Kevin Backhouse)

0.9.9.62
---------------------
- Changed - <a href="https://github.com/nextcloud/news-android/issues/824">#824 Enhance empty content view (thanks Stefan)</a>
- Changed - <a href="https://github.com/nextcloud/news-android/issues/976">#976 Sync Interval - settings menu is now a popup (thanks @fabienli)</a>
- Changed - <a href="https://github.com/nextcloud/news-android/issues/974">#974 only show notification if it is different to the previous unread articles list</a>

0.9.9.61
---------------------
- Changed - <a href="https://github.com/nextcloud/news-android/issues/969">#969 Remove unnecessary Notifications setting</a>
- Changed - <a href="https://github.com/nextcloud/news-android/issues/968">#968 Rename "Light/Dark (based on Daytime)" to "System Default"</a>
- Changed - <a href="https://github.com/nextcloud/news-android/issues/960">#960 Make articles respect default system font</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/964">#964 Crash when using card layout</a>

0.9.9.60
---------------------
- Changed - Major Design Update thanks to @stefan-niedermann!
- Changed - <a href="https://github.com/nextcloud/news-android/issues/944">#944 Drop dark mode based on location</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/958">#958 OPML Export Dialog is now translated </a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/945">#945 New Thubmnails list layout does not show favorite status</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/938">#938 Everincreasing Fontsize with Fontsize setting "Big"</a>

0.9.9.54
---------------------
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/918">#918 Poor scroll performance for some feeds</a>
- Fixed - <a href="https://github.com/nextcloud/news-android/issues/903">#903 Bottom part of article not visible because of action icons</a>
- Changed - <a href="https://github.com/nextcloud/news-android/issues/929">#929 Widget should respect dark / light theme</a>
- Changed - Auto-Sync is enabled by default now (every 15min)
- Changed - Minor adjustments to UI (including new default list layout)
- Changed - New list layout in the app
- Changed - Widget redesign

0.9.9.53
---------------------
- Version bump for another Google review

0.9.9.52
---------------------
- Version bump for another Google review

0.9.9.51
---------------------
- Version bump for another Google review

0.9.9.50
---------------------
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/880">#880 Starred items were not synchronized in certain situations</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/889">#889 Fast Access Functions activated on startup but settings deactivated</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/892">#892 Refresh unread items view after update</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/403">#403 Problem with syncing "old" favorites</a>
- Changed - <a href="https://github.com/nextcloud/news-android/issues/896">#896 Change User-Info API</a>

0.9.9.41
---------------------
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/887">#887 Fix crashes due to huge rss items</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/878">#878 Floating menu setting had no effect / Show either the floating or the kebab menu</a>
- Feature - <a href="https://github.com/nextcloud/news-android/issues/754">#754 Add more meaningful notifications</a>
- Feature - <a href="https://github.com/nextcloud/news-android/pull/885">!885 Enable auto sync by default (every 24h)</a>

0.9.9.40
---------------------
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/344">#344 Starred items are not synced correctly</a>
- Feature - <a href="https://github.com/nextcloud/news-android/pull/881">!881 When enabled, also use custom tabs when skipping detailed view</a>

0.9.9.39
---------------------
- Google refused update

0.9.9.38
---------------------
- Feature - <a href="https://github.com/nextcloud/news-android/issues/868">#868 - Add thumbnail support (media) articles</a>
- Feature Removal: Double-Tap-To-Star in detail view
- Fix app crashes 

0.9.9.37
---------------------
- New feature: Fast actions (Huge thanks to @emasty)

0.9.9.36
---------------------
- Reduce min-newsApi level to 17

0.9.9.35
---------------------
- Fix Single-Sign On related Issues
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/769">#769 - Nextcloud API not responding</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/830">#830 - Only ask for Location permission if auto theme enabled</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/786">#786 - Error loading xml resource in Android 4.4</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/pull/833">#833 - fix tables are too wide</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/issues/821">#821 - "Add feed"-icon is misaligned</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/pull/827">#821 - Text in drawer not bold, except of "add new feed" and "settings" (thanks @tobiasKaminsky)</a>

0.9.9.34 / 0.9.9.33
---------------------
- Fix F-Droid build issues

0.9.9.32
---------------------
- Fix bug that items containing "image/jpeg" as enclosure, are interpreted as podcasts
- Fix app crash when changing server settings
- Improve opml import / export

0.9.9.31
---------------------
- Feature - <a href="https://github.com/nextcloud/news-android/issues/787">#787 - Display profile avatar in the sidenav</a>
- Feature - <a href="https://github.com/nextcloud/news-android/issues/788">#788 - Move settings menu to sidenav as last entry (thanks @emasty)</a>
- Feature - <a href="https://github.com/nextcloud/news-android/issues/789">#789 - Add a new feed should be in sidenav (thanks @emasty)</a>
- Feature - <a href="https://github.com/nextcloud/news-android/issues/804">#804 - Support Android 10 System DayNight Modes (thanks @wbrawner)</a>
- Feature - <a href="https://github.com/nextcloud/news-android/pull/811">#811 - Android Auto Support (including Voice Control)</a>
- Feature - <a href="https://github.com/nextcloud/news-android/pull/810">#810 - Automatically add debug information when reporting github issue through the app</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/pull/807">#807 - Fixed open article in browser call (thanks @emasty)</a>
- Bug fix - <a href="https://github.com/nextcloud/news-android/pull/806">#806 - Update app icon background layer (thanks @stefan-niedermann)</a>

0.9.9.28 / 0.9.9.29 / 0.9.9.30
---------------------
- Retry rejected review by google due to new android auto support
- Fix - <a href="https://github.com/nextcloud/news-android/issues/795">#795 Adjust app icon to match new regulations</a>
- Feature - <a href="https://github.com/nextcloud/news-android/pull/799">#799 - Added podcast browser for Android Auto App</a>
- Feature - <a href="https://github.com/nextcloud/news-android/issues/798">#798 better display of code blocks</a>
- Feature - <a href="https://github.com/nextcloud/news-android/pull/791">#791 Implement incognito mode</a>

0.9.9.27
---------------------
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/795">#795 Adjust app icon to match new regulations</a>
- Fix - Fix validation of urls during manual account setup

0.9.9.26
---------------------
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/726">#726 Add new feed fails</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/744">#744 Fix issues when adding feeds (thanks @Unpublished)</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/747">#747 Add option to share article when using chrome-custom-tabs</a>
- Fix - Reset database when account is stored
- Fix - Workaround for app-crashes due to widget problems
- Feature - Support for Android Auto (Podcast playback)
- Feature - Use picture-in-picture mode for video podcasts
- Fix - Fix restarts of app due to a bug in android compat library (when using dark mode)

0.9.9.25
---------------------
- Fix - app crashes

0.9.9.24
---------------------
- Fix - app crashes

0.9.9.23
---------------------
- Fix - app crashes
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/717">#717 Launch a synchronization when switching from this app to another</a>

0.9.9.22
---------------------
- Fix - app crash during startup
- Fix - app crash during sync

0.9.9.21
---------------------
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/713">#713 App hangs during sync </a>
- Fix - Sync on startup not working in some cases
- UI Improvement - Improve first app start experience

0.9.9.20
---------------------
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/702">#702 Widget not updating</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/698">#698 Black font color on all layouts</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/696">#696 Background sync (automatic sync) broken</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/693">#693 Fix background color in Settings (Thank you @AnotherDaniel)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/683">#683 OLED bg is lost on orientation change in auto NightMode (Thank you @AnotherDaniel)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/681">#681 Make audio podcasts controllable by Bluetooth media controls</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/678">#678 Settings section/page header text is black, also in dark theme</a>
- UI Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/704">#704 Move About/Changelog to Settings (Thank you @AnotherDaniel)</a>
- UI Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/690">#690 Settings - Disable oled setting if Light theme is selected  (Thank you @AnotherDaniel)</a>
- UI Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/688">#688 Settings - Add missing section header of first/general settings category  (Thank you @AnotherDaniel)</a>
- UI Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/680">#680 Add option to only show headlines</a>
- UI Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/677">#677 New feed items look read</a>

0.9.9.19
---------------------
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/661">#661 NightMode (Thank you @AnotherDaniel)</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/658">#658 Several UI refactorings</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/585">#585 Thumbnail support</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/467">#467 Adjustable Font Size (Thank you @AnotherDaniel)</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/596">#596 Download articles to view them offline</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/664">#664 Order of folders is confusing (Thank you @AnotherDaniel)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/633">#633 swipe upwards to mark as read</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/667">#667 Beeping while podcast playing/downloading</a>

0.9.9.18 (Google Play)
---------------------
- Improve - <a href="https://github.com/owncloud/News-Android-App/issues/651">#651 Automatic reload of rss item list when empty</a>
- Improve - <a href="https://github.com/owncloud/News-Android-App/issues/657">#657 Rename app from "Nextcloud News" to "News"</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/478">#478 Add Search Functionality (Thank you @NilsGriebner)</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/644">#644 Move feed (Thank you @NilsGriebner)</a>
- Improve first sign-on experience
- Several UI improvements
- Single Sign On (first official beta!)

0.9.9.17 (Google Play)
---------------------
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/630">#630 Improve unread rss item count notification (#645)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/646">#646 support for animated gifs on android 8.1</a>
- Fix - Login issues when using passwords with special characters
- Add Single Sign On (requires a non published version of the Nextcloud files app)

0.9.9.16 (Google Play)
---------------------
- Massive improvements to the rss-item-list scrolling performance
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/632">#632 App crash when downloading single image</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/629">#629 Error when trying to fetch more items</a>
- Add support for Android 8+ Notifications
- Added widget preview - thank you @stefan-niedermann
- Added roundIcon for API level 25 - thank you @stefan-niedermann
- Added adaptive icon and adjusted splash screen - thank you @stefan-niedermann

0.9.9.15 (Google Play)
---------------------
- Fix app crashes due to missing translations
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/622">#622 Sync fails (showrss.info feeds)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/618">#618 No white theme in 0.9.9.13 fdroid</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/564">#564 Feed icons don't appear to be caching</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/557">#557 Reloading Icon barely visible</a>
- Add option to change podcast playback speed (thanks @jwaghetti)

0.9.9.14 (Google Play)
---------------------
- Add more translations to reduce number of app crashes
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/617">#617 Strange behaviour when marking read with scroll</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/616">#616 Improve usability - Blue links with dark OLED theme</a>

0.9.9.13 (Google Play)
---------------------
- Optimization - <a href="https://github.com/owncloud/News-Android-App/issues/614">#614 Black background color for OLED screens (New Theme)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/612">#612 Impossible to delete or edit RSS feeds</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/607">#607 Workaround for SSL Handshake failed on Android 7.0 (thank you @svenschn)</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/606">#606 App crash when opening "Settings" on Android 4.2</a>
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/591">#591 Add option to load links in feeds in external browser</a>
- Fix app crash on android 8

0.9.9.12 (Google Play)
---------------------
- Several bug fixes
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/602">#602 crash when trying to open settings</a>

0.9.9.11 (Google Play)
---------------------
- Fix app crashes on Android 8+
- Fix - <a href="https://github.com/owncloud/News-Android-App/issues/571">#571 Move updates/changes to a separate CHANGES/CHANGELOG file</a>

0.9.9.10 (Google Play)
---------------------
- Several bug fixes
- Add support for cardview
- Optimization - <a href="https://github.com/owncloud/News-Android-App/issues/590">#590 Improve "mark as read while scrolling" feature</a>
- Optimization - <a href="https://github.com/owncloud/News-Android-App/issues/591">#591 Load links of feeds in external browser</a>

0.9.9.9 (Google Play)
---------------------
- Fix several app crashes
- Fix several widget issues
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/583">#583 App crashes on Android 8</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/579">#579 App crash due to invalid drawable tag vector</a>
- Optimization - <a href="https://github.com/owncloud/News-Android-App/issues/575">#575 Widget unusable on dark background</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/587">#587 App crashes</a>

0.9.9.8 (Google Play)
---------------------
- Fix several app crashes
- Use flavors (for proprietary newsApi calls)

0.9.9.7 (Google Play)
---------------------
- Fix several app crashes

0.9.9.6 (Google Play)
---------------------
- Rewrite of sync backend (use Retrofit, Dagger, OkHttp)
- Fix app crash (when using self signed ssl certificates)
- Several other fixes and improvements

0.9.9.5 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/559">#559 Sync is slow</a>

0.9.9.4 (Google Play)
---------------------
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/549">#549 Native YouTube video support</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/497">#497 Starts playing podcast when headphones are removed</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/546">#546 Share button has wrong color</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/540">#540 Dialog disappears on device rotation</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/532">#532 Graphical bug in landscape mode 10.1"</a>
- Optimization - <a href="https://github.com/owncloud/News-Android-App/issues/538">#538 Display total number of new items instead of last fetched in the notification</a>
- Optimization - <a href="https://github.com/owncloud/News-Android-App/issues/537">#537 display news title instead of "unread articles"</a>
- UI-Update - <a href="https://github.com/owncloud/News-Android-App/pull/542">#542 Nextcloud Theme - Thank you @stefan-niedermann</a>

0.9.9.3 (Google Play)
---------------------
- Critical bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/539">#539 Can not sync with Nextcloud 11 beta 1</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/511">#511 Prevent preload of videos</a>

0.9.9.2 (Google Play)
---------------------
- Partial bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/532">#532 Graphical bug in landscape mode 10.1"</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/530">#530 App crashes when trying to launch "Settings"</a>

0.9.9.1 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/531">#531 Design issues with longclick-dialogs</a>

0.9.9.0 (Google Play)
---------------------
- Improvement - Better error handling if API returns wrong version code
- Feature - Add Splash Screen
- Several Bug fixes and improvements

0.9.8.7 (Google Play)
---------------------
- Fix app crash - <a href="https://github.com/owncloud/News-Android-App/issues/519">#519 New versions force quit on CM11</a>

0.9.8.6 (Google Play)
---------------------
- Fix app crash - <a href="https://github.com/owncloud/News-Android-App/issues/519">#519 New versions force quit on CM11</a>

0.9.8.5 (Google Play)
---------------------
- Critical bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/518">#518 Bug in 0.9.8.3: Using the app caused marking all articles as read and starred articles are lost</a>

0.9.8.4
---------------------
- Critical bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/518">#518 Bug in 0.9.8.3: Using the app caused marking all articles as read and starred articles are lost</a>

0.9.8.3
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/502">#502 App crash when scrolling on empty list</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/509">#509 Sharing links duplicates titles</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/493">#493 Server and Username disappears</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/498">#498 Server and Username disappears</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/515">#515 Increase the padding for article content</a>
- Feature - <a href="https://github.com/owncloud/News-Android-App/issues/513">#513 Deduplicate articles</a>
- Feature - add support for video/mp4 podcasts
- Several Bug fixes and improvements

0.9.8.2 (Google Play)
---------------------
- Critical bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/492">#492 App crashes on start</a>

0.9.8.1 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/487">#487 App crashes when entering "Settings" on Android 4.4.4</a>
- Security fix - <a href="https://github.com/owncloud/News-Android-App/issues/489">#489 rfc: disable password check</a>

0.9.8 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/435">#435 Audio podcasts: icon disappears in detailed view</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/396">#396 podcasts stop playing, maybe high memory usage</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/463">#463 "Download images" stops after a few images</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/480">#480 Show ALT text (and TITLE) in image long-click menu</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/481">#481 Error with special characters in the title of feed</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/479">#479 Add a button to share article</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/445">#445 Audio Podcast: Download progress</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/434">#434 Audio Podcast: use androids media control elements</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/436">#436 Audio podcast: highlight them in detailed view</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/485">#485 Rename to "ownCloud News"</a>
- Performance improvement
- Several Bug fixes and improvements

0.9.7.6 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/349">#349 Widget always empty</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/472">#472 Starring is broken (add swipe to star again)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/146">#146 add context menu on pressing long on an item</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/239">#239 Add support for OPML files import/export</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/343">#343 Mark as read only when scrolling past article</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/374">#374 unread badge - teslaunread-newsApi</a>
- Security improvement (Prevent XSS)

0.9.7.5 (Google Play)
---------------------
- Bug fix

0.9.7.4 (Google Play)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/474">#474 New Feature: Rename and remove feeds </a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/465">#465 Support for right-to-left languages</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/456">#456 Download-Directory-Chooser for images in webview</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/466">#466 Articles are displayed in desktop view</a>

0.9.7.3 (Google Play)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/431">#431 Avoid volume change at beginning and end of feed</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/430">#430 Switched collapse folder icons</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/438">#438 context menu "save image" in detail view</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/410">#410 Latest release on google play does not sync</a>

0.9.7.2 (Google Play)
---------------------
- Add profile picture support
- Bug fixes

0.9.7.1 (Google Play)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/359">#359 Feed view with full article content</a>
- UI-Tweaks - <a href="https://github.com/owncloud/News-Android-App/issues/377">#377 read and star slide</a>
- Add ShowcaseView

0.9.7 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/393">#393 Login button might get cropped / completely hidden</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/407">#407 Auto reload news after sync</a>
- Bug fixes

0.9.6.3 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/399">#399 Missing scroll indicator in article list</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/401">#401 "Open in browser" not using default browser</a>

0.9.6.2 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/394">#394 back button doesn't work correct</a>

0.9.6.1 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/381">#381 Back button doesn't work correct in articles</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/392">#392 Wrong article is shown</a>

0.9.6 (Google Play)
---------------------
- Performance improvements
- Bug fixes

0.9.5.4 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/388">#388 App crash when opening an article</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/386">#386 News always open in external browser</a>

0.9.5.3 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/383">#383 Back button doesn't close the app on tablets</a>

0.9.5.2 (Google Play)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/376">#376 Design improvements</a>

0.9.5.1 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/371">#371 App crash since 0.9.4 at startup</a>

0.9.5 (Google Play)
---------------------
- UI-Redesign (special thanks to Daniel Schaal)
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/367">#367 Widget non-functional, crashes frequently</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/366">#366 "Sync on startup" option does not sync on startup only</a>
- Bug fixes

0.9.4 (Google Play - Beta)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/363">#363 Add support for Chrome Custom Tabs</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/361">#361 Pause podcast when receiving call</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/pull/362">#362 Redesign of the login dialog (special thanks to Daniel Schaal)</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/360">#360 Fix app crash</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/364">#364 App crash on Android < 4.1</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/258">#258 login fails with long passwords</a>
- Bug fixes

0.9.3 (Google Play)
---------------------
- Several UI-Improvements (special thanks to Daniel Schaal)

0.9.2 (Google Play)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/350">#350 option to set lines-count of title</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/318">#318 Image in advanced News item</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/342">#342 Low contrast checkboxes in settings (pre Lollipop)</a>

0.9.1 (Google Play)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/343">#343 Mark as read only when scrolling past article</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/345">#345 Pause support for podcast streams</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/348">#348 Notification icon in Android 5.0 is just a white square</a>

0.9.0 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/339">#339 Does not remember position in article listing</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/338">#338 Allow App to be installed on SD-Card</a>

0.8.9.5 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/334">#334 Display error since 0.8.6 - white screen after swiping to next article</a>

0.8.8 (Google Play - Beta)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/329">#329 "Mark all as read" freezes UI for long lists.</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/333">#333 Crash when opening Settings on Android 2.3</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/332">#332 [0.8.7] Crash when opening article after mark newer item as read</a>

0.8.7 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/331">#331 Bug in 0.8.6: App crashs by opening an article in external browser</a>

0.8.6 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/303">#303 List Item opens wrong Article (off by one)</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/308">#308 Allow feeds being checked as "keep unread" instead of "read" when "mark as read while scrolling" feature is used</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/324">#324 when I read the last unread news the news are not marked as read</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/327">#327 Scrolling with volume keys produces sound...</a> (Thanks @cemrich)
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/321">#321 Disabled options menu item not greyed out in actionbar</a> (Thanks @cemrich)
- Bug fixes

0.8.5 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/311">#311 Android 5.0.2 performance</a>
- Bug fixes

0.8.4 (Google Play)
---------------------
- PLEASE NOTE: This update deletes all your un-synchronized changes. After updating you'll need to perform a manual sync.
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/288">#288 Text to Speech (TTS)</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/307">#307 App crash when favicon has a height or width of 0px</a>
- Improvement - Show dialog to share a link/open in browser on long clicking a link in the detail-view
- Improve performance

0.8.3 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/301">#301 App crashes while adding feed</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/296">#296 App crashes when cache is full</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/295">#295 Images included from relative URLs are not loaded</a>

0.8.2 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/292">#292 0.8.1: Can't save sync interval</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/282">#282 Launch by default: *rss.xml - subscribe</a>

0.8.1 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/291">#291 0.8.0: App crashes when adding new feed</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/290">#290 0.8.0: Three dot menu in light theme wrong colors (black font on dark gray background)</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/289">#289 0.8.0: Widget isn't working anymore</a>
- Bug fixes/Improvements

0.8.0 (Google Play)
---------------------
- Material Design
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/236">#236 Read items in Android News Client are not synced to server</a>
- Bug fixes/Improvements

0.7.7 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/278">#278 App broken on latest News release (4.0.1)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/277">#277 Blockquote not correctly rendered</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/272">#272 Too much loading since v0.7.x</a>
- Bug fixes/Improvements

0.7.6 (Google Play)
---------------------
- Bug fixes

0.7.5 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/269">#269 App won't start</a>

0.7.4 (Google Play)
---------------------
- Update podcast feature
- Fix podcast video view position
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/256">#256 3.001: Expected BEGIN_ARRAY but was Number at line 1 column 19</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/262">#262 Deleting a feed on the server does not delete it on the client</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/257">#257 Share "Title - url" via twitter</a>
- Lot of bug fixes

0.7.3 (Google Play - Beta)
---------------------
- Update podcast feature (Add option to download podcast)

0.7.2 (Google Play - Beta)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/252">#252 "Open in Browser" should open current page.</a>
- New feature - <a href="https://github.com/owncloud/News-Android-App/issues/182">#182 »Read« checkbox in widget</a>
- Move "Sync Settings" option from Actionbar to Settings
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/212">#212 sort order of starred items</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/124">#124 Add download image options: Over WiFi only, Over WiFi and Mobil or ask when not connected to WiFi</a>
- Bug fixes
- Improve podcast layout

0.7.1 (Google Play)
---------------------
- Layout improvements
- Performance improvements
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/244">#244 app crashs if screen rotate</a>

0.7.0 (Google Play - Beta)
---------------------
- Layout improvements
- Bug fixes

0.6.9.9 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/245">#245 clicking on feeds under starred items gives weird result</a>
- Lot of bug fixes

0.6.9.8 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/243">#243 Readed items are not synced to owncloud</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/242">#242 Starred items aren't counted</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/241">#241 Feeds without unread items are shown</a>

0.6.9.7 (Google Play - Beta)
---------------------
- Rewrite backend - **IMPORTANT** All your data will be deleted. You'll have to make a full-sync after the update.
- Lot of bug fixes/improvements
- Performance improvements
- Add sorting podcasts by pub-date (descending)
- Add showcase view (API 11+)

0.6.9.6 (Google Play)
---------------------
- Fix app crash on devices with Android 2.2 - 2.3.*
- Small layout improvements (podcast view)
- Automatically restart app after podcast view has been enabled/disabled (or app theme changed)
- Start podcasts from the item detail view

0.6.9.5 (Google Play - Beta)
---------------------
- Add option to delete downloaded podcasts
- Bug fixes

0.6.9.4 (Google Play - Beta)
---------------------
- Add Podcast download support
- Add Video Podcast Support
- Youtube playlists are supported <a href="http://elliottbledsoe.com/brain-drain/how-to/rss-subscribe-to-youtube-playlist/">(Subscribe to a YouTube playlist using RSS)</a>
- Fix app crash
- Other fixes and improvements

0.6.9.3 (Google Play - Beta)
---------------------
- Accept ogg podcasts
- Improve layout of podcast player

0.6.9.2 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/234">#234 Favorite items don't count in total item count</a>
- Accept mpeg podcasts (only mp3)

0.6.9.1 (Google Play - Beta)
---------------------
- Add notifications for Podcasts
- Fix app crash (tablets)
- Add option to disable podcast support
- Add podcast view to item detail view
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/231">#231 App 0.6.7 crashs on start or after closing</a>

0.6.9 (Google Play - Beta)
---------------------
- Add Podcast support (early preview)
- Bug fixes

0.6.8 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/232">#232 Sync of already read items creates duplicate items</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/230">#230 Leaving space after ownCloud address in the Login dialog produces an error</a>

0.6.7 (Google Play - Beta)
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/226">#226 Poor sync performance under high count of unread articles</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/227">#227 Images appears in android gallery apps</a>

0.6.6 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/223">#223 All unread article counts are 0</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/220">#220 Wrong display of unread items</a>

0.6.5 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/223">#223 All unread article counts are 0</a>

0.6.4 (Google Play - Beta)
---------------------
- Improvement - Improved feed list scroll performance
- Improvement - Fixed that the list was blocked while updating the unread count

0.6.3 (Google Play - Beta)
---------------------
- Feature - Import Accounts from other ownCloud Apps

0.6.2 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/219">#219 No feed icons in list overview (0.6.1)</a>

0.6.1 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/216">#216 Bug in list overview in 0.6.0</a>

0.6.0 (Google Play - Beta)
---------------------
- Performance improvements
- Layout improvement
- Fix critical app crash when leaving the add new activity
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/199">#199 Change App-Logo/Icon</a>
- Improvement (better performance now) - <a href="https://github.com/owncloud/News-Android-App/issues/154">#154 Scrolling feed list is slow</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/215">#215 Adjust Colors of light and dark view to the web-interface</a>

0.5.9 (Google Play - Beta)
---------------------
- Extreme performance improvements
- Several bug fixes
- Layout improvement
- New feature - <a href="https://github.com/owncloud/News-Android-App/issues/35">#35 Subscribe to feed with app</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/208">#208 Summary: gray font on black background</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/154">#154 Scrolling feed list is slow</a>

0.5.8 (Google Play)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/214">#214 Scrolling within article causes unwanted tap on links</a>

0.5.7 (Google Play - Beta)
---------------------
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/213">#213 When using the dark theme websites with no background color are unreadable</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/211">#211 Links within articles</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/198">#198 enable auto sync configuration</a>

0.5.6
---------------------
- Fixed flickering of the screen when changing Feeds (in dark Theme)
- New Pull-To-Refresh Style
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/200">#200 Clicking article in widget makes app crash</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/196">#196 Stutter with "mark as read while scrolling" turned on</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/189">#189 Read mouse-over</a>

0.5.5
---------------------
- Improve Changelog View
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/186">#186 Missing "clear cache" in the settings (on Tablets)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/189">#189 Read mouse-over</a>
- Improvement - Fix Layout problems in DetailView
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/195">#195 Mark as read when opened in browser</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/194">#194 favIcons and imgCache show up in Gallery</a>

0.5.4
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/184">#184 Option to disable notification</a>

0.5.3
---------------------
- Update star/checkbox icons for devices with lower screen size
- Update language support
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/176">#176 Open directly in Browser</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/179">#179 Widget items not clickable</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/183">#183 Widget items color stripe position</a>

0.5.2
---------------------
- Improvement - Notification when background sync is enabled and new items are received
- Improvement - Fix high CPU-Load in Detail-View
- Improvement - Speed up image caching

0.5.0
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/162">#162 New items available notification pops up when there really aren't</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/160">#160 Widget font size</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/161">#161 'Send via' should be removed from sharing </a>

0.4.11
---------------------
- Critical Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/158">#158 0.4.10 instantly crashes when opening</a>

0.4.10 (unpublished)
---------------------
- Improvement - New Changelog Design
- Improvement - AppRater Plugin added
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/155">#155 Feed view isn't refreshed on sync</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/153">#153 Sidebar should be darker</a>
- Bug fixes

0.4.9
---------------------
- Update German Language support
- Readded full support of Android 2.2+ (was broken since 0.4.4)
- Improvement - In Landscape Mode on Tablets (7inch+) the Feed/Folder pane is always visible.
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/77">#77 There should be icons for folders and special categories</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/139">#139 Article list jumps after having article opened</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/137">#137 Back button shouldn't close app when app displays a specific feed or folder</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/151">#151 Reload slide pane when open event is triggered</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/136">#136 Fix that the translated app name is used as the folder name</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/134">#134 Sidebar - "Loading ..." font color should be brighter</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/133">#133 Refreshing after adding server data results in unauthorized</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/57">#57 Background synchronization</a>
- Bug fix - <a href="https://github.com/owncloud/News-Android-App/issues/152">#152 Changing sorting direction</a>

0.4.8
---------------------
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/140">#140 Open in browser and Share with controls always act on original article</a>
- Update Language support

0.4.7
---------------------
- fixed app crash when sync on startup is enabled
- faster favIcon pre-caching

0.4.6
---------------------
- Fixed app freeze when sync is finished
- Small improvements

0.4.5 (unpublished)
---------------------
- Fixed critical app crash after sync finished
- Improved security for self signed certificates. Special thanks to Dominik Schürmann (@dschuermann) <a href="https://github.com/owncloud/News-Android-App/issues/130">#130 (Implement MemorizingTrustManager to prevent MitM attacks)</a>
- Small bug fixes
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/128">#128 (»Mark all as read« is sometimes disabled)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/125">#125 (Feed list entries flash when unread count changes)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/129">#129 (Line height needs to be increased for better readability)</a>

0.4.4 (unpublished)
---------------------
- Fixed Security issue - thank you for the hint @davivel <a href="https://github.com/owncloud/News-Android-App/issues/47">#47 (can't connect to my ownCloud)</a>
- Fixed issue - <a href="https://github.com/owncloud/News-Android-App/issues/105">#105 (Androids back button does not hide empty feeds)</a>
- Fixed issue - <a href="https://github.com/owncloud/News-Android-App/issues/119">#119 ("mark all read" button has some bugs)</a>
- Fixed issue - <a href="https://github.com/owncloud/News-Android-App/issues/103">#103 (Favicons not shown)</a>
- Fixed issue - <a href="https://github.com/owncloud/News-Android-App/issues/112">#112 (Click on wrong item)</a>
- Fixed issue - <a href="https://github.com/owncloud/News-Android-App/issues/115">#115 (Database lock issue)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/117">#117 (Rearange the icons in the detail view)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/118">#118 (Add author to the new detail view header)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/120">#120 (Add coloured line to the feeds view in the average coulour of the favicon)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/107">#107 (Keep unread)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/60">#60 (Sync from unread items (or any feed view))</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/113">#113 (Long press on image to show title text)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/108">#108 (Mark as read once post is beyond the screen)</a>
- Improvement - <a href="https://github.com/owncloud/News-Android-App/issues/34">#34 (Widget)</a>
- Layout improvement - <a href="https://github.com/owncloud/News-Android-App/issues/106">#106 (Option to skip list view)</a>
- Layout improvement - <a href="https://github.com/owncloud/News-Android-App/issues/55">#55 (collapsible feeds list to maximize item space on phablets)</a>
- Layout improvement - <a href="https://github.com/owncloud/News-Android-App/issues/15">#15 (make column bar between folders and newslist movable)</a>
- Layout improvement - <a href="https://github.com/owncloud/News-Android-App/issues/116">#116 (Remove About/Changelog Menu Item from the List Detail View (Second view))</a>
- Improved german translation - <a href="https://github.com/owncloud/News-Android-App/issues/88">#88 (Bad german translation)</a>

0.4.3
---------------------
- Fixed issue <a href="https://github.com/owncloud/News-Android-App/issues/104">#104 (0.4.2 does not sync)</a>
- Fix issue that sometimes Exeptions are not shown
- Update F-Droid (merge dev with master)
- Update Language Support from master branch

0.4.2
---------------------
- critical bug fix that sync was broken <a href="https://github.com/owncloud/News-Android-App/issues/102">#102 (0.4.1 doesn't sync anymore)</a>

0.4.1
---------------------
- Font settings are also applied to the item detail view now
- Fix issue that the Button "Download more items" was not working

0.4.0
---------------------
- Fixed app crash when image cache is enabled and the dialog appear which asks the user if download via roaming is allowed.
- Fixed app crash reports.
- Fixed Issue <a href="https://github.com/owncloud/News-Android-App/issues/96">#96 (Can't sync feeds - using a bad URL)</a>
- Improved <a href="https://github.com/owncloud/News-Android-App/issues/95">#95 Make font/font size user selectable</a>
- Improved <a href="https://github.com/owncloud/News-Android-App/issues/86">#86 clearing the cache while having read items prevents them from being synced</a>
- Implemented Feature <a href="https://github.com/owncloud/News-Android-App/issues/99">#99 Option to change item order new-old/old-new</a>

0.3.9
---------------------
- Support for APIv1 and APIv2. (That means the app on Google Play will be updated, too!)
- Small fixes
- Improved memory usage while synchronizing
- Auto sync of item state every 5 minutes
- Changed font style to Roboto Light

0.3.8
---------------------
- Fixed Issue when trying to download more items in "all unread" and "starred items" view.
- Added option to set up the maximum cache size.
- Fixed app crash on tablets (could crash somtimes since v.0.3.7 when trying to download more items).
- Fixed Issue <a href="https://github.com/owncloud/News-Android-App/issues/78">#78 (The cache should be cleared in the background)</a>
- Improved feature <a href="https://github.com/owncloud/News-Android-App/issues/84">#84 (Buttons to toggle the folders are hard to hit and not descriptive)</a>
- Improved feature <a href="https://github.com/owncloud/News-Android-App/issues/76">#76 (There should me more spacing between feeds and folders)</a>
- Speed optimizations in the Folder/Feed Overview
- About/Changelog added

0.3.7
---------------------
- Option to mark articles as read while scrolling <a href="https://github.com/owncloud/News-Android-App/issues/14">#14 ("mark as read" on scroll)</a>
- Rich list theme layout (WebView) <a href="https://github.com/owncloud/News-Android-App/issues/6">#6</a>
- Fixed issue <a href="https://github.com/owncloud/News-Android-App/issues/46">#46 (Android 3.2.1 crash)</a>
- Fixed issue <a href="https://github.com/owncloud/News-Android-App/issues/68">#68 (Special folder "all unread articles" shows all articles)</a>
- Fixed issue <a href="https://github.com/owncloud/News-Android-App/issues/69">#69 (Crash when image cache enabled)</a>

0.3.6
---------------------
- Option to scroll through articles with Volume rockers <a href="https://github.com/owncloud/News-Android-App/issues/61">#61 (Use volume rocker to browse through articles)</a>
- Option to download old items for feed/folder <a href="https://github.com/owncloud/News-Android-App/issues/63">#63 (Allow dowloading old items)</a>
- Light Theme for item view <a href="https://github.com/owncloud/News-Android-App/issues/59">#59 (White Theme doesn't apply to articles)</a>
- Image offline caching function asks now if you want to download if you're not connected with wifi
- Item detail optimizations

0.3.5
---------------------
- Fixed issue <a href="https://github.com/owncloud/News-Android-App/issues/52">#52 (Folders visible multiple times)</a>
- Fixed issue <a href="https://github.com/owncloud/News-Android-App/issues/53">#53 (New items get added at the bottom)</a>
- Added default feed favIcon
- Theme is now also applied in the settings screen
- Implemented <a href="https://github.com/owncloud/News-Android-App/issues/56">#56 (Click on header to open article in browser)</a>

0.3.4
---------------------
- Offline reading (Only when you sync items the marked/starred/unread/unstarred items get synchronized. This save a lot of network traffic
- Offline image caching
- Login is getting verified when you click sign-in
- Strict-Hostname-Verification (Important Security Fix)
- Simple or extended list view
- Light or dark app Theme
- Implemented <a href="https://github.com/owncloud/News-Android-App/issues/29">#29 Mark all Article in one Column as readed</a>
- A lot of other new stuff and fixes

0.3.3
---------------------
- Dark/Light App Theme
- Feed List Design Simple/Extended
- many new languages have been added

0.3.2
---------------------
- Fixed app crash when leaving item detail view.

0.3.1
---------------------
- Polish language support added (thank you for translating Cyryl)
- App crash fixed when no item header text is available
- Go back in the item view if you press the home button
- Added Up Button in detail view as fix for GitHub Issue #13
- Other small fixes

0.3.0
---------------------
- Android 2.2+ Support added
- small bugfixes


================================================
FILE: COPYING-AGPL.md
================================================
                    GNU AFFERO GENERAL PUBLIC LICENSE
                       Version 3, 19 November 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

                            Preamble

  The GNU Affero General Public License is a free, copyleft license for
software and other kinds of works, specifically designed to ensure
cooperation with the community in the case of network server software.

  The licenses for most software and other practical works are designed
to take away your freedom to share and change the works.  By contrast,
our General Public Licenses are intended to guarantee your freedom to
share and change all versions of a program--to make sure it remains free
software for all its users.

  When we speak of free software, we are referring to freedom, not
price.  Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
them if you wish), that you receive source code or can get it if you
want it, that you can change the software or use pieces of it in new
free programs, and that you know you can do these things.

  Developers that use our General Public Licenses protect your rights
with two steps: (1) assert copyright on the software, and (2) offer
you this License which gives you legal permission to copy, distribute
and/or modify the software.

  A secondary benefit of defending all users' freedom is that
improvements made in alternate versions of the program, if they
receive widespread use, become available for other developers to
incorporate.  Many developers of free software are heartened and
encouraged by the resulting cooperation.  However, in the case of
software used on network servers, this result may fail to come about.
The GNU General Public License permits making a modified version and
letting the public access it on a server without ever releasing its
source code to the public.

  The GNU Affero General Public License is designed specifically to
ensure that, in such cases, the modified source code becomes available
to the community.  It requires the operator of a network server to
provide the source code of the modified version running there to the
users of that server.  Therefore, public use of a modified version, on
a publicly accessible server, gives the public access to the source
code of the modified version.

  An older license, called the Affero General Public License and
published by Affero, was designed to accomplish similar goals.  This is
a different license, not a version of the Affero GPL, but Affero has
released a new version of the Affero GPL which permits relicensing under
this license.

  The precise terms and conditions for copying, distribution and
modification follow.

                       TERMS AND CONDITIONS

  0. Definitions.

  "This License" refers to version 3 of the GNU Affero General Public License.

  "Copyright" also means copyright-like laws that apply to other kinds of
works, such as semiconductor masks.

  "The Program" refers to any copyrightable work licensed under this
License.  Each licensee is addressed as "you".  "Licensees" and
"recipients" may be individuals or organizations.

  To "modify" a work means to copy from or adapt all or part of the work
in a fashion requiring copyright permission, other than the making of an
exact copy.  The resulting work is called a "modified version" of the
earlier work or a work "based on" the earlier work.

  A "covered work" means either the unmodified Program or a work based
on the Program.

  To "propagate" a work means to do anything with it that, without
permission, would make you directly or secondarily liable for
infringement under applicable copyright law, except executing it on a
computer or modifying a private copy.  Propagation includes copying,
distribution (with or without modification), making available to the
public, and in some countries other activities as well.

  To "convey" a work means any kind of propagation that enables other
parties to make or receive copies.  Mere interaction with a user through
a computer network, with no transfer of a copy, is not conveying.

  An interactive user interface displays "Appropriate Legal Notices"
to the extent that it includes a convenient and prominently visible
feature that (1) displays an appropriate copyright notice, and (2)
tells the user that there is no warranty for the work (except to the
extent that warranties are provided), that licensees may convey the
work under this License, and how to view a copy of this License.  If
the interface presents a list of user commands or options, such as a
menu, a prominent item in the list meets this criterion.

  1. Source Code.

  The "source code" for a work means the preferred form of the work
for making modifications to it.  "Object code" means any non-source
form of a work.

  A "Standard Interface" means an interface that either is an official
standard defined by a recognized standards body, or, in the case of
interfaces specified for a particular programming language, one that
is widely used among developers working in that language.

  The "System Libraries" of an executable work include anything, other
than the work as a whole, that (a) is included in the normal form of
packaging a Major Component, but which is not part of that Major
Component, and (b) serves only to enable use of the work with that
Major Component, or to implement a Standard Interface for which an
implementation is available to the public in source code form.  A
"Major Component", in this context, means a major essential component
(kernel, window system, and so on) of the specific operating system
(if any) on which the executable work runs, or a compiler used to
produce the work, or an object code interpreter used to run it.

  The "Corresponding Source" for a work in object code form means all
the source code needed to generate, install, and (for an executable
work) run the object code and to modify the work, including scripts to
control those activities.  However, it does not include the work's
System Libraries, or general-purpose tools or generally available free
programs which are used unmodified in performing those activities but
which are not part of the work.  For example, Corresponding Source
includes interface definition files associated with source files for
the work, and the source code for shared libraries and dynamically
linked subprograms that the work is specifically designed to require,
such as by intimate data communication or control flow between those
subprograms and other parts of the work.

  The Corresponding Source need not include anything that users
can regenerate automatically from other parts of the Corresponding
Source.

  The Corresponding Source for a work in source code form is that
same work.

  2. Basic Permissions.

  All rights granted under this License are granted for the term of
copyright on the Program, and are irrevocable provided the stated
conditions are met.  This License explicitly affirms your unlimited
permission to run the unmodified Program.  The output from running a
covered work is covered by this License only if the output, given its
content, constitutes a covered work.  This License acknowledges your
rights of fair use or other equivalent, as provided by copyright law.

  You may make, run and propagate covered works that you do not
convey, without conditions so long as your license otherwise remains
in force.  You may convey covered works to others for the sole purpose
of having them make modifications exclusively for you, or provide you
with facilities for running those works, provided that you comply with
the terms of this License in conveying all material for which you do
not control copyright.  Those thus making or running the covered works
for you must do so exclusively on your behalf, under your direction
and control, on terms that prohibit them from making any copies of
your copyrighted material outside their relationship with you.

  Conveying under any other circumstances is permitted solely under
the conditions stated below.  Sublicensing is not allowed; section 10
makes it unnecessary.

  3. Protecting Users' Legal Rights From Anti-Circumvention Law.

  No covered work shall be deemed part of an effective technological
measure under any applicable law fulfilling obligations under article
11 of the WIPO copyright treaty adopted on 20 December 1996, or
similar laws prohibiting or restricting circumvention of such
measures.

  When you convey a covered work, you waive any legal power to forbid
circumvention of technological measures to the extent such circumvention
is effected by exercising rights under this License with respect to
the covered work, and you disclaim any intention to limit operation or
modification of the work as a means of enforcing, against the work's
users, your or third parties' legal rights to forbid circumvention of
technological measures.

  4. Conveying Verbatim Copies.

  You may convey verbatim copies of the Program's source code as you
receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice;
keep intact all notices stating that this License and any
non-permissive terms added in accord with section 7 apply to the code;
keep intact all notices of the absence of any warranty; and give all
recipients a copy of this License along with the Program.

  You may charge any price or no price for each copy that you convey,
and you may offer support or warranty protection for a fee.

  5. Conveying Modified Source Versions.

  You may convey a work based on the Program, or the modifications to
produce it from the Program, in the form of source code under the
terms of section 4, provided that you also meet all of these conditions:

    a) The work must carry prominent notices stating that you modified
    it, and giving a relevant date.

    b) The work must carry prominent notices stating that it is
    released under this License and any conditions added under section
    7.  This requirement modifies the requirement in section 4 to
    "keep intact all notices".

    c) You must license the entire work, as a whole, under this
    License to anyone who comes into possession of a copy.  This
    License will therefore apply, along with any applicable section 7
    additional terms, to the whole of the work, and all its parts,
    regardless of how they are packaged.  This License gives no
    permission to license the work in any other way, but it does not
    invalidate such permission if you have separately received it.

    d) If the work has interactive user interfaces, each must display
    Appropriate Legal Notices; however, if the Program has interactive
    interfaces that do not display Appropriate Legal Notices, your
    work need not make them do so.

  A compilation of a covered work with other separate and independent
works, which are not by their nature extensions of the covered work,
and which are not combined with it such as to form a larger program,
in or on a volume of a storage or distribution medium, is called an
"aggregate" if the compilation and its resulting copyright are not
used to limit the access or legal rights of the compilation's users
beyond what the individual works permit.  Inclusion of a covered work
in an aggregate does not cause this License to apply to the other
parts of the aggregate.

  6. Conveying Non-Source Forms.

  You may convey a covered work in object code form under the terms
of sections 4 and 5, provided that you also convey the
machine-readable Corresponding Source under the terms of this License,
in one of these ways:

    a) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by the
    Corresponding Source fixed on a durable physical medium
    customarily used for software interchange.

    b) Convey the object code in, or embodied in, a physical product
    (including a physical distribution medium), accompanied by a
    written offer, valid for at least three years and valid for as
    long as you offer spare parts or customer support for that product
    model, to give anyone who possesses the object code either (1) a
    copy of the Corresponding Source for all the software in the
    product that is covered by this License, on a durable physical
    medium customarily used for software interchange, for a price no
    more than your reasonable cost of physically performing this
    conveying of source, or (2) access to copy the
    Corresponding Source from a network server at no charge.

    c) Convey individual copies of the object code with a copy of the
    written offer to provide the Corresponding Source.  This
    alternative is allowed only occasionally and noncommercially, and
    only if you received the object code with such an offer, in accord
    with subsection 6b.

    d) Convey the object code by offering access from a designated
    place (gratis or for a charge), and offer equivalent access to the
    Corresponding Source in the same way through the same place at no
    further charge.  You need not require recipients to copy the
    Corresponding Source along with the object code.  If the place to
    copy the object code is a network server, the Corresponding Source
    may be on a different server (operated by you or a third party)
    that supports equivalent copying facilities, provided you maintain
    clear directions next to the object code saying where to find the
    Corresponding Source.  Regardless of what server hosts the
    Corresponding Source, you remain obligated to ensure that it is
    available for as long as needed to satisfy these requirements.

    e) Convey the object code using peer-to-peer transmission, provided
    you inform other peers where the object code and Corresponding
    Source of the work are being offered to the general public at no
    charge under subsection 6d.

  A separable portion of the object code, whose source code is excluded
from the Corresponding Source as a System Library, need not be
included in conveying the object code work.

  A "User Product" is either (1) a "consumer product", which means any
tangible personal property which is normally used for personal, family,
or household purposes, or (2) anything designed or sold for incorporation
into a dwelling.  In determining whether a product is a consumer product,
doubtful cases shall be resolved in favor of coverage.  For a particular
product received by a particular user, "normally used" refers to a
typical or common use of that class of product, regardless of the status
of the particular user or of the way in which the particular user
actually uses, or expects or is expected to use, the product.  A product
is a consumer product regardless of whether the product has substantial
commercial, industrial or non-consumer uses, unless such uses represent
the only significant mode of use of the product.

  "Installation Information" for a User Product means any methods,
procedures, authorization keys, or other information required to install
and execute modified versions of a covered work in that User Product from
a modified version of its Corresponding Source.  The information must
suffice to ensure that the continued functioning of the modified object
code is in no case prevented or interfered with solely because
modification has been made.

  If you convey an object code work under this section in, or with, or
specifically for use in, a User Product, and the conveying occurs as
part of a transaction in which the right of possession and use of the
User Product is transferred to the recipient in perpetuity or for a
fixed term (regardless of how the transaction is characterized), the
Corresponding Source conveyed under this section must be accompanied
by the Installation Information.  But this requirement does not apply
if neither you nor any third party retains the ability to install
modified object code on the User Product (for example, the work has
been installed in ROM).

  The requirement to provide Installation Information does not include a
requirement to continue to provide support service, warranty, or updates
for a work that has been modified or installed by the recipient, or for
the User Product in which it has been modified or installed.  Access to a
network may be denied when the modification itself materially and
adversely affects the operation of the network or violates the rules and
protocols for communication across the network.

  Corresponding Source conveyed, and Installation Information provided,
in accord with this section must be in a format that is publicly
documented (and with an implementation available to the public in
source code form), and must require no special password or key for
unpacking, reading or copying.

  7. Additional Terms.

  "Additional permissions" are terms that supplement the terms of this
License by making exceptions from one or more of its conditions.
Additional permissions that are applicable to the entire Program shall
be treated as though they were included in this License, to the extent
that they are valid under applicable law.  If additional permissions
apply only to part of the Program, that part may be used separately
under those permissions, but the entire Program remains governed by
this License without regard to the additional permissions.

  When you convey a copy of a covered work, you may at your option
remove any additional permissions from that copy, or from any part of
it.  (Additional permissions may be written to require their own
removal in certain cases when you modify the work.)  You may place
additional permissions on material, added by you to a covered work,
for which you have or can give appropriate copyright permission.

  Notwithstanding any other provision of this License, for material you
add to a covered work, you may (if authorized by the copyright holders of
that material) supplement the terms of this License with terms:

    a) Disclaiming warranty or limiting liability differently from the
    terms of sections 15 and 16 of this License; or

    b) Requiring preservation of specified reasonable legal notices or
    author attributions in that material or in the Appropriate Legal
    Notices displayed by works containing it; or

    c) Prohibiting misrepresentation of the origin of that material, or
    requiring that modified versions of such material be marked in
    reasonable ways as different from the original version; or

    d) Limiting the use for publicity purposes of names of licensors or
    authors of the material; or

    e) Declining to grant rights under trademark law for use of some
    trade names, trademarks, or service marks; or

    f) Requiring indemnification of licensors and authors of that
    material by anyone who conveys the material (or modified versions of
    it) with contractual assumptions of liability to the recipient, for
    any liability that these contractual assumptions directly impose on
    those licensors and authors.

  All other non-permissive additional terms are considered "further
restrictions" within the meaning of section 10.  If the Program as you
received it, or any part of it, contains a notice stating that it is
governed by this License along with a term that is a further
restriction, you may remove that term.  If a license document contains
a further restriction but permits relicensing or conveying under this
License, you may add to a covered work material governed by the terms
of that license document, provided that the further restriction does
not survive such relicensing or conveying.

  If you add terms to a covered work in accord with this section, you
must place, in the relevant source files, a statement of the
additional terms that apply to those files, or a notice indicating
where to find the applicable terms.

  Additional terms, permissive or non-permissive, may be stated in the
form of a separately written license, or stated as exceptions;
the above requirements apply either way.

  8. Termination.

  You may not propagate or modify a covered work except as expressly
provided under this License.  Any attempt otherwise to propagate or
modify it is void, and will automatically terminate your rights under
this License (including any patent licenses granted under the third
paragraph of section 11).

  However, if you cease all violation of this License, then your
license from a particular copyright holder is reinstated (a)
provisionally, unless and until the copyright holder explicitly and
finally terminates your license, and (b) permanently, if the copyright
holder fails to notify you of the violation by some reasonable means
prior to 60 days after the cessation.

  Moreover, your license from a particular copyright holder is
reinstated permanently if the copyright holder notifies you of the
violation by some reasonable means, this is the first time you have
received notice of violation of this License (for any work) from that
copyright holder, and you cure the violation prior to 30 days after
your receipt of the notice.

  Termination of your rights under this section does not terminate the
licenses of parties who have received copies or rights from you under
this License.  If your rights have been terminated and not permanently
reinstated, you do not qualify to receive new licenses for the same
material under section 10.

  9. Acceptance Not Required for Having Copies.

  You are not required to accept this License in order to receive or
run a copy of the Program.  Ancillary propagation of a covered work
occurring solely as a consequence of using peer-to-peer transmission
to receive a copy likewise does not require acceptance.  However,
nothing other than this License grants you permission to propagate or
modify any covered work.  These actions infringe copyright if you do
not accept this License.  Therefore, by modifying or propagating a
covered work, you indicate your acceptance of this License to do so.

  10. Automatic Licensing of Downstream Recipients.

  Each time you convey a covered work, the recipient automatically
receives a license from the original licensors, to run, modify and
propagate that work, subject to this License.  You are not responsible
for enforcing compliance by third parties with this License.

  An "entity transaction" is a transaction transferring control of an
organization, or substantially all assets of one, or subdividing an
organization, or merging organizations.  If propagation of a covered
work results from an entity transaction, each party to that
transaction who receives a copy of the work also receives whatever
licenses to the work the party's predecessor in interest had or could
give under the previous paragraph, plus a right to possession of the
Corresponding Source of the work from the predecessor in interest, if
the predecessor has it or can get it with reasonable efforts.

  You may not impose any further restrictions on the exercise of the
rights granted or affirmed under this License.  For example, you may
not impose a license fee, royalty, or other charge for exercise of
rights granted under this License, and you may not initiate litigation
(including a cross-claim or counterclaim in a lawsuit) alleging that
any patent claim is infringed by making, using, selling, offering for
sale, or importing the Program or any portion of it.

  11. Patents.

  A "contributor" is a copyright holder who authorizes use under this
License of the Program or a work on which the Program is based.  The
work thus licensed is called the contributor's "contributor version".

  A contributor's "essential patent claims" are all patent claims
owned or controlled by the contributor, whether already acquired or
hereafter acquired, that would be infringed by some manner, permitted
by this License, of making, using, or selling its contributor version,
but do not include claims that would be infringed only as a
consequence of further modification of the contributor version.  For
purposes of this definition, "control" includes the right to grant
patent sublicenses in a manner consistent with the requirements of
this License.

  Each contributor grants you a non-exclusive, worldwide, royalty-free
patent license under the contributor's essential patent claims, to
make, use, sell, offer for sale, import and otherwise run, modify and
propagate the contents of its contributor version.

  In the following three paragraphs, a "patent license" is any express
agreement or commitment, however denominated, not to enforce a patent
(such as an express permission to practice a patent or covenant not to
sue for patent infringement).  To "grant" such a patent license to a
party means to make such an agreement or commitment not to enforce a
patent against the party.

  If you convey a covered work, knowingly relying on a patent license,
and the Corresponding Source of the work is not available for anyone
to copy, free of charge and under the terms of this License, through a
publicly available network server or other readily accessible means,
then you must either (1) cause the Corresponding Source to be so
available, or (2) arrange to deprive yourself of the benefit of the
patent license for this particular work, or (3) arrange, in a manner
consistent with the requirements of this License, to extend the patent
license to downstream recipients.  "Knowingly relying" means you have
actual knowledge that, but for the patent license, your conveying the
covered work in a country, or your recipient's use of the covered work
in a country, would infringe one or more identifiable patents in that
country that you have reason to believe are valid.

  If, pursuant to or in connection with a single transaction or
arrangement, you convey, or propagate by procuring conveyance of, a
covered work, and grant a patent license to some of the parties
receiving the covered work authorizing them to use, propagate, modify
or convey a specific copy of the covered work, then the patent license
you grant is automatically extended to all recipients of the covered
work and works based on it.

  A patent license is "discriminatory" if it does not include within
the scope of its coverage, prohibits the exercise of, or is
conditioned on the non-exercise of one or more of the rights that are
specifically granted under this License.  You may not convey a covered
work if you are a party to an arrangement with a third party that is
in the business of distributing software, under which you make payment
to the third party based on the extent of your activity of conveying
the work, and under which the third party grants, to any of the
parties who would receive the covered work from you, a discriminatory
patent license (a) in connection with copies of the covered work
conveyed by you (or copies made from those copies), or (b) primarily
for and in connection with specific products or compilations that
contain the covered work, unless you entered into that arrangement,
or that patent license was granted, prior to 28 March 2007.

  Nothing in this License shall be construed as excluding or limiting
any implied license or other defenses to infringement that may
otherwise be available to you under applicable patent law.

  12. No Surrender of Others' Freedom.

  If conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License.  If you cannot convey a
covered work so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you may
not convey it at all.  For example, if you agree to terms that obligate you
to collect a royalty for further conveying from those to whom you convey
the Program, the only way you could satisfy both those terms and this
License would be to refrain entirely from conveying the Program.

  13. Remote Network Interaction; Use with the GNU General Public License.

  Notwithstanding any other provision of this License, if you modify the
Program, your modified version must prominently offer all users
interacting with it remotely through a computer network (if your version
supports such interaction) an opportunity to receive the Corresponding
Source of your version by providing access to the Corresponding Source
from a network server at no charge, through some standard or customary
means of facilitating copying of software.  This Corresponding Source
shall include the Corresponding Source for any work covered by version 3
of the GNU General Public License that is incorporated pursuant to the
following paragraph.

  Notwithstanding any other provision of this License, you have
permission to link or combine any covered work with a work licensed
under version 3 of the GNU General Public License into a single
combined work, and to convey the resulting work.  The terms of this
License will continue to apply to the part which is the covered work,
but the work with which it is combined will remain governed by version
3 of the GNU General Public License.

  14. Revised Versions of this License.

  The Free Software Foundation may publish revised and/or new versions of
the GNU Affero General Public License from time to time.  Such new versions
will be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.

  Each version is given a distinguishing version number.  If the
Program specifies that a certain numbered version of the GNU Affero General
Public License "or any later version" applies to it, you have the
option of following the terms and conditions either of that numbered
version or of any later version published by the Free Software
Foundation.  If the Program does not specify a version number of the
GNU Affero General Public License, you may choose any version ever published
by the Free Software Foundation.

  If the Program specifies that a proxy can decide which future
versions of the GNU Affero General Public License can be used, that proxy's
public statement of acceptance of a version permanently authorizes you
to choose that version for the Program.

  Later license versions may give you additional or different
permissions.  However, no additional obligations are imposed on any
author or copyright holder as a result of your choosing to follow a
later version.

  15. Disclaimer of Warranty.

  THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
APPLICABLE LAW.  EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
IS WITH YOU.  SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

  16. Limitation of Liability.

  IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
SUCH DAMAGES.

  17. Interpretation of Sections 15 and 16.

  If the disclaimer of warranty and limitation of liability provided
above cannot be given local legal effect according to their terms,
reviewing courts shall apply local law that most closely approximates
an absolute waiver of all civil liability in connection with the
Program, unless a warranty or assumption of liability accompanies a
copy of the Program in return for a fee.

                     END OF TERMS AND CONDITIONS

            How to Apply These Terms to Your New Programs

  If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.

  To do so, attach the following notices to the program.  It is safest
to attach them to the start of each source file to most effectively
state the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.

    <one line to give the program's name and a brief idea of what it does.>
    Copyright (C) <year>  <name of author>

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.

Also add information on how to contact you by electronic and paper mail.

  If your software can interact with users remotely through a computer
network, you should also make sure that it provides a way for users to
get its source.  For example, if your program is a web application, its
interface could display a "Source" link that leads users to an archive
of the code.  There are many ways you could offer source, and different
solutions will be better for different programs; see section 13 for the
specific requirements.

  You should also get your employer (if you work as a programmer) or school,
if any, to sign a "copyright disclaimer" for the program, if necessary.
For more information on this, and how to apply and follow the GNU AGPL, see
<http://www.gnu.org/licenses/>.

================================================
FILE: COPYING-README.md
================================================
Files in the ownCloud News Reader Android App Repo are licensed under the Affero General Public License version 3,
the text of which can be found in COPYING-AGPL, or any later version of the AGPL,
unless otherwise noted.

================================================
FILE: Gemfile
================================================
source "https://rubygems.org"

gem "fastlane"


================================================
FILE: NEWS-POLICY.md
================================================
# Nextcloud News Android [News Policy](https://support.google.com/googleplay/android-developer/answer/9935326)

The "Nextcloud News" Android-App (in the following referred to as "App") is RSS feed aggregator that allows users to subscribe to and read content from various external news sources and blogs. Please read the following disclaimer carefully as it contains important information about the use of our app.

**Nature of Content:** "Nextcloud News" is a platform for aggregating content from a variety of RSS feeds chosen by our users. We do not create, endorse, or control any of the content displayed in the app. The views and opinions expressed in the articles are those of the original publishers and authors and do not necessarily reflect the official policy or position of our App.

**Source Transparency:** For each article, we strive to provide clear information about the publisher and author. We believe in transparency and aim to guide users in recognizing the source of the information.

**Age of Content:** The content displayed in our app is in real-time from the chosen RSS feeds.
Consequently, we cannot guarantee that all content is current or less than three months old. Users
are encouraged to check the publication dates and validity of the information in the feeds they
subscribe to.

**Contact Information:** For any queries or concerns regarding the app, please refer to the '
Contact' section below.

**User Responsibility:** As users have the freedom to choose their own RSS feeds, we encourage
responsible usage. We advise our users to select reputable and reliable news sources. Our app is not
responsible for the accuracy or reliability of any information provided by external sources.

**Updates to Disclaimer:** This disclaimer is subject to changes and updates. We will notify users
of any significant changes through our app or website. Continued use of the app after such changes
will constitute acceptance of the new terms.

Thank you for choosing Nextcloud News for your news and information needs. We are dedicated to
providing a platform that respects the diversity of content and promotes informed reading.

## Contact

- **David Luhmer**
- **E-Mail:** david-dev(at)live.de
- **Phone:** +49 2222 9770191

================================================
FILE: News-Android-App/.gitignore
================================================
/build


================================================
FILE: News-Android-App/build.gradle
================================================
plugins {
    id 'com.android.application'
    id 'com.google.devtools.ksp'
    id 'io.gitlab.arturbosch.detekt' version "1.23.8"
    id "com.diffplug.spotless" version "8.2.1"
}

android {
    testOptions.unitTests.includeAndroidResources = true

    defaultConfig {
        compileSdk = Integer.parseInt(project.ANDROID_BUILD_SDK_VERSION)
        minSdkVersion Integer.parseInt(project.ANDROID_BUILD_MIN_SDK_VERSION)
        targetSdkVersion Integer.parseInt(project.ANDROID_BUILD_TARGET_SDK_VERSION)

        //testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
        testInstrumentationRunner "de.luhmer.owncloudnewsreader.CustomTestRunner"

        // The following argument makes the Android Test Orchestrator run its
        // "pm clear" command after each test invocation. This command ensures
        // that the app's state is completely cleared between tests.
        testInstrumentationRunnerArguments clearPackageData: 'true'

        vectorDrawables.useSupportLibrary = true

        versionCode 196
        versionName "0.9.9.95"
    }

    buildFeatures {
        buildConfig true
        viewBinding true
    }

    testOptions {
        execution 'ANDROIDX_TEST_ORCHESTRATOR'
        unitTests.returnDefaultValues = true
    }

    compileOptions {
        coreLibraryDesugaringEnabled true
        sourceCompatibility JavaVersion.VERSION_17
        targetCompatibility JavaVersion.VERSION_17
    }

    buildTypes {
        debug {
            shrinkResources false
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            testProguardFiles 'proguard-test.pro'
            pseudoLocalesEnabled true
        }
        release {
            shrinkResources true
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            testProguardFiles 'proguard-test.pro'
            //signingConfig signingConfigs.debug
        }
    }

    flavorDimensions = ["default"]

    productFlavors {
        // 100% Open-Source Edition
        oss {
            dimension "default"
        }
        // Used for continous integration, e.g. to test built .apk-files from pull requests
        dev {
            dimension "default"
            applicationIdSuffix ".dev"
        }
    }

    spotless {
        kotlin {
            target 'src/*/java/**/*.kt'
            ktlint()
        }
    }

    packagingOptions {
        resources {
            excludes += ['META-INF/LICENSE.txt', 'META-INF/NOTICE.txt', 'LICENSE.txt', 'META-INF/services/javax.annotation.processing.Processor']
        }
    }

    // Gradle automatically adds 'android.test.runner' as a dependency.
    useLibrary 'android.test.runner'
    useLibrary 'android.test.base'
    useLibrary 'android.test.mock'
    lint {
        abortOnError true
        checkReleaseBuilds false
        disable 'MissingTranslation', 'ExtraTranslation', 'MissingQuantity', 'InconsistentArrays', 'TypographyEllipsis'
        ignoreWarnings true
    }
    namespace 'de.luhmer.owncloudnewsreader'

}

repositories {
    google()
    mavenCentral()
    maven {
        url "https://jitpack.io"
        content {
            includeGroup "com.github.nextcloud"
        }
    }
    maven { url 'https://guardian.github.io/maven/repo-releases' }
    //needed for com.gu:option:1.3 in Android-DirectoryChooser
}

final DAGGER_VERSION = '2.59.2'
final GLIDE_VERSION = '5.0.5'
final ESPRESSO_VERSION = '3.7.0'
final OKHTTP_VERSION = '5.3.2'
final MOCKITO_VERSION = '5.21.0'
final RETROFIT_VERSION = '3.0.0'

dependencies {
    // core android studio module
    // compile project(':core')
    // You must install or update the Google Repository through the SDK manager to use this dependency.
    // The Google Repository (separate from the corresponding library) can be found in the Extras category.
    // implementation 'com.google.android.gms:play-services:4.2.42'
    // implementation project(path: ':MaterialShowcaseView:library', configuration: 'default')
    // implementation project(':Android-SingleSignOn:lib')
    implementation 'com.github.nextcloud:Android-SingleSignOn:f401ec4'
    // latest version which uses OKHTTP 5
    implementation "androidx.core:core:1.17.0"
    implementation 'androidx.annotation:annotation:1.9.1'
    implementation "androidx.appcompat:appcompat:1.7.1"
    implementation "androidx.preference:preference:1.2.1"
    implementation 'androidx.core:core-splashscreen:1.2.0'
    implementation "androidx.media:media:1.7.1"

    // https://mvnrepository.com/artifact/com.google.android.material/material
    implementation "com.google.android.material:material:1.13.0"
    implementation "androidx.palette:palette:1.0.0"
    implementation "androidx.recyclerview:recyclerview:1.4.0"
    implementation "androidx.browser:browser:1.9.0"
    implementation "androidx.cardview:cardview:1.0.0"
    implementation 'androidx.constraintlayout:constraintlayout:2.2.1'
    implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.2.0'
    implementation 'com.google.code.gson:gson:2.13.2'

    implementation "com.github.bumptech.glide:glide:${GLIDE_VERSION}"
    ksp "com.github.bumptech.glide:ksp:${GLIDE_VERSION}"
    debugImplementation "com.github.technoir42:glide-debug-indicator:0.9.1"
    implementation 'com.caverock:androidsvg-aar:1.4'

    implementation 'com.sothree.slidinguppanel:library:3.4.0'

    implementation 'org.greenrobot:eventbus:3.3.1'
    implementation 'de.greenrobot:greendao:2.1.0'
    implementation ('de.greenrobot:greendao-generator:2.1.0') {
        exclude group: 'org.freemarker'
    }

    // implementation 'org.freemarker:freemarker:2.3.23' // Required for DAO generation
    // implementation 'org.apache.commons:commons-lang3:3.4' // Required for DAO generation

    implementation 'com.github.gabrielemariotti.changeloglib:changelog:2.1.0'
    implementation 'org.jsoup:jsoup:1.22.1'
    implementation ('net.rdrei.android.dirchooser:library:3.2@aar') {
        exclude group: 'com.google.auto.value', module: 'auto-value'
        transitive = true
    }

    implementation "com.google.dagger:dagger:${DAGGER_VERSION}"
    ksp "com.google.dagger:dagger-compiler:${DAGGER_VERSION}"

    implementation 'io.reactivex.rxjava3:rxandroid:3.0.2'
    // Because RxAndroid releases are few and far between, it is recommended you also
    // explicitly depend on RxJava's latest version for bug fixes and new features.
    implementation 'io.reactivex.rxjava3:rxjava:3.1.12'
    implementation "com.squareup.retrofit2:adapter-rxjava3:$RETROFIT_VERSION"

    implementation "com.squareup.retrofit2:retrofit:$RETROFIT_VERSION"
    implementation "com.squareup.retrofit2:converter-gson:$RETROFIT_VERSION"
    implementation "com.squareup.okhttp3:okhttp:${OKHTTP_VERSION}"
    implementation "com.squareup.okhttp3:logging-interceptor:${OKHTTP_VERSION}"

    coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:2.1.5'

    testImplementation 'junit:junit:4.13.2'
    testImplementation("org.mockito:mockito-core:$MOCKITO_VERSION") {
        exclude group: 'org.hamcrest'
    }
    testImplementation 'com.google.dexmaker:dexmaker:1.2'
    testImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'
    testImplementation "com.squareup.okhttp3:mockwebserver:${OKHTTP_VERSION}"

    // https://mvnrepository.com/artifact/com.squareup.okhttp3/mockwebserver
    //androidTestImplementation "com.squareup.okhttp3:mockwebserver:${OKHTTP_VERSION}"


    androidTestImplementation 'tools.fastlane:screengrab:2.1.1'
    // Add falcon:2.2.0 explicitly, because screengrab:2.1.0 relies on falcon:2.1.1 which is not available on mavenCentral
    // See https://github.com/fastlane/fastlane/issues/12651#issuecomment-849653404
    androidTestImplementation 'com.jraska:falcon:2.2.0'
    //androidTestImplementation "org.mockito:mockito-core:MOCKITO_VERSION"
    androidTestImplementation "org.mockito:mockito-android:$MOCKITO_VERSION"


    //androidTestImplementation 'com.google.dexmaker:dexmaker:1.2'
    //androidTestImplementation 'com.google.dexmaker:dexmaker-mockito:1.2'

    testImplementation 'org.robolectric:robolectric:4.16.1'

    // Core library
    androidTestImplementation 'androidx.test:core:1.7.0'

    // AndroidJUnitRunner and JUnit Rules
    androidTestImplementation 'androidx.test:runner:1.7.0'
    androidTestImplementation 'androidx.test:rules:1.7.0'

    // Assertions
    androidTestImplementation 'androidx.test.ext:junit:1.3.0'
    androidTestImplementation 'androidx.test.ext:truth:1.7.0'
    androidTestImplementation 'com.google.truth:truth:1.4.5'

    // Espresso dependencies
    androidTestImplementation "androidx.test.espresso:espresso-core:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso:espresso-contrib:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso:espresso-intents:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso:espresso-accessibility:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso:espresso-web:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso.idling:idling-concurrent:$ESPRESSO_VERSION"

    // https://developer.android.com/training/testing/junit-runner.html#using-android-test-orchestrator
    androidTestUtil 'androidx.test:orchestrator:1.6.1'

    // The following Espresso dependency can be either "implementation"
    // or "androidTestImplementation", depending on whether you want the
    // dependency to appear on your APK's compile classpath or the test APK
    // classpath.
    //androidTestImplementation 'androidx.test.espresso:espresso-idling-resource:3.1.1'
}


================================================
FILE: News-Android-App/config/detekt/detekt.yml
================================================
build:
  maxIssues: 0
  weights:
  # complexity: 2
  # LongParameterList: 1
  # style: 1
  # comments: 1

processors:
  active: true
  exclude:
  # - 'FunctionCountProcessor'
  # - 'PropertyCountProcessor'
  # - 'ClassCountProcessor'
  # - 'PackageCountProcessor'
  # - 'KtFileCountProcessor'

console-reports:
  active: true
  exclude:
  #  - 'ProjectStatisticsReport'
  #  - 'ComplexityReport'
  #  - 'NotificationReport'
  #  - 'FindingsReport'
  #  - 'BuildFailureReport'

comments:
  active: true
  CommentOverPrivateFunction:
    active: false
  CommentOverPrivateProperty:
    active: false
  EndOfSentenceFormat:
    active: false
    endOfSentenceFormat: ([.?!][ \t\n\r\f<])|([.?!]$)
  UndocumentedPublicClass:
    active: false
    searchInNestedClass: true
    searchInInnerClass: true
    searchInInnerObject: true
    searchInInnerInterface: true
  UndocumentedPublicFunction:
    active: false

complexity:
  active: true
  ComplexCondition:
    active: true
    threshold: 4
  ComplexInterface:
    active: false
    threshold: 10
    includeStaticDeclarations: false
  ComplexMethod:
    active: true
    threshold: 10
    ignoreSingleWhenExpression: false
    ignoreSimpleWhenEntries: false
    excludes: ['**/androidTest/**']
  LabeledExpression:
    active: false
    ignoredLabels: ""
  LargeClass:
    active: true
    threshold: 600
  LongMethod:
    active: true
    threshold: 60
    excludes: ['**/androidTest/**']
  LongParameterList:
    active: true
    functionThreshold: 6
    constructorThreshold: 6
    ignoreDefaultParameters: false
  MethodOverloading:
    active: false
    threshold: 6
  NestedBlockDepth:
    active: true
    threshold: 4
  StringLiteralDuplication:
    active: false
    threshold: 3
    ignoreAnnotation: true
    excludeStringsWithLessThan5Characters: true
    ignoreStringsRegex: '$^'
  TooManyFunctions:
    active: true
    thresholdInFiles: 15
    thresholdInClasses: 15
    thresholdInInterfaces: 15
    thresholdInObjects: 15
    thresholdInEnums: 11
    ignoreDeprecated: true
    ignorePrivate: false
    ignoreOverridden: true

empty-blocks:
  active: true
  EmptyCatchBlock:
    active: true
    allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
  EmptyClassBlock:
    active: true
  EmptyDefaultConstructor:
    active: true
  EmptyDoWhileBlock:
    active: true
  EmptyElseBlock:
    active: true
  EmptyFinallyBlock:
    active: true
  EmptyForBlock:
    active: true
  EmptyFunctionBlock:
    active: true
    ignoreOverridden: false
  EmptyIfBlock:
    active: true
  EmptyInitBlock:
    active: true
  EmptyKtFile:
    active: true
  EmptySecondaryConstructor:
    active: true
  EmptyWhenBlock:
    active: true
  EmptyWhileBlock:
    active: true

exceptions:
  active: true
  ExceptionRaisedInUnexpectedLocation:
    active: false
    methodNames: 'toString,hashCode,equals,finalize'
  InstanceOfCheckForException:
    active: false
  NotImplementedDeclaration:
    active: false
  PrintStackTrace:
    active: false
  RethrowCaughtException:
    active: false
  ReturnFromFinally:
    active: false
  SwallowedException:
    active: false
    ignoredExceptionTypes: 'InterruptedException,NumberFormatException,ParseException,MalformedURLException'
  ThrowingExceptionFromFinally:
    active: false
  ThrowingExceptionInMain:
    active: false
  ThrowingExceptionsWithoutMessageOrCause:
    active: false
    exceptions: 'IllegalArgumentException,IllegalStateException,IOException'
  ThrowingNewInstanceOfSameException:
    active: false
  TooGenericExceptionCaught:
    active: true
    exceptionNames:
      - ArrayIndexOutOfBoundsException
      - Error
      - Exception
      - IllegalMonitorStateException
      - NullPointerException
      - IndexOutOfBoundsException
      - RuntimeException
      - Throwable
    allowedExceptionNameRegex: "^(_|(ignore|expected).*)"
  TooGenericExceptionThrown:
    active: true
    exceptionNames:
      - Error
      - Exception
      - Throwable
      - RuntimeException

naming:
  active: true
  ClassNaming:
    active: true
    classPattern: '[A-Z$][a-zA-Z0-9$]*'
  ConstructorParameterNaming:
    active: true
    parameterPattern: '[a-z][A-Za-z0-9]*'
    privateParameterPattern: '[a-z][A-Za-z0-9]*'
    excludeClassPattern: '$^'
  EnumNaming:
    active: true
    enumEntryPattern: '^[A-Z][_a-zA-Z0-9]*'
  ForbiddenClassName:
    active: false
    forbiddenName: ''
  FunctionMaxLength:
    active: false
    maximumFunctionNameLength: 30
  FunctionMinLength:
    active: false
    minimumFunctionNameLength: 3
  FunctionNaming:
    active: true
    functionPattern: '^([a-z$][a-zA-Z$0-9]*)|(`.*`)$'
    excludeClassPattern: '$^'
    ignoreOverridden: true
    excludes:
      - "**/*Test.kt"
      - "**/*IT.kt"
  FunctionParameterNaming:
    active: true
    parameterPattern: '[a-z][A-Za-z0-9]*'
    excludeClassPattern: '$^'
    ignoreOverridden: true
  MatchingDeclarationName:
    active: true
  MemberNameEqualsClassName:
    active: false
    ignoreOverridden: true
  ObjectPropertyNaming:
    active: true
    constantPattern: '[A-Za-z][_A-Za-z0-9]*'
    propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
    privatePropertyPattern: '(_)?[A-Za-z][_A-Za-z0-9]*'
  PackageNaming:
    active: true
    packagePattern: '^[a-z]+(\.[a-z][A-Za-z0-9]*)*$'
  TopLevelPropertyNaming:
    active: true
    constantPattern: '[A-Z][_A-Z0-9]*'
    propertyPattern: '[A-Za-z][_A-Za-z0-9]*'
    privatePropertyPattern: '(_)?[A-Za-z][A-Za-z0-9]*'
  VariableMaxLength:
    active: false
    maximumVariableNameLength: 64
  VariableMinLength:
    active: false
    minimumVariableNameLength: 1
  VariableNaming:
    active: true
    variablePattern: '[a-z][A-Za-z0-9]*'
    privateVariablePattern: '(_)?[a-z][A-Za-z0-9]*'
    excludeClassPattern: '$^'
    ignoreOverridden: true

performance:
  active: true
  ArrayPrimitive:
    active: false
  ForEachOnRange:
    active: true
  SpreadOperator:
    active: true
  UnnecessaryTemporaryInstantiation:
    active: true

potential-bugs:
  active: true
  DuplicateCaseInWhenExpression:
    active: true
  EqualsAlwaysReturnsTrueOrFalse:
    active: false
  EqualsWithHashCodeExist:
    active: true
  ExplicitGarbageCollectionCall:
    active: true
  InvalidRange:
    active: false
  IteratorHasNextCallsNextMethod:
    active: false
  IteratorNotThrowingNoSuchElementException:
    active: false
  LateinitUsage:
    active: false
    ignoreAnnotated: []
    ignoreOnClassesPattern: ""
  UnconditionalJumpStatementInLoop:
    active: false
  UnreachableCode:
    active: true
  UnsafeCallOnNullableType:
    active: false
  UnsafeCast:
    active: false
  UselessPostfixExpression:
    active: false
  WrongEqualsTypeParameter:
    active: false

style:
  active: true
  CollapsibleIfStatements:
    active: false
  DataClassContainsFunctions:
    active: false
    conversionFunctionPrefix: 'to'
  EqualsNullCall:
    active: false
  EqualsOnSignatureLine:
    active: false
  ExplicitItLambdaParameter:
    active: false
  ExpressionBodySyntax:
    active: false
    includeLineWrapping: false
  ForbiddenComment:
    active: true
    values: 'TODO:,FIXME:,STOPSHIP:'
  ForbiddenImport:
    active: false
    imports: ''
  ForbiddenVoid:
    active: false
  FunctionOnlyReturningConstant:
    active: false
    ignoreOverridableFunction: true
    excludedFunctions: 'describeContents'
  LoopWithTooManyJumpStatements:
    active: false
    maxJumpCount: 1
  MagicNumber:
    active: true
    ignoreNumbers: '-1,0,1,2'
    ignoreHashCodeFunction: true
    ignorePropertyDeclaration: false
    ignoreConstantDeclaration: true
    ignoreCompanionObjectPropertyDeclaration: true
    ignoreAnnotation: false
    ignoreNamedArgument: true
    ignoreEnums: false
    excludes:
      - "**/*Test.kt"
      - "**/*IT.kt"
  MandatoryBracesIfStatements:
    active: false
  MaxLineLength:
    active: true
    maxLineLength: 120
    excludePackageStatements: true
    excludeImportStatements: true
    excludeCommentStatements: false
  MayBeConst:
    active: false
  ModifierOrder:
    active: true
  NestedClassesVisibility:
    active: false
  NewLineAtEndOfFile:
    active: true
  NoTabs:
    active: false
  OptionalAbstractKeyword:
    active: true
  OptionalUnit:
    active: false
  OptionalWhenBraces:
    active: false
  PreferToOverPairSyntax:
    active: false
  ProtectedMemberInFinalClass:
    active: false
  RedundantVisibilityModifierRule:
    active: false
  ReturnCount:
    active: true
    max: 2
    excludedFunctions: "equals"
    excludeLabeled: false
    excludeReturnFromLambda: true
  SafeCast:
    active: true
  SerialVersionUIDInSerializableClass:
    active: false
  SpacingBetweenPackageAndImports:
    active: false
  ThrowsCount:
    active: true
    max: 2
  TrailingWhitespace:
    active: false
  UnderscoresInNumericLiterals:
    active: false
    acceptableLength: 5
  UnnecessaryAbstractClass:
    active: false
    ignoreAnnotated:
      - "dagger.Module"
  UnnecessaryApply:
    active: false
  UnnecessaryInheritance:
    active: false
  UnnecessaryLet:
    active: false
  UnnecessaryParentheses:
    active: false
  UntilInsteadOfRangeTo:
    active: false
  UnusedImports:
    active: false
  UnusedPrivateClass:
    active: false
  UnusedPrivateMember:
    active: false
    allowedNames: "(_|ignored|expected|serialVersionUID)"
  UseDataClass:
    active: false
    ignoreAnnotated: []
  UtilityClassWithPublicConstructor:
    active: false
  VarCouldBeVal:
    active: false
  WildcardImport:
    active: true
    excludeImports: 'java.util.*,kotlinx.android.synthetic.*'


================================================
FILE: News-Android-App/proguard-rules.pro
================================================
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /opt/android-studio/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the ProGuard
# include property in project.properties.
#
# For more details, see
#   http://developer.android.com/guide/developing/tools/proguard.html

# Add any project specific keep options here:

# 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 *;
#}

# Required for Test execution
-dontwarn org.xmlpull.v1.**
-dontwarn org.apache.tools.ant.**
-dontwarn java.beans.**
-dontwarn javax.naming.**
-dontwarn sun.misc.Unsafe


# Mockito
-dontwarn org.mockito.**


-keepnames class * implements java.io.Serializable

-keepclassmembers class * implements java.io.Serializable {
    static final long serialVersionUID;
    private static final java.io.ObjectStreamField[] serialPersistentFields;
    !static !transient <fields>;
    private void writeObject(java.io.ObjectOutputStream);
    private void readObject(java.io.ObjectInputStream);
    java.lang.Object writeReplace();
    java.lang.Object readResolve();
}


# AndroidSlidingUpPanel
# https://github.com/umano/AndroidSlidingUpPanel/issues/921
-dontwarn com.sothree.slidinguppanel.SlidingUpPanelLayout

# jsoup
-dontwarn com.google.re2j.*

# Other Libraries
-dontwarn org.apache.velocity.**
-dontwarn freemarker.**
-dontwarn com.google.auto.value.**
-dontwarn autovalue.shaded.**
#-keep class com.gu.option.Option
#-keep class com.gu.option.UnitFunction

# keep application classes used as database and network models
-keep class de.luhmer.owncloudnewsreader.database.model.** { *; }
-keep class de.luhmer.owncloudnewsreader.reader.nextcloud.ItemIds { *; }
-keep class de.luhmer.owncloudnewsreader.reader.nextcloud.ItemMap { *; }
-keep class de.luhmer.owncloudnewsreader.model.** { *; }
# keep the name of SyncItemStateService so SyncItemStateService.isMyServiceRunning works
-keepnames class de.luhmer.owncloudnewsreader.services.SyncItemStateService
# keep fields necessary for NewsReaderListActivity.adjustEdgeSizeOfDrawer and NewsReaderListActivity.getEdgeSizeOfDrawer to work
-keepclassmembers class androidx.drawerlayout.widget.DrawerLayout {
    private androidx.customview.widget.ViewDragHelper mLeftDragger;
}
-keepclassmembers class androidx.customview.widget.ViewDragHelper {
    private int mEdgeSize;
}

-printmapping out.map
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile

###############
# GreenDAO
-keep class de.greenrobot.** { *; }
-dontwarn de.greenrobot.daogenerator.DaoGenerator

-keepclassmembers class * extends de.greenrobot.dao.AbstractDao { *; }


###############
# Guava (official)
## Not yet defined: follow https://github.com/google/guava/issues/2117
# Guava (unofficial)
## https://github.com/google/guava/issues/2926#issuecomment-325455128
## https://stackoverflow.com/questions/9120338/proguard-configuration-for-guava-with-obfuscation-and-optimization
-dontwarn com.google.common.base.**
-dontwarn com.google.errorprone.annotations.**
-dontwarn com.google.j2objc.annotations.**
-dontwarn java.lang.ClassValue
-dontwarn org.codehaus.mojo.animal_sniffer.IgnoreJRERequirement
-dontwarn javax.annotation.**
-dontwarn javax.inject.**
-dontwarn sun.misc.Unsafe

# Added for guava 23.5-android
-dontwarn afu.org.checkerframework.**
-dontwarn org.checkerframework.**


# Required for unit tests

# https://stackoverflow.com/a/39777485
# Also, note that this rule should be added to the regular proguard file(the one of listed in proguardFiles) and not the test one(declared as testProguardFile)
# java.lang.NoSuchMethodError: No virtual method getParameter
-keepclasseswithmembers public class com.nextcloud.android.sso.aidl.NextcloudRequest { *; }
-keepclasseswithmembers public class com.nextcloud.android.sso.AccountImporter { *; }

# NewsReaderListActivityTests
-keepclasseswithmembers public class androidx.recyclerview.widget.RecyclerView { *; }


================================================
FILE: News-Android-App/proguard-test.pro
================================================
# proguard-test.pro:
-include proguard-rules.pro
-keepattributes SourceFile,LineNumberTable



-dontwarn androidx.test.espresso.**


###############
# Required for Mockito
-keep class retrofit2.NextcloudRetrofitApiBuilder { *; }
-keep class net.bytebuddy.* { *; }
-dontwarn net.bytebuddy.**

-keep class module-info
-keepattributes Module*
-dontwarn org.mockito.**


# Proguard rules that are applied to your test apk/code.
-ignorewarnings

-keepattributes *Annotation*

-dontnote junit.framework.**
-dontnote junit.runner.**

-dontwarn android.test.**
-dontwarn android.support.test.**
-dontwarn org.junit.**
-dontwarn org.hamcrest.**
-dontwarn com.squareup.javawriter.JavaWriter

-dontwarn androidx.concurrent.futures.AbstractResolvableFuture


#-dontwarn org.conscrypt.Conscrypt
#com.google.common.util.concurrent.ListenableFuture
#-keep interface okhttp3.internal.platform.ConscryptPlatform
#-keep class okhttp3.internal.platform.ConscryptPlatform

#-keep class org.conscrypt.Conscrypt { *; }
#-keep interface org.conscrypt.Conscrypt { *; }


================================================
FILE: News-Android-App/remove_invalid_languages.sh
================================================
git rm -r src/main/res/values-ach/
git rm -r src/main/res/values-ady/
git rm -r src/main/res/values-nds/
git rm -r src/main/res/values-nqo/
git rm -r src/main/res/values-tzm/


================================================
FILE: News-Android-App/src/androidTest/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools"
    xmlns:android="http://schemas.android.com/apk/res/android">

    <uses-sdk tools:overrideLibrary="android_libs.ub_uiautomator" />

    <application>
        <!-- You don't need to include android:required="false" if your app's minSdkVersion is 28 or higher. -->
        <uses-library
            android:name="android.test.runner"
            android:required="false" />
        <uses-library
            android:name="android.test.base"
            android:required="false" />
        <uses-library
            android:name="android.test.mock"
            android:required="false" />
    </application>
</manifest>

================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/CustomTestRunner.java
================================================
package de.luhmer.owncloudnewsreader;

import android.app.Application;
import android.content.Context;

import androidx.test.runner.AndroidJUnitRunner;

public class CustomTestRunner extends AndroidJUnitRunner {

    /*
    @Override
    public void onCreate(Bundle arguments) {
        // The workaround for Mockito issue #922
        // https://github.com/mockito/mockito/issues/922

        arguments.putString("notPackage", "net.bytebuddy");
        super.onCreate(arguments);
    }
    */

    public Application newApplication(ClassLoader cl, String className, Context context) throws IllegalAccessException, InstantiationException, ClassNotFoundException {
        return super.newApplication(cl, TestApplication.class.getName(), context);
    }
}





================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/TestApplication.java
================================================
package de.luhmer.owncloudnewsreader;

import de.luhmer.owncloudnewsreader.di.DaggerTestComponent;
import de.luhmer.owncloudnewsreader.di.TestApiModule;

public class TestApplication extends NewsReaderApplication {

    @Override
    public void initDaggerAppComponent() {
        // Dagger%COMPONENT_NAME%

        mAppComponent = DaggerTestComponent.builder()
                .apiModule(new TestApiModule(this))
                .build();

        // If a Dagger 2 component does not have any constructor arguments for any of its modules,
        // then we can use .create() as a shortcut instead:
        //mAppComponent = DaggerAppComponent.create();
    }

}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestApiModule.java
================================================
package de.luhmer.owncloudnewsreader.di;

import android.app.Application;
import android.content.Context;
import android.content.SharedPreferences;
import android.util.Log;

import androidx.test.InstrumentationRegistry;

import com.nextcloud.android.sso.AccountImporter;
import com.nextcloud.android.sso.model.SingleSignOnAccount;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;

import de.luhmer.owncloudnewsreader.NewsReaderListFragment;
import de.luhmer.owncloudnewsreader.SettingsActivity;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;
import de.luhmer.owncloudnewsreader.model.OcsUser;
import de.luhmer.owncloudnewsreader.ssl.MemorizingTrustManager;

public class TestApiModule extends ApiModule {

    private static final String TAG = TestApiModule.class.getCanonicalName();
    private final Application application;

    public static String DUMMY_ACCOUNT_AccountName = "test-account";
    public static String DUMMY_ACCOUNT_username = "david";
    public static String DUMMY_ACCOUNT_token = "abc";
    public static String DUMMY_ACCOUNT_server_url = "http://nextcloud.com/";

    public TestApiModule(Application application) {
        super(application);
        this.application = application;
    }

    @Override
    public SharedPreferences providesSharedPreferences() {
        // Create dummy account
        String prefKey = "PREF_ACCOUNT_STRING" + DUMMY_ACCOUNT_AccountName;
        SingleSignOnAccount ssoAccount = new SingleSignOnAccount(
                DUMMY_ACCOUNT_AccountName, DUMMY_ACCOUNT_username,
                DUMMY_ACCOUNT_token, DUMMY_ACCOUNT_server_url,
                "prod"
        );

        OcsUser userInfo = new OcsUser("1", DUMMY_ACCOUNT_username);

        //SharedPreferences sharedPrefs = new MockSharedPreference();
        SharedPreferences sharedPrefs = application.getSharedPreferences(providesSharedPreferencesFileName(), Context.MODE_PRIVATE);

        // Reset SharedPreferences to make tests reproducible
        sharedPrefs.edit().clear().commit();

        // Turn on Single-Sign-On
        sharedPrefs.edit().putBoolean(SettingsActivity.SW_USE_SINGLE_SIGN_ON, true).commit();

        // Set mock preferences for AccountImporter
        AccountImporter.setSharedPreferences(sharedPrefs);


        // Return mock login data when requesting the account
        try {
            sharedPrefs.edit().putString(prefKey, SingleSignOnAccount.toString(ssoAccount)).commit();
        } catch (IOException e) {
            throw new Error(e);
        }

        // For userinfo in main activity
        sharedPrefs.edit().putString(SettingsActivity.EDT_OWNCLOUDROOTPATH_STRING, DUMMY_ACCOUNT_server_url).commit();
        sharedPrefs.edit().putString(SettingsActivity.EDT_USERNAME_STRING, DUMMY_ACCOUNT_username).commit();
        sharedPrefs.edit().putString("PREF_CURRENT_ACCOUNT_STRING", DUMMY_ACCOUNT_AccountName).commit();
        try {
            sharedPrefs.edit().putString("USER_INFO", NewsReaderListFragment.toString(userInfo)).commit();
        } catch (IOException e) {
            throw new Error(e);
        }

        ThemeChooser.init(sharedPrefs);

        return sharedPrefs;
    }

   @Override
    public String providesSharedPreferencesFileName() {
        return application.getPackageName() + "_preferences_test";
    }

    @Override
    public String providesDatabaseFileName() {
        String filename = "OwncloudNewsReaderOrmTest.db";

        try {

            String dst = "/data/data/" + application.getApplicationContext().getPackageName() + "/databases/" + filename;
            File dstFile = new File(dst);
            dstFile.getParentFile().mkdirs();

            // https://stackoverflow.com/a/35690692
            copy(InstrumentationRegistry.getContext().getAssets().open("OwncloudNewsReaderOrm.db"), dstFile);
        } catch (IOException e) {
            Log.e(TAG, "Failed copying Test Database", e);
        }
        //return PreferenceManager.getDefaultSharedPreferencesName(mApplication);
        return filename;
    }

    @Override
    protected ApiProvider provideAPI(MemorizingTrustManager mtm, SharedPreferences sp) {
        ApiProvider apiProvider = new TestApiProvider(mtm, sp, application);
        return apiProvider;
    }



    public static void copy(InputStream in, File dst) throws IOException {
        try (OutputStream out = new FileOutputStream(dst)) {
            // Transfer bytes from in to out
            byte[] buf = new byte[1024];
            int len;
            while ((len = in.read(buf)) > 0) {
                out.write(buf, 0, len);
            }
        }
        in.close();

    }
}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestApiProvider.java
================================================
package de.luhmer.owncloudnewsreader.di;

import static org.mockito.ArgumentMatchers.any;
import static de.luhmer.owncloudnewsreader.di.TestApiModule.DUMMY_ACCOUNT_AccountName;
import static de.luhmer.owncloudnewsreader.di.TestApiModule.DUMMY_ACCOUNT_username;

import android.content.Context;
import android.content.SharedPreferences;
import android.os.Looper;
import android.os.NetworkOnMainThreadException;
import android.util.Log;

import com.nextcloud.android.sso.aidl.NextcloudRequest;
import com.nextcloud.android.sso.api.NetworkRequest;
import com.nextcloud.android.sso.api.NextcloudAPI;
import com.nextcloud.android.sso.api.Response;
import com.nextcloud.android.sso.exceptions.NextcloudHttpRequestFailedException;

import org.mockito.Mockito;

import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;

import de.luhmer.owncloudnewsreader.helper.GsonConfig;
import de.luhmer.owncloudnewsreader.reader.nextcloud.NewsAPI;
import de.luhmer.owncloudnewsreader.ssl.MemorizingTrustManager;
import retrofit2.NextcloudRetrofitApiBuilder;

public class TestApiProvider extends ApiProvider {

    private static final String TAG = TestApiProvider.class.getCanonicalName();

    public static final String NEW_FEED_SUCCESS  = "http://test.de/new";
    public static final String NEW_FEED_EXISTING = "http://test.de/existing";
    public static final String NEW_FEED_FAIL     = "http://test.de/fail";
    private static final String NEW_FEED_EXISTING_ERROR_MESSAGE = "{\"message\":\"Feed konnte nicht hinzugef\\u00fcgt werden:  Existiert bereits\"}";
    private static final String NEW_FEED_FAIL_ERROR_MESSAGE     = "{\"message\":\"FeedIo\\\\Adapter\\\\NotFoundException: Client error: `GET http:\\/\\/feeds2.feedburner.com\\/stadt-bremerhaven\\/dqXM222` resulted in a `404 Feed not found error: FeedBurner cannot locate this feed URI.` response:\\n\\u003Chtml\\u003E\\n\\u003Chead\\u003E\\n\\u003Cstyle type=\\\"text\\/css\\\"\\u003E\\na:link, a:visited {\\n  color: #000099;\\n  text-decoration: underline;\\n}\\n\\na:hover {\\n  (truncated...)\\n in \\/apps2\\/news\\/lib\\/Fetcher\\/Client\\/FeedIoClient.php:57\\nStack trace:\\n#0 \\/apps2\\/news\\/vendor\\/debril\\/feed-io\\/src\\/FeedIo\\/Reader.php(116): OCA\\\\News\\\\Fetcher\\\\Client\\\\FeedIoClient-\\u003EgetResponse('http:\\/\\/feeds2.f...', Object(DateTime))\\n#1 \\/apps2\\/news\\/vendor\\/debril\\/feed-io\\/src\\/FeedIo\\/FeedIo.php(286): FeedIo\\\\Reader-\\u003Eread('http:\\/\\/feeds2.f...', Object(FeedIo\\\\Feed), Object(DateTime))\\n#2 \\/apps2\\/news\\/lib\\/Fetcher\\/FeedFetcher.php(77): FeedIo\\\\FeedIo-\\u003Eread('http:\\/\\/feeds2.f...')\\n#3 \\/apps2\\/news\\/lib\\/Fetcher\\/Fetcher.php(68): OCA\\\\News\\\\Fetcher\\\\FeedFetcher-\\u003Efetch('http:\\/\\/feeds2.f...', true, NULL, NULL, NULL)\\n#4 \\/apps2\\/news\\/lib\\/Service\\/FeedService.php(116): OCA\\\\News\\\\Fetcher\\\\Fetcher-\\u003Efetch('http:\\/\\/feeds2.f...', true, NULL, NULL, NULL)\\n#5 \\/apps2\\/news\\/lib\\/Controller\\/FeedApiController.php(96): OCA\\\\News\\\\Service\\\\FeedService-\\u003Ecreate('http:\\/\\/feeds2.f...', 0, 'david')\\n#6 \\/nextcloud\\/lib\\/private\\/AppFramework\\/Http\\/Dispatcher.php(166): OCA\\\\News\\\\Controller\\\\FeedApiController-\\u003Ecreate('http:\\/\\/feeds2.f...', 0)\\n#7 \\/nextcloud\\/lib\\/private\\/AppFramework\\/Http\\/Dispatcher.php(99): OC\\\\AppFramework\\\\Http\\\\Dispatcher-\\u003EexecuteController(Object(OCA\\\\News\\\\Controller\\\\FeedApiController), 'create')\\n#8 \\/nextcloud\\/lib\\/private\\/AppFramework\\/App.php(118): OC\\\\AppFramework\\\\Http\\\\Dispatcher-\\u003Edispatch(Object(OCA\\\\News\\\\Controller\\\\FeedApiController), 'create')\\n#9 \\/nextcloud\\/lib\\/private\\/AppFramework\\/Routing\\/RouteActionHandler.php(47): OC\\\\AppFramework\\\\App::main('OCA\\\\\\\\News\\\\\\\\Contro...', 'create', Object(OC\\\\AppFramework\\\\DependencyInjection\\\\DIContainer), Array)\\n#10 [internal function]: OC\\\\AppFramework\\\\Routing\\\\RouteActionHandler-\\u003E__invoke(Array)\\n#11 \\/nextcloud\\/lib\\/private\\/Route\\/Router.php(297): call_user_func(Object(OC\\\\AppFramework\\\\Routing\\\\RouteActionHandler), Array)\\n#12 \\/nextcloud\\/lib\\/base.php(987): OC\\\\Route\\\\Router-\\u003Ematch('\\/apps\\/news\\/api\\/...')\\n#13 \\/nextcloud\\/index.php(42): OC::handleRequest()\\n#14 {main}\"}";


    public NewsTestNetworkRequest networkRequestSpy;

    TestApiProvider(MemorizingTrustManager mtm, SharedPreferences sp, Context context) {
        super(mtm, sp, context);
    }

    @Override
    protected void initSsoApi(final NextcloudAPI.ApiConnectedListener callback) {
        NewsTestNetworkRequest networkRequest = new NewsTestNetworkRequest(context, callback);
        networkRequestSpy = Mockito.spy(networkRequest);

        // By spying on the method "performNetworkRequest" we can later check if requests were build correctly
        try {
            Mockito.doCallRealMethod().when(networkRequestSpy).performNetworkRequest(any(), any());
        } catch (Exception e) {
            e.printStackTrace();
        }

        NextcloudAPI nextcloudAPI = new NextcloudAPI(GsonConfig.GetGson(), networkRequestSpy);
        mNewsApi = new NextcloudRetrofitApiBuilder(nextcloudAPI, NewsAPI.mApiEndpoint).create(NewsAPI.class);
    }


    public class NewsTestNetworkRequest extends NetworkRequest {

        NewsTestNetworkRequest(Context context, NextcloudAPI.ApiConnectedListener callback) {
            super(null, null, callback);
        }

        @Override
        protected void connect(String type) {
            super.connect(type);
            mCallback.onConnected();
        }

        public InputStream performNetworkRequest(NextcloudRequest request, InputStream requestBodyInputStream) throws Exception {
            if(Looper.myLooper() == Looper.getMainLooper()) {
                throw new NetworkOnMainThreadException();
            }

            Log.w(TAG, "Requested URL: " + request.getUrl());
            InputStream inputStream;
            switch (request.getUrl()) {
                case "/index.php/apps/news/api/v1-2/feeds":
                    if("POST".equals(request.getMethod())) {
                        inputStream = handleCreateFeed(request);
                    } else {
                        inputStream = stringToInputStream("{\"feeds\": []}");
                    }
                    break;
                case "/index.php/apps/news/api/v1-2/user":
                    inputStream = handleUser();
                    break;
                case "/index.php/apps/news/api/v1-2/folders":
                    inputStream = handleFolders();
                    break;
                case "/index.php/apps/news/api/v1-2/items":
                    inputStream = stringToInputStream("{\"items\": []}");
                    break;
                //case "index.php/apps/news/api/v1-2/feeds":
                case "/index.php/apps/news/api/v1-2/items/unread/multiple":
                    inputStream = stringToInputStream("");
                    break;
                default:
                    Log.e(TAG, request.getUrl());
                    throw new Error("Not implemented yet!");
            }
            return inputStream;
        }

        @Override
        protected Response performNetworkRequestV2(NextcloudRequest request, InputStream requestBodyInputStream) throws Exception {
            return new Response(
                    performNetworkRequest(request, requestBodyInputStream), new ArrayList<>(0)
            );
        }

        private InputStream handleFolders() {
            String folders = "{\"folders\":[{\"id\":2,\"name\":\"Comic\"},{\"id\":3,\"name\":\"Android\"}]}";
            return stringToInputStream(folders);
        }


        // https://github.com/nextcloud/news/blob/master/docs/externalapi/Legacy.md#create-a-feed
        private InputStream handleCreateFeed(NextcloudRequest request) throws NextcloudHttpRequestFailedException {
            var url = request.getParameterV2().stream().filter((s) -> s.key.equals("url")).findFirst().get().value;
            switch (url) {
                case NEW_FEED_SUCCESS:
                    return stringToInputStream("");
                case NEW_FEED_EXISTING:
                    throw new NextcloudHttpRequestFailedException(context, 409, new Throwable(NEW_FEED_EXISTING_ERROR_MESSAGE));
                case NEW_FEED_FAIL:
                    throw new NextcloudHttpRequestFailedException(context, 422, new Throwable(NEW_FEED_FAIL_ERROR_MESSAGE));
                default:
                    throw new Error("Not implemented yet!");
            }
        }

        private InputStream handleUser() {
            String user = "{\n" +
            "  \"userId\": \"" + DUMMY_ACCOUNT_AccountName + "\",\n" +
            "  \"displayName\": \"" + DUMMY_ACCOUNT_username + "\",\n" +
            "  \"lastLoginTimestamp\": 1241231233, \n" +
            "  \"avatar\": null" +
            "}";

            return stringToInputStream(user);
        }

        private InputStream stringToInputStream(String data) {
            return new ByteArrayInputStream(data.getBytes(StandardCharsets.UTF_8));
        }
    }
}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestComponent.java
================================================
package de.luhmer.owncloudnewsreader.di;

import javax.inject.Singleton;

import dagger.Component;
import de.luhmer.owncloudnewsreader.tests.NewFeedTests;
import de.luhmer.owncloudnewsreader.tests.NewsReaderListActivityUiTests;
import de.luhmer.owncloudnewsreader.tests.NightModeTest;

@Singleton
@Component(modules = { ApiModule.class })
public interface TestComponent extends AppComponent {

    void inject(NewFeedTests newFeedTest);
    void inject(NightModeTest nightModeTest);

    void inject(NewsReaderListActivityUiTests newsReaderListActivityUiTests);
}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/helper/Utils.java
================================================
package de.luhmer.owncloudnewsreader.helper;

import android.content.Context;
import android.content.SharedPreferences;

import de.luhmer.owncloudnewsreader.R;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.withId;

public class Utils {

    public static void initMaterialShowCaseView(Context context) {
        String PREFS_NAME = "material_showcaseview_prefs";
        SharedPreferences sp = context.getSharedPreferences(PREFS_NAME, Context.MODE_PRIVATE);
        sp.edit()
            .putInt("status_SWIPE_LEFT_RIGHT_AND_PTR", -1)
            .putInt("status_LOGO_SYNC", -1)
            .commit();
    }

    public static void clearFocus() {
        sleep(200);
        onView(withId(R.id.toolbar)).perform(click());
        sleep(200);
    }

    public static void sleep(int millis) {
        try {
            Thread.sleep(millis);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void sleep(float seconds) {
        try {
            Thread.sleep((long) seconds * 1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/DownloadWebPageServiceTest.java
================================================
package de.luhmer.owncloudnewsreader.tests;

import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Rule;
import org.junit.runner.RunWith;

import de.luhmer.owncloudnewsreader.NewsReaderListActivity;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class DownloadWebPageServiceTest {

    //private String expectedAppName;

    @Rule
    public ActivityTestRule<NewsReaderListActivity> mActivityRule = new ActivityTestRule<>(NewsReaderListActivity.class);

    /*
    private UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

    private Activity getActivity() {
        return mActivityRule.getActivity();
    }

    @Before
    private void setUp() {
        expectedAppName = getActivity().getString(R.string.app_name);
    }

    @Test
    public void testStartDownload() {
        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
        onView(withText(getActivity().getString(R.string.action_download_articles_offline))).perform(click());

    }

    private void clearAllNotifications() {
        UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
        uiDevice.openNotification();
        long timeoutInMillis = 1000;
        uiDevice.wait(Until.hasObject(By.textStartsWith(expectedAppName)), timeoutInMillis);
        //UiObject2 clearAll = uiDevice.findObject(By.res(clearAllNotificationRes));
        //clearAll.click();
    }

    @Test
    void shouldSendNotificationWhichContainsTitleTextAndAllCities() {
        String expectedAppName = "Test";
        String expectedAllCities = "Test";
        String expectedTitle = "Test";
        String expectedText = "Test";
        // TODO do something here..!
        uiDevice.openNotification();
        //uiDevice.wait(Until.hasObject(By.textStartsWith(expectedAppName)), timeout);
        UiObject2 title = uiDevice.findObject(By.text(expectedTitle));
        UiObject2 text= uiDevice.findObject(By.textStartsWith(expectedText));
        //UiObject2 allCities= uiDevice.findObject(By.res(expectedAllCitiesActionRes));
        assertEquals(expectedTitle, title.getText());
        assertTrue(text.getText().startsWith(expectedText));
        //assertEquals(expectedAllCities.toLowerCase(), allCities.getText().toLowerCase());
        clearAllNotifications();
    }

    private class ClickOnSendNotification implements ViewAction {

        private final String TAG = ClickOnSendNotification.class.getCanonicalName();

        public String getDescription() {
            return "Click on the send notification button";
        }

        public Matcher<View> getConstraints() {
            return Matchers.allOf(isDisplayed(), isAssignableFrom(Button.class));
        }

        public void perform(@Nullable UiController uiController, @Nullable View view) {
            //view.findViewById(R.id.stop).performClick();
            Log.d(TAG, "perform() called with: uiController = [" + uiController + "], view = [" + view + "]");
        }
    }

    */
}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NewFeedTests.java
================================================
package de.luhmer.owncloudnewsreader.tests;


import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.closeSoftKeyboard;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.hasErrorText;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.timeout;
import static org.mockito.Mockito.verify;

import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;

import com.nextcloud.android.sso.aidl.NextcloudRequest;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.junit.MockitoJUnitRunner;

import javax.inject.Inject;

import de.luhmer.owncloudnewsreader.NewFeedActivity;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.TestApplication;
import de.luhmer.owncloudnewsreader.di.ApiProvider;
import de.luhmer.owncloudnewsreader.di.TestApiProvider;
import de.luhmer.owncloudnewsreader.di.TestComponent;


//@RunWith(AndroidJUnit4.class)
@RunWith(MockitoJUnitRunner.class)
@LargeTest
public class NewFeedTests {

    @Rule
    public ActivityTestRule<NewFeedActivity> activityRule = new ActivityTestRule<>(NewFeedActivity.class);

    protected @Inject ApiProvider mApi;

    @Before
    public void setUp() {
        TestComponent ac = (TestComponent) ((TestApplication)(activityRule.getActivity().getApplication())).getAppComponent();
        ac.inject(this);

        // Reset Spy object
        mApi.initApi(null);
        //reset(((TestApiProvider)mApi).networkRequestSpy);
    }

    @Test
    public void addNewFeed() {
        String feed = TestApiProvider.NEW_FEED_SUCCESS;

        // Type text and then press the button.
        onView(withId(R.id.et_feed_url)).perform(typeText(feed), closeSoftKeyboard());
        onView(withId(R.id.btn_addFeed)).perform(click());

        try {
            verifyRequest(feed);

            //onView(withId(R.id.et_feed_url)).check(matches(hasErrorText(nullValue(String.class))));

            // Check Activity existed
            Thread.sleep(1000);
            assertFalse(activityRule.getActivity().getWindow().getDecorView().isShown());
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }

    @Test
    public void addExistingFeed() {
        String feed = TestApiProvider.NEW_FEED_EXISTING;

        // Type text and then press the button.
        onView(withId(R.id.et_feed_url)).perform(typeText(feed), closeSoftKeyboard());
        onView(withId(R.id.btn_addFeed)).perform(click());

        try {
            verifyRequest(feed);

            // Check Activity still open
            Thread.sleep(1000);
            assertTrue(activityRule.getActivity().getWindow().getDecorView().isShown());

            onView(withId(R.id.et_feed_url)).check(matches(hasErrorText(is("Feed konnte nicht hinzugefügt werden:  Existiert bereits"))));
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }

    @Test
    public void addInvalidFeed() {
        String feed = TestApiProvider.NEW_FEED_FAIL;

        // Type text and then press the button.
        onView(withId(R.id.et_feed_url)).perform(typeText(feed), closeSoftKeyboard());
        onView(withId(R.id.btn_addFeed)).perform(click());

        try {
            verifyRequest(feed);

            // Check Activity still open
            Thread.sleep(1000);
            assertTrue(activityRule.getActivity().getWindow().getDecorView().isShown());

            onView(withId(R.id.et_feed_url)).check(matches(hasErrorText(is("FeedIo\\Adapter\\NotFoundException: Client error: `GET http://feeds2.feedburner.com/stadt-bremerhaven/dqXM222` resulted in a `404 Feed not found error: ..."))));
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }

    // Verify that the API was actually called
    private void verifyRequest(String feed) throws Exception {
        TestApiProvider.NewsTestNetworkRequest nr = ((TestApiProvider) mApi).networkRequestSpy;
        ArgumentCaptor<NextcloudRequest> argument = ArgumentCaptor.forClass(NextcloudRequest.class);
        verify(nr, timeout(2000)).performNetworkRequest(argument.capture(), any());
        assertEquals("/index.php/apps/news/api/v1-2/feeds", argument.getValue().getUrl());
        var url = argument.getValue().getParameterV2().stream().filter((s) -> s.key.equals(("url"))).findFirst().get().value;
        var folderId = argument.getValue().getParameterV2().stream().filter((s) -> s.key.equals(("folderId"))).findFirst().get().value;
        assertEquals(feed, url);
        assertEquals("0", folderId);
    }
}


================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NewsReaderListActivityUiTests.java
================================================
package de.luhmer.owncloudnewsreader.tests;

import android.content.SharedPreferences;
import android.os.Bundle;
import android.os.SystemClock;
import android.view.View;

import androidx.annotation.IdRes;
import androidx.annotation.NonNull;
import androidx.fragment.app.Fragment;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.Espresso;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.espresso.matcher.BoundedMatcher;
import androidx.test.espresso.matcher.ViewMatchers;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.runner.AndroidJUnit4;

import com.nextcloud.android.sso.aidl.NextcloudRequest;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.stream.Collectors;

import javax.inject.Inject;

import de.luhmer.owncloudnewsreader.Constants;
import de.luhmer.owncloudnewsreader.NewsReaderDetailFragment;
import de.luhmer.owncloudnewsreader.NewsReaderListActivity;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.TestApplication;
import de.luhmer.owncloudnewsreader.adapter.NewsListRecyclerAdapter;
import de.luhmer.owncloudnewsreader.adapter.RssItemViewHolder;
import de.luhmer.owncloudnewsreader.di.ApiProvider;
import de.luhmer.owncloudnewsreader.di.TestApiProvider;
import de.luhmer.owncloudnewsreader.di.TestComponent;
import helper.OrientationChangeAction;
import helper.RecyclerViewAssertions;

import static androidx.core.util.Preconditions.checkNotNull;
import static androidx.test.InstrumentationRegistry.getInstrumentation;
import static androidx.test.InstrumentationRegistry.registerInstance;
import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.action.ViewActions.typeText;
import static androidx.test.espresso.assertion.ViewAssertions.doesNotExist;
import static androidx.test.espresso.assertion.ViewAssertions.matches;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.isDisplayed;
import static androidx.test.espresso.matcher.ViewMatchers.isRoot;
import static androidx.test.espresso.matcher.ViewMatchers.withClassName;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withEffectiveVisibility;
import static androidx.test.espresso.matcher.ViewMatchers.withId;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static de.luhmer.owncloudnewsreader.helper.Utils.clearFocus;
import static de.luhmer.owncloudnewsreader.helper.Utils.initMaterialShowCaseView;
import static de.luhmer.owncloudnewsreader.helper.Utils.sleep;
import static junit.framework.TestCase.assertNotNull;
import static junit.framework.TestCase.assertTrue;
import static junit.framework.TestCase.fail;
import static org.hamcrest.Matchers.allOf;
import static org.hamcrest.Matchers.is;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class NewsReaderListActivityUiTests {

    private int scrollPosition = 10;

    @Rule
    public ActivityTestRule<NewsReaderListActivity> mActivityRule = new ActivityTestRule<>(NewsReaderListActivity.class);

    @Rule
    public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);

    protected @Inject SharedPreferences mPrefs;
    protected @Inject ApiProvider mApi;

    private NewsReaderListActivity getActivity() {
        return mActivityRule.getActivity();
    }

    @Before
    public void setUp() {
        registerInstance(getInstrumentation(), new Bundle());
        sleep(0.3f);

        TestComponent ac = (TestComponent) ((TestApplication)(getActivity().getApplication())).getAppComponent();
        ac.inject(this);

        clearFocus();

        initMaterialShowCaseView(getActivity());
    }

    @Test
    public void testPositionAfterOrientationChange_sameActivity() {
        NewsReaderDetailFragment ndf = (NewsReaderDetailFragment) waitForFragment(R.id.content_frame, 5000);

        onView(withId(R.id.list)).perform(
                RecyclerViewActions.scrollToPosition(scrollPosition));

        onView(isRoot()).perform(OrientationChangeAction.orientationLandscape(getActivity()));
        //onView(isRoot()).perform(OrientationChangeAction.orientationPortrait(getActivity()));

        sleep(2000);

        LinearLayoutManager llm = (LinearLayoutManager) ndf.getRecyclerView().getLayoutManager();
        int expectedPosition = scrollPosition-(scrollPosition-llm.findFirstVisibleItemPosition());

        // As there is a little offset when rotating.. we need to add one here..
        onView(withId(R.id.list)).check(new RecyclerViewAssertions(expectedPosition+1));
        onView(withId(R.id.tv_no_items_available)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));

        sleep(2000);

        onView(isRoot()).perform(OrientationChangeAction.orientationPortrait(getActivity()));

        onView(withId(R.id.list)).check(new RecyclerViewAssertions(expectedPosition));
        onView(withId(R.id.tv_no_items_available)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
    }

    @Test
    public void testPositionAfterActivityRestart_sameActivity() {
        onView(withId(R.id.list)).perform(RecyclerViewActions.scrollToPosition(scrollPosition));

        onView(withId(R.id.list)).perform(RecyclerViewActions.actionOnItemAtPosition(scrollPosition, click()));

        sleep(2000);

        Espresso.pressBack();

        NewsReaderDetailFragment ndf = (NewsReaderDetailFragment) waitForFragment(R.id.content_frame, 5000);
        assertNotNull(ndf);
        final NewsListRecyclerAdapter na = (NewsListRecyclerAdapter) ndf.getRecyclerView().getAdapter();
        assertNotNull(na);
        final RssItemViewHolder vh = (RssItemViewHolder) ndf.getRecyclerView().getChildViewHolder(ndf.getRecyclerView().getLayoutManager().findViewByPosition(scrollPosition));
        assertNotNull(vh);
        LinearLayoutManager llm = (LinearLayoutManager) ndf.getRecyclerView().getLayoutManager();

        getActivity().runOnUiThread(() -> na.changeReadStateOfItem(vh, false));
        sleep(1.0f);

        int expectedPosition = scrollPosition-(scrollPosition-llm.findFirstVisibleItemPosition());
        onView(withId(R.id.list)).check(new RecyclerViewAssertions(expectedPosition));
        onView(withId(R.id.tv_no_items_available)).check(matches(withEffectiveVisibility(ViewMatchers.Visibility.GONE)));
    }


    @Test
    public void testSyncFinishedRefreshRecycler_sameActivity() {
        assertTrue(syncResultTest(true));
    }

    @Test
    public void testSyncFinishedSnackbar_sameActivity() {
        assertTrue(syncResultTest(false));
    }


    @Test
    public void searchTest() {
        String firstItem = "Immer wieder sonntags KW 19";
        // String firstItem = "These are the best screen protectors for the Huawei P30 Pro";

        // Check first item
        checkRecyclerViewFirstItemText(firstItem);

        // Open search menu
        onView(allOf(withId(R.id.menu_search), withContentDescription(getString(R.string.action_search)), isDisplayed())).perform(click());

        // Type in "test" into searchbar
        onView(allOf(withClassName(is("android.widget.SearchView$SearchAutoComplete")), isDisplayed())).perform(typeText("test"));
        sleep(1000);
        checkRecyclerViewFirstItemText("VR ohne Kabel: Die Oculus Quest im Test, definitiv der richtige Ansatz");
        // checkRecyclerViewFirstItemText("Testfahrt im Mercedes E 300 de mit 90-kW-Elektromotor und Vierzylinder-Diesel");

        // Close search bar
        onView(withContentDescription("Collapse")).perform(click());

        sleep(1000);

        // Test if search reset was successful
        checkRecyclerViewFirstItemText(firstItem);
    }

    @Test
    public void syncTest() {
        // Open navigation drawer
        onView(allOf(withContentDescription(getString(R.string.news_list_drawer_text)), isDisplayed())).perform(click());

        sleep(1500);

        /*
        // Click on Got it
        onView(allOf(withText("GOT IT"), isDisplayed())).perform(click());

        sleep(1000);
        */

        // Trigger refresh
        onView(allOf(withContentDescription(getString(R.string.content_desc_tap_to_refresh)), isDisplayed())).perform(click());

        sleep(1000);
        try {
            verifySyncRequested();
        } catch (Exception e) {
            fail(e.getMessage());
        }
    }

    // Verify that the API was actually called
    private void verifySyncRequested() throws Exception {
        TestApiProvider.NewsTestNetworkRequest nr = ((TestApiProvider)mApi).networkRequestSpy;
        ArgumentCaptor<NextcloudRequest> argument = ArgumentCaptor.forClass(NextcloudRequest.class);
        verify(nr, times(6)).performNetworkRequest(argument.capture(), any());

        List<String> requestedUrls = argument.getAllValues().stream().map(nextcloudRequest -> nextcloudRequest.getUrl()).collect(Collectors.toList());

        assertTrue(requestedUrls.contains("/index.php/apps/news/api/v1-2/folders"));
        assertTrue(requestedUrls.contains("/index.php/apps/news/api/v1-2/feeds"));
        assertTrue(requestedUrls.contains("/index.php/apps/news/api/v1-2/items/unread/multiple"));
        assertTrue(requestedUrls.contains("/index.php/apps/news/api/v1-2/items")); // TODO Double check why /items is called twice... ?
        assertTrue(requestedUrls.contains("/index.php/apps/news/api/v1-2/user"));
    }



    private void checkRecyclerViewFirstItemText(String text) {
        onView(withId(R.id.list)).check(matches(atPosition(0, hasDescendant(withText(text)))));
    }

    private String getString(@IdRes int resId) {
        return mActivityRule.getActivity().getString(resId);
    }


    public static Matcher<View> atPosition(final int position, @NonNull final Matcher<View> itemMatcher) {
        checkNotNull(itemMatcher);
        return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
            @Override
            public void describeTo(Description description) {
                description.appendText("has item at position " + position + ": ");
                itemMatcher.describeTo(description);
            }

            @Override
            protected boolean matchesSafely(final RecyclerView view) {
                RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(position);
                if (viewHolder == null) {
                    // has no item on such position
                    return false;
                }
                return itemMatcher.matches(viewHolder.itemView);
            }
        };
    }

    private boolean syncResultTest(boolean testFirstPosition) {
        if(!testFirstPosition) {
            onView(withId(R.id.list)).perform(RecyclerViewActions.scrollToPosition(scrollPosition));
        }

        mPrefs.edit().putInt(Constants.LAST_UPDATE_NEW_ITEMS_COUNT_STRING, 5).commit();

        try {
            final Method method = NewsReaderListActivity.class.getDeclaredMethod("syncFinishedHandler");
            method.setAccessible(true);
            getActivity().runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    try {
                        if (!(boolean) method.invoke(getActivity())) {
                            fail("Method invocation failed!");
                        }
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        fail(e.getMessage());
                    } catch (InvocationTargetException e) {
                        e.printStackTrace();
                        fail(e.getMessage());
                    }
                }
            });
            getInstrumentation().waitForIdleSync();
            sleep(1.0f);

            if(!testFirstPosition) {
                onView(withId(com.google.android.material.R.id.snackbar_text)).check(matches(isDisplayed()));
            } else {
                onView(withId(com.google.android.material.R.id.snackbar_text)).check(doesNotExist());
            }
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
            fail(e.getMessage());
        }
        return true;
    }

    private Fragment waitForFragment(int id, int timeout) {
        long endTime = SystemClock.uptimeMillis() + timeout;
        while (SystemClock.uptimeMillis() <= endTime) {
            Fragment fragment = getActivity().getSupportFragmentManager().findFragmentById(id);
            if (fragment != null) {
                return fragment;
            }
        }
        return null;
    }


}

================================================
FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NightModeTest.java
================================================
package de.luhmer.owncloudnewsreader.tests;

import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;

import androidx.recyclerview.widget.RecyclerView;
import androidx.test.InstrumentationRegistry;
import androidx.test.espresso.contrib.RecyclerViewActions;
import androidx.test.filters.LargeTest;
import androidx.test.rule.ActivityTestRule;
import androidx.test.rule.GrantPermissionRule;
import androidx.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

import javax.inject.Inject;

import de.luhmer.owncloudnewsreader.NewsReaderListActivity;
import de.luhmer.owncloudnewsreader.R;
import de.luhmer.owncloudnewsreader.TestApplication;
import de.luhmer.owncloudnewsreader.di.TestComponent;
import de.luhmer.owncloudnewsreader.helper.ThemeChooser;

import static androidx.test.espresso.Espresso.onView;
import static androidx.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
import static androidx.test.espresso.action.ViewActions.click;
import static androidx.test.espresso.matcher.ViewMatchers.hasDescendant;
import static androidx.test.espresso.matcher.ViewMatchers.withContentDescription;
import static androidx.test.espresso.matcher.ViewMatchers.withText;
import static junit.framework.TestCase.assertTrue;
import static org.hamcrest.CoreMatchers.instanceOf;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.fail;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class NightModeTest {

    protected @Inject SharedPreferences mPrefs;

    /**
     * NOTE: These tests only work during "daylight".. (this is because there is no way to check
     * the current state of the android day/night mode)
     */

    @Rule
    public ActivityTestRule<NewsReaderListActivity> mActivityRule = new ActivityTestRule<>(NewsReaderListActivity.class);
    //public ActivityTestRule<NewsReaderListActivity> mActivityRule = new ActivityTestRule<>(NewsReaderListActivity.class, true, false);

    @Rule
    public GrantPermissionRule mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.ACCESS_FINE_LOCATION);

    private Activity getActivity() {
        return mActivityRule.getActivity();
    }

    @Before
    public void resetSharedPrefs() {
        TestComponent ac = (TestComponent) ((TestApplication)(getActivity().getApplication())).getAppComponent();
        ac.inject(this);

        /*
        // Set Fixed time
        Instant.now(
                Clock.fixed(
                        Instant.parse( "2019-04-05T18:00:00Z"), ZoneOffset.UTC
                )
        );
        */
    }


    @Test
    public void testBackgroundDaylightTheme() {
        assertFalse(isDarkTheme());
        //onView(withId(R.id.sliding_layout)).check(matches(withBackgroundColor(android.R.color.white, getActivity())));
    }

    @Test
    public void testOledAutoMode() {
        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
        openSettings();

        changeAppTheme(R.string.pref_display_apptheme_auto);
        switchOled();
        navigateUp();
        assertFalse(isDarkTheme());
        sleep();

        //onView(withId(R.id.sliding_layout)).check(ViewAssertions.matches(CustomMatchers.withBackgroundColor(android.R.color.white, getActivity())));
        assertEquals(ThemeChooser.THEME.LIGHT, getPrivateField("mSelectedTheme"));
    }

    @Test
    public void testLightTheme() {
        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
        openSettings();

        changeAppTheme(R.string.pref_display_apptheme_light);
        navigateUp();
        sleep();
        boolean isDarkTheme = isDarkTheme();
        assertFalse(ThemeChooser.isOledMode(false));
        assertFalse(isDarkTheme);
        assertEquals(ThemeChooser.THEME.LIGHT, getPrivateField("mSelectedTheme"));
        //sleep();
    }

    @Test
    public void testDarkTheme() {
        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
        openSettings();

        changeAppTheme(R.string.pref_display_apptheme_dark);
        navigateUp();
        sleep();
        boolean isDarkTheme = isDarkTheme();
        assertFalse(ThemeChooser.isOledMode(false));
        assertTrue(isDarkTheme);
        assertEquals(ThemeChooser.THEME.DARK, getPrivateField("mSelectedTheme"));
        //sleep();
    }

    @Test
    public void testDarkOledTheme() {
        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
        openSettings();

        changeAppTheme(R.string.pref_display_apptheme_dark);
        switchOled();
        navigateUp();
        sleep();
        boolean isDarkTheme = isDarkTheme();
        assertTrue(ThemeChooser.isOledMode(false));
        assertTrue(isDarkTheme);
        assertEquals(ThemeChooser.THEME.OLED, getPrivateField("mSelectedTheme"));
        //sleep();
    }

    private void sleep() {
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void navigateUp() {
        onView(withContentDescription(androidx.appcompat.R.string.abc_action_bar_up_description)).perform(click());
    }

    private void openSettings() {
        onView(withText(getActivity().getString(R.string.action_settings))).perform(click());
    }

    private void changeAppTheme(int appThemeText) {
        String title = getActivity().getString(R.string.pref_title_app_theme);

        onView(is(instanceOf(RecyclerView.class)))
            .perform(RecyclerViewActions.scrollTo(hasDescendant(withText(title))))
            .perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(title)), click()));

        onView(withText(getActivity().getString(appThemeText)))
                .perform(click());
    }

    private void switchOled() {
        String title = getActivity().getString(R.string.pref_oled_mode);

        onView(is(instanceOf(RecyclerView.class)))
                .perform(RecyclerViewActions.scrollTo(hasDescendant(withText(title))))
                .perform(RecyclerViewActions.actionOnItem(hasDescendant(withText(title)), click()));
    }

    private boolean isDarkTheme() {
        try {
            Method method = ThemeChooser.class.getDeclaredMethod("isDarkTheme", Context.class);
            method.setAccessible(true);
            boolean isDarkTheme = (boolean) method.invoke(null, getActivity());
            return isDarkTheme;
        } catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
            fail(e.toString() + " - " + e.getMessage());
        }
        return false;
    }

    private Object getPrivateField(String fieldName) {
        try {
            Field[] fields = ThemeChooser.class.getDeclaredFields();
            for (Field field : fields) {
                if(fieldName.equals(field.getName())) {
                    field.setAccessible(true);
                    return field.get(null);
                }
            }
        } catch (IllegalAccessException e) {
            fail(e.getMessage());
        }
        return null;
    }

}

================================================
FILE: News-Android-App/src/androidTest/java/helper/CustomMatchers.java
================================================
package helper;

import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.graphics.drawable.ColorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.StateListDrawable;
import android.os.Build;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.TextView;

import androidx.core.content.ContextCompat;
import androidx.test.espresso.matcher.BoundedMatcher;

import org.hamcrest.Description;
import org.hamcrest.Matcher;
import org.hamcrest.TypeSafeDiagnosingMatcher;
import org.hamcrest.TypeSafeMatcher;

public class CustomMatchers {
    private static final String TAG = CustomMatchers.class.getCanonicalName();

    public static Matcher<View> withBackgroundColor(final int resourceColorId, final Activity activity) {
        return new TypeSafeDiagnosingMatcher<View>() {

            String error;

            @Override
            public void describeTo(Description description) {
                description.appendText(error);
            }

            @Override
            protected boolean matchesSafely(View view, Description mismatchDescription) {
                Drawable drawable = view.getBackground();
                Drawable otherDrawable = ContextCompat.getDrawable(view.getContext(), resourceColorId);

                if (drawable instanceof ColorDrawable) {
                    int colorId = ((ColorDrawable) drawable).getColor();

                    if(colorId == resourceColorId) {
                        return true;
                    } else {
                        error = "FAILED Got: " + colorId;
                    }
                } else {
                    Log.e(TAG, drawable.toString());
                    Log.e(TAG, otherDrawable.toString());
                    error = "Not ColorDrawable's!!";
                }

                return false;
            }
        };
    }

    private static int getColor(Context context, int color) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            return context.getColor(color);
        } else {
            return ContextCompat.getColor(context, color);
        }
    }

    public static int getBackgroundColor(Context context, View v, int defaultColor) {
        Drawable drawable = v.getBackground();
        if (drawable instanceof ColorDrawable) {
            ColorDrawable colorDrawable = (ColorDrawable) drawable;
            return colorDrawable.getColor();
        } else {
            return getColor(context, defaultColor);
        }
    }

    public static Matcher<View> withBackground(final int resourceId) {
        return new TypeSafeMatcher<View>() {

            @Override
            public boolean matchesSafely(View view) {
                return sameBitmap(view.getContext(), view.getBackground(), resourceId);
            }

            @Override
            protected void describeMismatchSafely(View item, Description mismatchDescription) {
                mismatchDescription.appendText("view.getBackground() returned: " + item.getBackground());
            }

            @Override
            public void describeTo(Description description) {
                description.appendText("" + resourceId);
            }
        };
    }

    public static Matcher<View> withCompoundDrawable(final int resourceId) {
        return new BoundedMatcher<View, TextView>(TextView.class) {
            @Override
            public void describeTo(Description description) {
                description.appendText("has compound drawable resource " + resourceId);
            }

            @Override
            public boolean matchesSafely(TextView textView) {
                for (Drawable drawable : textView.getCompoundDrawables()) {
                    if (sameBitmap(textView.getContext(), drawable, resourceId)) {
                        return true;
                    }
                }
                return false;
            }
        };
    }

    public static Matcher<View> withImageDrawable(final int resourceId) {
        return new BoundedMatcher<View, ImageView>(ImageView.class) {
            @Override
            public void describeTo(Description description) {
                description.appendText("has image drawable resource " + resourceId);
            }

            @Override
            public boolean matchesSafely(ImageView imageView) {
                return sameBitmap(imageView.getContext(), imageView.getDrawable(), resourceId);
            }
        };
    }

    private static boolean sameBitmap(Context context, Drawable drawable, int resourceId) {
        Drawable otherDrawable = context.getResources().getDrawable(resourceId);
        if (drawable == null || otherDrawable == null) {
            Log.e(TAG, "drawable null!!");
            return false;
        }
        if (drawable instanceof StateListDrawable && otherDrawable instanceof StateListDrawable) {
            Log.e(TAG, "other drawable!!");
            return drawable.getCurrent().equals(otherDrawable.getCurrent());
        }
        if (drawable instanceof BitmapDrawable) {
            Log.e(TAG, "bitmap drawable!!");
            Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
            Bitmap otherBitmap = ((BitmapDrawable) otherDrawable).getBitmap();
            return bitmap.sameAs(otherBitmap);
        }
        return false;
    }
}

================================================
FILE: News-Android-App/src/androidTest/java/helper/OrientationChangeAction.java
================================================
/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2015 - Nathan Barraille
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 * 
 */

package helper;

import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.view.View;

import androidx.test.espresso.UiController;
import androidx.test.espresso.ViewAction;
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry;
import androidx.test.runner.lifecycle.Stage;

import org.hamcrest.Matcher;

import java.util.Collection;

import static androidx.test.espresso.matcher.ViewMatchers.isRoot;

/**
 * An Espresso ViewAction that changes the orientation of the screen
 */
public class OrientationChangeAction implements ViewAction {

    private final int orientation;
    private Activity activity;

    private OrientationChangeAction(int orientation, Activity activity) {
        this.orientation = orientation;
        this.activity = activity;
    }

    @Override
    public Matcher<View> getConstraints() {
        return isRoot();
    }

    @Override
    public String getDescription() {
        return "change orientation to " + orientation;
    }

    @Override
    public void perform(UiController uiController, View view) {
        uiController.loopMainThreadUntilIdle();
        activity.setRequestedOrientation(orientation);

        Collection<Activity> resumedActivities = ActivityLifecycleMonitorRegistry.getInstance().getActivitiesInStage(Stage.RESUMED);
        if (resumedActivities.isEmpty()) {
            throw new RuntimeException("Could not change orientation");
        }
    }

    public static ViewAction orientationLandscape(Activity activity) {
        return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE, activity);
    }

    public static ViewAction orientationPortrait(Activity activity) {
        return new OrientationChangeAction(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT, activity);
    }
}

================================================
FILE: News-Android-App/src/androidTest/java/helper/RecyclerViewAssertions.java
================================================
package helper;

import android.view.View;

import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import androidx.test.espresso.NoMatchingViewException;
import androidx.test.espresso.ViewAssertion;

public class RecyclerViewAssertions implements ViewAssertion {

    private int mExpectedPos;

    public RecyclerViewAssertions(int expectedPos) {
        this.mExpectedPos = expectedPos;
    }

    @Override
    public void check(View view, NoMatchingViewException e) {
        RecyclerView recyclerView = (RecyclerView) view;
        LinearLayoutManager layoutManager = ((LinearLayoutManager)recyclerView.getLayoutManager());
        int firstVisiblePosition = layoutManager.findFirstVisibleItemPosition();

        if(firstVisiblePosition != mExpectedPos) {
            throw new RuntimeException("Wrong position! Expected: " + mExpectedPos + " but was: " + firstVisiblePosition);
        }
    }
}


================================================
FILE: News-Android-App/src/androidTes
Download .txt
gitextract_ye9_lomr/

├── .editorconfig
├── .github/
│   ├── FUNDING.yml
│   ├── dependabot.yml
│   └── workflows/
│       ├── analysis.yml
│       ├── ci.yml
│       └── codeql.yml
├── .gitignore
├── .tx/
│   └── config
├── CHANGELOG.md
├── COPYING-AGPL.md
├── COPYING-README.md
├── Gemfile
├── NEWS-POLICY.md
├── News-Android-App/
│   ├── .gitignore
│   ├── build.gradle
│   ├── config/
│   │   └── detekt/
│   │       └── detekt.yml
│   ├── proguard-rules.pro
│   ├── proguard-test.pro
│   ├── remove_invalid_languages.sh
│   └── src/
│       ├── androidTest/
│       │   ├── AndroidManifest.xml
│       │   └── java/
│       │       ├── de/
│       │       │   └── luhmer/
│       │       │       └── owncloudnewsreader/
│       │       │           ├── CustomTestRunner.java
│       │       │           ├── TestApplication.java
│       │       │           ├── di/
│       │       │           │   ├── TestApiModule.java
│       │       │           │   ├── TestApiProvider.java
│       │       │           │   └── TestComponent.java
│       │       │           ├── helper/
│       │       │           │   └── Utils.java
│       │       │           └── tests/
│       │       │               ├── DownloadWebPageServiceTest.java
│       │       │               ├── NewFeedTests.java
│       │       │               ├── NewsReaderListActivityUiTests.java
│       │       │               └── NightModeTest.java
│       │       ├── helper/
│       │       │   ├── CustomMatchers.java
│       │       │   ├── OrientationChangeAction.java
│       │       │   └── RecyclerViewAssertions.java
│       │       └── screengrab/
│       │           └── ScreenshotTest.java
│       ├── dev/
│       │   └── res/
│       │       ├── drawable/
│       │       │   └── ic_launcher_foreground.xml
│       │       └── values/
│       │           └── strings.xml
│       ├── main/
│       │   ├── AndroidManifest.xml
│       │   ├── assets/
│       │   │   └── web.css
│       │   ├── icon.xcf
│       │   ├── java/
│       │   │   ├── com/
│       │   │   │   └── bumptech/
│       │   │   │       └── glide/
│       │   │   │           └── samples/
│       │   │   │               └── svg/
│       │   │   │                   ├── SvgDecoder.kt
│       │   │   │                   └── SvgDrawableTranscoder.kt
│       │   │   └── de/
│       │   │       └── luhmer/
│       │   │           └── owncloudnewsreader/
│       │   │               ├── AddFolderDialogFragment.java
│       │   │               ├── Constants.java
│       │   │               ├── DirectoryChooserActivity.java
│       │   │               ├── FolderOptionsDialogFragment.java
│       │   │               ├── LazyLoadingLinearLayoutManager.kt
│       │   │               ├── ListView/
│       │   │               │   ├── BlockingExpandableListView.java
│       │   │               │   ├── PodcastArrayAdapter.java
│       │   │               │   ├── PodcastFeedArrayAdapter.java
│       │   │               │   └── SubscriptionExpandableListAdapter.java
│       │   │               ├── LoginDialogActivity.java
│       │   │               ├── NewFeedActivity.java
│       │   │               ├── NewsDetailActivity.java
│       │   │               ├── NewsDetailFragment.java
│       │   │               ├── NewsDetailImageDialogFragment.java
│       │   │               ├── NewsReaderApplication.java
│       │   │               ├── NewsReaderDetailFragment.java
│       │   │               ├── NewsReaderListActivity.java
│       │   │               ├── NewsReaderListDialogFragment.java
│       │   │               ├── NewsReaderListFragment.java
│       │   │               ├── NewsReaderOPMLImportDialogFragment.java
│       │   │               ├── PiPVideoPlaybackActivity.java
│       │   │               ├── PodcastFragment.java
│       │   │               ├── PodcastFragmentActivity.java
│       │   │               ├── SettingsActivity.java
│       │   │               ├── SettingsFragment.java
│       │   │               ├── VersionInfoDialogFragment.java
│       │   │               ├── adapter/
│       │   │               │   ├── HasId.kt
│       │   │               │   ├── NewsListRecyclerAdapter.java
│       │   │               │   ├── ProgressBarWebChromeClient.kt
│       │   │               │   ├── ProgressViewHolder.kt
│       │   │               │   ├── RecyclerItemClickListener.kt
│       │   │               │   ├── RssItemCardViewHolder.kt
│       │   │               │   ├── RssItemFullTextViewHolder.kt
│       │   │               │   ├── RssItemHeadlineThumbnailViewHolder.kt
│       │   │               │   ├── RssItemHeadlineViewHolder.kt
│       │   │               │   ├── RssItemTextViewHolder.kt
│       │   │               │   ├── RssItemThumbnailViewHolder.kt
│       │   │               │   ├── RssItemViewHolder.java
│       │   │               │   └── RssItemWebViewHolder.kt
│       │   │               ├── async_tasks/
│       │   │               │   ├── DownloadChangelogTask.java
│       │   │               │   ├── DownloadImageHandler.java
│       │   │               │   └── RssItemToHtmlTask.java
│       │   │               ├── authentication/
│       │   │               │   ├── AccountGeneral.java
│       │   │               │   ├── OwnCloudAccountAuthenticator.java
│       │   │               │   └── OwnCloudSyncAdapter.java
│       │   │               ├── chrometabs/
│       │   │               │   └── KeepAliveService.kt
│       │   │               ├── database/
│       │   │               │   ├── DatabaseConnectionOrm.java
│       │   │               │   ├── DatabaseHelperOrm.java
│       │   │               │   ├── generator/
│       │   │               │   │   ├── DatabaseOrmGenerator.java
│       │   │               │   │   ├── LastestVersion.java
│       │   │               │   │   └── SchemaVersion.java
│       │   │               │   └── model/
│       │   │               │       ├── CurrentRssItemView.java
│       │   │               │       ├── CurrentRssItemViewDao.java
│       │   │               │       ├── DaoMaster.java
│       │   │               │       ├── DaoSession.java
│       │   │               │       ├── Feed.java
│       │   │               │       ├── FeedDao.java
│       │   │               │       ├── Folder.java
│       │   │               │       ├── FolderDao.java
│       │   │               │       ├── RssItem.java
│       │   │               │       └── RssItemDao.java
│       │   │               ├── di/
│       │   │               │   ├── ApiModule.java
│       │   │               │   ├── ApiProvider.java
│       │   │               │   └── AppComponent.java
│       │   │               ├── events/
│       │   │               │   └── podcast/
│       │   │               │       ├── CollapsePodcastView.java
│       │   │               │       ├── ExitPlayback.java
│       │   │               │       ├── ExpandPodcastView.java
│       │   │               │       ├── NewPodcastPlaybackListener.java
│       │   │               │       ├── PodcastCompletedEvent.java
│       │   │               │       ├── PodcastFeedClicked.kt
│       │   │               │       ├── RegisterVideoOutput.java
│       │   │               │       ├── SeekPodcast.java
│       │   │               │       ├── SpeedPodcast.java
│       │   │               │       ├── StartDownloadPodcast.kt
│       │   │               │       ├── TogglePlayerStateEvent.java
│       │   │               │       └── WindPodcast.java
│       │   │               ├── helper/
│       │   │               │   ├── AppCompatPreferenceActivity.java
│       │   │               │   ├── AsyncTaskHelper.java
│       │   │               │   ├── AutoResizeTextView.java
│       │   │               │   ├── ColorHelper.java
│       │   │               │   ├── DatabaseUtils.kt
│       │   │               │   ├── DateTimeFormatter.java
│       │   │               │   ├── FavIconHandler.java
│       │   │               │   ├── FavIconUtils.java
│       │   │               │   ├── ForegroundListener.kt
│       │   │               │   ├── GsonConfig.java
│       │   │               │   ├── ImageDownloadFinished.java
│       │   │               │   ├── ImageHandler.java
│       │   │               │   ├── NetworkConnection.java
│       │   │               │   ├── NewsFileUtils.java
│       │   │               │   ├── NextcloudGlideModule.kt
│       │   │               │   ├── NotificationActionReceiver.java
│       │   │               │   ├── NotificationActionReceiverDownloadWebPage.java
│       │   │               │   ├── OpmlXmlParser.java
│       │   │               │   ├── PostDelayHandler.java
│       │   │               │   ├── Search.java
│       │   │               │   ├── StopWatch.java
│       │   │               │   ├── ThemeChooser.java
│       │   │               │   ├── ThemeUtils.java
│       │   │               │   └── URLConnectionReader.kt
│       │   │               ├── interfaces/
│       │   │               │   ├── ExpListTextClicked.java
│       │   │               │   └── IPlayPausePodcastClicked.java
│       │   │               ├── model/
│       │   │               │   ├── AbstractItem.java
│       │   │               │   ├── ConcreteFeedItem.java
│       │   │               │   ├── CurrentRssViewDataHolder.java
│       │   │               │   ├── FolderSubscribtionItem.java
│       │   │               │   ├── MediaItem.java
│       │   │               │   ├── NextcloudNewsVersion.java
│       │   │               │   ├── NextcloudStatus.java
│       │   │               │   ├── OcsUser.java
│       │   │               │   ├── PodcastFeedItem.java
│       │   │               │   ├── PodcastItem.java
│       │   │               │   ├── TTSItem.java
│       │   │               │   └── Tuple.java
│       │   │               ├── notification/
│       │   │               │   └── NextcloudNotificationManager.java
│       │   │               ├── providers/
│       │   │               │   └── OwnCloudSyncProvider.kt
│       │   │               ├── reader/
│       │   │               │   ├── FeedItemTags.java
│       │   │               │   ├── InsertIntoDatabase.java
│       │   │               │   ├── OnAsyncTaskCompletedListener.java
│       │   │               │   └── nextcloud/
│       │   │               │       ├── IHandleJsonObject.java
│       │   │               │       ├── InsertRssItemIntoDatabase.java
│       │   │               │       ├── ItemIds.java
│       │   │               │       ├── ItemMap.java
│       │   │               │       ├── ItemStateSync.java
│       │   │               │       ├── NewsAPI.java
│       │   │               │       ├── NextcloudNewsDeserializer.java
│       │   │               │       ├── NextcloudServerDeserializer.java
│       │   │               │       ├── OcsAPI.java
│       │   │               │       ├── RssItemObservable.java
│       │   │               │       └── Types.java
│       │   │               ├── services/
│       │   │               │   ├── DownloadImagesService.java
│       │   │               │   ├── DownloadWebPageService.java
│       │   │               │   ├── OwnCloudAuthenticatorService.kt
│       │   │               │   ├── OwnCloudSyncService.java
│       │   │               │   ├── PodcastDownloadService.java
│       │   │               │   ├── PodcastPlaybackService.java
│       │   │               │   ├── SyncItemStateService.java
│       │   │               │   ├── events/
│       │   │               │   │   ├── StopWebArchiveDownloadEvent.kt
│       │   │               │   │   ├── SyncFailedEvent.kt
│       │   │               │   │   ├── SyncFinishedEvent.kt
│       │   │               │   │   └── SyncStartedEvent.kt
│       │   │               │   └── podcast/
│       │   │               │       ├── MediaPlayerPlaybackService.java
│       │   │               │       ├── PlaybackService.java
│       │   │               │       └── TTSPlaybackService.java
│       │   │               ├── ssl/
│       │   │               │   ├── MTMDecision.java
│       │   │               │   ├── MemorizingDialogFragment.java
│       │   │               │   ├── MemorizingTrustManager.java
│       │   │               │   ├── OkHttpSSLClient.java
│       │   │               │   └── TLSSocketFactory.kt
│       │   │               ├── view/
│       │   │               │   ├── AnimatingProgressBar.java
│       │   │               │   ├── ChangeLogFileListView.kt
│       │   │               │   ├── PodcastNotification.java
│       │   │               │   └── PodcastSlidingUpPanelLayout.java
│       │   │               └── widget/
│       │   │                   ├── WidgetNewsViewsFactory.java
│       │   │                   ├── WidgetProvider.java
│       │   │                   └── WidgetService.kt
│       │   └── res/
│       │       ├── anim/
│       │       │   ├── all_read_success.xml
│       │       │   ├── slide_in_left.xml
│       │       │   ├── slide_in_right.xml
│       │       │   ├── slide_out_left.xml
│       │       │   └── slide_out_right.xml
│       │       ├── color/
│       │       │   ├── options_menu_item.xml
│       │       │   └── options_menu_item_night.xml
│       │       ├── drawable/
│       │       │   ├── background_with_shadow.xml
│       │       │   ├── checkbox_background_holo_dark.xml
│       │       │   ├── cursor.xml
│       │       │   ├── custom_progress.xml
│       │       │   ├── fa_all_read_target.xml
│       │       │   ├── fa_all_read_target_success.xml
│       │       │   ├── fa_bg.xml
│       │       │   ├── feed_icon.xml
│       │       │   ├── ic_action_delete_24.xml
│       │       │   ├── ic_action_delete_24_theme_aware.xml
│       │       │   ├── ic_action_download_24.xml
│       │       │   ├── ic_action_expand_less_24.xml
│       │       │   ├── ic_action_open_in_browser_24.xml
│       │       │   ├── ic_action_open_in_browser_24_theme_aware.xml
│       │       │   ├── ic_action_pause_24.xml
│       │       │   ├── ic_add_black_24dp.xml
│       │       │   ├── ic_baseline_account_circle_24.xml
│       │       │   ├── ic_baseline_create_new_folder_24_black.xml
│       │       │   ├── ic_baseline_folder_24.xml
│       │       │   ├── ic_baseline_play_arrow_24.xml
│       │       │   ├── ic_baseline_play_arrow_24_theme_aware.xml
│       │       │   ├── ic_checkbox_black.xml
│       │       │   ├── ic_checkbox_outline_black.xml
│       │       │   ├── ic_checkbox_outline_theme_aware.xml
│       │       │   ├── ic_checkbox_outline_white.xml
│       │       │   ├── ic_checkbox_theme_aware.xml
│       │       │   ├── ic_checkbox_white.xml
│       │       │   ├── ic_done_all.xml
│       │       │   ├── ic_forward_30_24.xml
│       │       │   ├── ic_launcher_background.xml
│       │       │   ├── ic_launcher_foreground.xml
│       │       │   ├── ic_replay_10_24.xml
│       │       │   ├── ic_search_24dp_theme_aware.xml
│       │       │   ├── ic_settings_black_24dp.xml
│       │       │   ├── ic_share_theme_aware.xml
│       │       │   ├── ic_share_white.xml
│       │       │   ├── ic_slow_motion_video_24.xml
│       │       │   ├── ic_star_24_theme_aware.xml
│       │       │   ├── ic_star_black_24dp.xml
│       │       │   ├── ic_star_border_24dp_theme_aware.xml
│       │       │   ├── ic_star_white_24.xml
│       │       │   ├── ic_visibility_24.xml
│       │       │   ├── incognito.xml
│       │       │   ├── rounded_rectangle.xml
│       │       │   ├── shadow.xml
│       │       │   ├── swipe_markasread.xml
│       │       │   ├── swipe_openinbrowser.xml
│       │       │   ├── swipe_setstarred.xml
│       │       │   ├── swipe_share.xml
│       │       │   └── widget_background.xml
│       │       ├── layout/
│       │       │   ├── activity_login_dialog.xml
│       │       │   ├── activity_new_feed.xml
│       │       │   ├── activity_news_detail.xml
│       │       │   ├── activity_newsreader.xml
│       │       │   ├── activity_pip_video_playback.xml
│       │       │   ├── activity_settings.xml
│       │       │   ├── dialog_list_folder.xml
│       │       │   ├── dialog_version_info.xml
│       │       │   ├── empty_content_view.xml
│       │       │   ├── fragment_dialog_add_folder.xml
│       │       │   ├── fragment_dialog_feedoptions.xml
│       │       │   ├── fragment_dialog_folderoptions.xml
│       │       │   ├── fragment_dialog_image.xml
│       │       │   ├── fragment_dialog_listviewitem.xml
│       │       │   ├── fragment_dialog_opml_import.xml
│       │       │   ├── fragment_news_detail.xml
│       │       │   ├── fragment_newsreader_detail.xml
│       │       │   ├── fragment_newsreader_list.xml
│       │       │   ├── fragment_newsreader_list_footer.xml
│       │       │   ├── fragment_podcast.xml
│       │       │   ├── podcast_feed_row.xml
│       │       │   ├── podcast_row.xml
│       │       │   ├── progressbar_item.xml
│       │       │   ├── subscription_detail_list_item_card_view.xml
│       │       │   ├── subscription_detail_list_item_headline.xml
│       │       │   ├── subscription_detail_list_item_headline_thumbnail.xml
│       │       │   ├── subscription_detail_list_item_podcast_wrapper.xml
│       │       │   ├── subscription_detail_list_item_text.xml
│       │       │   ├── subscription_detail_list_item_thumbnail.xml
│       │       │   ├── subscription_detail_list_item_web_layout.xml
│       │       │   ├── subscription_list_item.xml
│       │       │   ├── subscription_list_sub_item.xml
│       │       │   ├── toolbar_layout.xml
│       │       │   ├── widget_fastactions_detailview.xml
│       │       │   ├── widget_item.xml
│       │       │   └── widget_layout.xml
│       │       ├── layout-sw600dp-land/
│       │       │   └── activity_newsreader.xml
│       │       ├── menu/
│       │       │   ├── list_footer_menu.xml
│       │       │   ├── news_detail.xml
│       │       │   └── news_reader.xml
│       │       ├── mipmap-anydpi-v26/
│       │       │   ├── ic_launcher.xml
│       │       │   └── ic_launcher_round.xml
│       │       ├── values/
│       │       │   ├── attrs.xml
│       │       │   ├── booleans.xml
│       │       │   ├── colors.xml
│       │       │   ├── config.xml
│       │       │   ├── dimens.xml
│       │       │   ├── integers.xml
│       │       │   ├── isrighttoleft.xml
│       │       │   ├── strings.xml
│       │       │   ├── styles.xml
│       │       │   └── themes.xml
│       │       ├── values-ar/
│       │       │   └── strings.xml
│       │       ├── values-ast/
│       │       │   └── strings.xml
│       │       ├── values-bg-rBG/
│       │       │   └── strings.xml
│       │       ├── values-ca/
│       │       │   └── strings.xml
│       │       ├── values-cs-rCZ/
│       │       │   └── strings.xml
│       │       ├── values-da/
│       │       │   └── strings.xml
│       │       ├── values-de/
│       │       │   └── strings.xml
│       │       ├── values-el/
│       │       │   └── strings.xml
│       │       ├── values-en-rGB/
│       │       │   └── strings.xml
│       │       ├── values-es/
│       │       │   └── strings.xml
│       │       ├── values-es-rCL/
│       │       │   └── strings.xml
│       │       ├── values-es-rCO/
│       │       │   └── strings.xml
│       │       ├── values-es-rCR/
│       │       │   └── strings.xml
│       │       ├── values-es-rDO/
│       │       │   └── strings.xml
│       │       ├── values-es-rEC/
│       │       │   └── strings.xml
│       │       ├── values-es-rGT/
│       │       │   └── strings.xml
│       │       ├── values-es-rHN/
│       │       │   └── strings.xml
│       │       ├── values-es-rMX/
│       │       │   └── strings.xml
│       │       ├── values-es-rNI/
│       │       │   └── strings.xml
│       │       ├── values-es-rPA/
│       │       │   └── strings.xml
│       │       ├── values-es-rPE/
│       │       │   └── strings.xml
│       │       ├── values-es-rPR/
│       │       │   └── strings.xml
│       │       ├── values-es-rPY/
│       │       │   └── strings.xml
│       │       ├── values-es-rSV/
│       │       │   └── strings.xml
│       │       ├── values-es-rUS/
│       │       │   └── strings.xml
│       │       ├── values-es-rUY/
│       │       │   └── strings.xml
│       │       ├── values-et-rEE/
│       │       │   └── strings.xml
│       │       ├── values-eu/
│       │       │   └── strings.xml
│       │       ├── values-fa/
│       │       │   └── strings.xml
│       │       ├── values-fi-rFI/
│       │       │   └── strings.xml
│       │       ├── values-fr/
│       │       │   └── strings.xml
│       │       ├── values-ga/
│       │       │   └── strings.xml
│       │       ├── values-gl/
│       │       │   └── strings.xml
│       │       ├── values-he/
│       │       │   └── strings.xml
│       │       ├── values-hr/
│       │       │   └── strings.xml
│       │       ├── values-hu-rHU/
│       │       │   └── strings.xml
│       │       ├── values-id/
│       │       │   └── strings.xml
│       │       ├── values-is/
│       │       │   └── strings.xml
│       │       ├── values-it/
│       │       │   └── strings.xml
│       │       ├── values-ja-rJP/
│       │       │   └── strings.xml
│       │       ├── values-ka-rGE/
│       │       │   └── strings.xml
│       │       ├── values-ko/
│       │       │   └── strings.xml
│       │       ├── values-large/
│       │       │   ├── refs.xml
│       │       │   └── styles.xml
│       │       ├── values-ldrtl/
│       │       │   └── isrighttoleft.xml
│       │       ├── values-lo/
│       │       │   └── strings.xml
│       │       ├── values-lt-rLT/
│       │       │   └── strings.xml
│       │       ├── values-nb-rNO/
│       │       │   └── strings.xml
│       │       ├── values-night/
│       │       │   ├── booleans.xml
│       │       │   └── colors.xml
│       │       ├── values-nl/
│       │       │   └── strings.xml
│       │       ├── values-oc/
│       │       │   └── strings.xml
│       │       ├── values-pl/
│       │       │   └── strings.xml
│       │       ├── values-pt-rBR/
│       │       │   └── strings.xml
│       │       ├── values-pt-rPT/
│       │       │   └── strings.xml
│       │       ├── values-ro/
│       │       │   └── strings.xml
│       │       ├── values-ru/
│       │       │   └── strings.xml
│       │       ├── values-sc/
│       │       │   └── strings.xml
│       │       ├── values-sk-rSK/
│       │       │   └── strings.xml
│       │       ├── values-sl/
│       │       │   └── strings.xml
│       │       ├── values-sq/
│       │       │   └── strings.xml
│       │       ├── values-sr/
│       │       │   └── strings.xml
│       │       ├── values-sr-rSP/
│       │       │   └── strings.xml
│       │       ├── values-sv/
│       │       │   └── strings.xml
│       │       ├── values-sw/
│       │       │   └── strings.xml
│       │       ├── values-sw600dp/
│       │       │   └── config.xml
│       │       ├── values-sw720dp-land/
│       │       │   └── dimens.xml
│       │       ├── values-th-rTH/
│       │       │   └── strings.xml
│       │       ├── values-tr/
│       │       │   └── strings.xml
│       │       ├── values-ug/
│       │       │   └── strings.xml
│       │       ├── values-uk/
│       │       │   └── strings.xml
│       │       ├── values-v23/
│       │       │   └── themes.xml
│       │       ├── values-v27/
│       │       │   └── themes.xml
│       │       ├── values-vi/
│       │       │   └── strings.xml
│       │       ├── values-w820dp/
│       │       │   └── dimens.xml
│       │       ├── values-zh-rCN/
│       │       │   └── strings.xml
│       │       ├── values-zh-rHK/
│       │       │   └── strings.xml
│       │       ├── values-zh-rTW/
│       │       │   └── strings.xml
│       │       └── xml/
│       │           ├── account_preferences.xml
│       │           ├── authenticator.xml
│       │           ├── automotive_app_desc.xml
│       │           ├── file_provider_paths.xml
│       │           ├── pref_about.xml
│       │           ├── pref_data_sync.xml
│       │           ├── pref_display.xml
│       │           ├── pref_general.xml
│       │           ├── syncadapter.xml
│       │           └── widget_info.xml
│       └── test/
│           ├── java/
│           │   └── de/
│           │       └── luhmer/
│           │           └── owncloudnewsreader/
│           │               ├── asynctasks/
│           │               │   └── RssItemToHtmlTaskTest.kt
│           │               └── junit_tests/
│           │                   ├── ImageHandlerTest.java
│           │                   └── TestDbTest.java
│           └── resources/
│               └── org.robolectric.Config.properties
├── PRIVACY.md
├── README.md
├── Screengrabfile
├── build.gradle
├── config/
│   └── detekt/
│       └── detekt.yml
├── docker-nextcloud-test-instances/
│   ├── .gitignore
│   ├── README.md
│   └── docker-compose.yaml
├── executeScreengrab.sh
├── fastlane/
│   ├── Fastfile
│   ├── README.md
│   └── metadata/
│       └── android/
│           ├── de-DE/
│           │   ├── changelogs/
│           │   │   ├── 166.txt
│           │   │   ├── 167.txt
│           │   │   ├── 168.txt
│           │   │   ├── 170.txt
│           │   │   ├── 171.txt
│           │   │   ├── 172.txt
│           │   │   ├── 173.txt
│           │   │   ├── 174.txt
│           │   │   ├── 175.txt
│           │   │   ├── 176.txt
│           │   │   ├── 177.txt
│           │   │   ├── 178.txt
│           │   │   ├── 179.txt
│           │   │   ├── 180.txt
│           │   │   ├── 181.txt
│           │   │   ├── 182.txt
│           │   │   ├── 183.txt
│           │   │   ├── 184.txt
│           │   │   ├── 185.txt
│           │   │   ├── 186.txt
│           │   │   ├── 189.txt
│           │   │   ├── 190.txt
│           │   │   ├── 191.txt
│           │   │   ├── 192.txt
│           │   │   ├── 193.txt
│           │   │   ├── 194.txt
│           │   │   ├── 195.txt
│           │   │   └── 196.txt
│           │   ├── full_description.txt
│           │   ├── short_description.txt
│           │   ├── title.txt
│           │   └── video.txt
│           └── en-US/
│               ├── changelogs/
│               │   ├── 166.txt
│               │   ├── 167.txt
│               │   ├── 168.txt
│               │   ├── 170.txt
│               │   ├── 171.txt
│               │   ├── 172.txt
│               │   ├── 173.txt
│               │   ├── 174.txt
│               │   ├── 175.txt
│               │   ├── 176.txt
│               │   ├── 177.txt
│               │   ├── 178.txt
│               │   ├── 179.txt
│               │   ├── 180.txt
│               │   ├── 181.txt
│               │   ├── 182.txt
│               │   ├── 183.txt
│               │   ├── 184.txt
│               │   ├── 185.txt
│               │   ├── 186.txt
│               │   ├── 189.txt
│               │   ├── 190.txt
│               │   ├── 191.txt
│               │   ├── 192.txt
│               │   ├── 193.txt
│               │   ├── 194.txt
│               │   ├── 195.txt
│               │   └── 196.txt
│               ├── full_description.txt
│               ├── short_description.txt
│               ├── title.txt
│               └── video.txt
├── gradle/
│   └── wrapper/
│       ├── gradle-wrapper.jar
│       └── gradle-wrapper.properties
├── gradle.properties
├── gradlew
├── gradlew.bat
├── security/
│   └── GHSL-2021-1033_Nextcloud_News_for_Android.md
└── settings.gradle
Download .txt
SYMBOL INDEX (1531 symbols across 143 files)

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/CustomTestRunner.java
  class CustomTestRunner (line 8) | public class CustomTestRunner extends AndroidJUnitRunner {
    method newApplication (line 21) | public Application newApplication(ClassLoader cl, String className, Co...

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/TestApplication.java
  class TestApplication (line 6) | public class TestApplication extends NewsReaderApplication {
    method initDaggerAppComponent (line 8) | @Override

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestApiModule.java
  class TestApiModule (line 25) | public class TestApiModule extends ApiModule {
    method TestApiModule (line 35) | public TestApiModule(Application application) {
    method providesSharedPreferences (line 40) | @Override
    method providesSharedPreferencesFileName (line 87) | @Override
    method providesDatabaseFileName (line 92) | @Override
    method provideAPI (line 111) | @Override
    method copy (line 119) | public static void copy(InputStream in, File dst) throws IOException {

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestApiProvider.java
  class TestApiProvider (line 32) | public class TestApiProvider extends ApiProvider {
    method TestApiProvider (line 45) | TestApiProvider(MemorizingTrustManager mtm, SharedPreferences sp, Cont...
    method initSsoApi (line 49) | @Override
    class NewsTestNetworkRequest (line 66) | public class NewsTestNetworkRequest extends NetworkRequest {
      method NewsTestNetworkRequest (line 68) | NewsTestNetworkRequest(Context context, NextcloudAPI.ApiConnectedLis...
      method connect (line 72) | @Override
      method performNetworkRequest (line 78) | public InputStream performNetworkRequest(NextcloudRequest request, I...
      method performNetworkRequestV2 (line 113) | @Override
      method handleFolders (line 120) | private InputStream handleFolders() {
      method handleCreateFeed (line 127) | private InputStream handleCreateFeed(NextcloudRequest request) throw...
      method handleUser (line 141) | private InputStream handleUser() {
      method stringToInputStream (line 152) | private InputStream stringToInputStream(String data) {

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestComponent.java
  type TestComponent (line 10) | @Singleton
    method inject (line 14) | void inject(NewFeedTests newFeedTest);
    method inject (line 15) | void inject(NightModeTest nightModeTest);
    method inject (line 17) | void inject(NewsReaderListActivityUiTests newsReaderListActivityUiTests);

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/helper/Utils.java
  class Utils (line 12) | public class Utils {
    method initMaterialShowCaseView (line 14) | public static void initMaterialShowCaseView(Context context) {
    method clearFocus (line 23) | public static void clearFocus() {
    method sleep (line 29) | public static void sleep(int millis) {
    method sleep (line 37) | public static void sleep(float seconds) {

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/DownloadWebPageServiceTest.java
  class DownloadWebPageServiceTest (line 12) | @RunWith(AndroidJUnit4.class)

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NewFeedTests.java
  class NewFeedTests (line 43) | @RunWith(MockitoJUnitRunner.class)
    method setUp (line 52) | @Before
    method addNewFeed (line 62) | @Test
    method addExistingFeed (line 83) | @Test
    method addInvalidFeed (line 104) | @Test
    method verifyRequest (line 126) | private void verifyRequest(String feed) throws Exception {

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NewsReaderListActivityUiTests.java
  class NewsReaderListActivityUiTests (line 80) | @RunWith(AndroidJUnit4.class)
    method getActivity (line 95) | private NewsReaderListActivity getActivity() {
    method setUp (line 99) | @Before
    method testPositionAfterOrientationChange_sameActivity (line 112) | @Test
    method testPositionAfterActivityRestart_sameActivity (line 139) | @Test
    method testSyncFinishedRefreshRecycler_sameActivity (line 166) | @Test
    method testSyncFinishedSnackbar_sameActivity (line 171) | @Test
    method searchTest (line 177) | @Test
    method syncTest (line 203) | @Test
    method verifySyncRequested (line 229) | private void verifySyncRequested() throws Exception {
    method checkRecyclerViewFirstItemText (line 245) | private void checkRecyclerViewFirstItemText(String text) {
    method getString (line 249) | private String getString(@IdRes int resId) {
    method atPosition (line 254) | public static Matcher<View> atPosition(final int position, @NonNull fi...
    method syncResultTest (line 275) | private boolean syncResultTest(boolean testFirstPosition) {
    method waitForFragment (line 316) | private Fragment waitForFragment(int id, int timeout) {

FILE: News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NightModeTest.java
  class NightModeTest (line 45) | @RunWith(AndroidJUnit4.class)
    method getActivity (line 63) | private Activity getActivity() {
    method resetSharedPrefs (line 67) | @Before
    method testBackgroundDaylightTheme (line 83) | @Test
    method testOledAutoMode (line 89) | @Test
    method testLightTheme (line 104) | @Test
    method testDarkTheme (line 119) | @Test
    method testDarkOledTheme (line 134) | @Test
    method sleep (line 150) | private void sleep() {
    method navigateUp (line 158) | private void navigateUp() {
    method openSettings (line 162) | private void openSettings() {
    method changeAppTheme (line 166) | private void changeAppTheme(int appThemeText) {
    method switchOled (line 177) | private void switchOled() {
    method isDarkTheme (line 185) | private boolean isDarkTheme() {
    method getPrivateField (line 197) | private Object getPrivateField(String fieldName) {

FILE: News-Android-App/src/androidTest/java/helper/CustomMatchers.java
  class CustomMatchers (line 24) | public class CustomMatchers {
    method withBackgroundColor (line 27) | public static Matcher<View> withBackgroundColor(final int resourceColo...
    method getColor (line 61) | private static int getColor(Context context, int color) {
    method getBackgroundColor (line 69) | public static int getBackgroundColor(Context context, View v, int defa...
    method withBackground (line 79) | public static Matcher<View> withBackground(final int resourceId) {
    method withCompoundDrawable (line 99) | public static Matcher<View> withCompoundDrawable(final int resourceId) {
    method withImageDrawable (line 118) | public static Matcher<View> withImageDrawable(final int resourceId) {
    method sameBitmap (line 132) | private static boolean sameBitmap(Context context, Drawable drawable, ...

FILE: News-Android-App/src/androidTest/java/helper/OrientationChangeAction.java
  class OrientationChangeAction (line 46) | public class OrientationChangeAction implements ViewAction {
    method OrientationChangeAction (line 51) | private OrientationChangeAction(int orientation, Activity activity) {
    method getConstraints (line 56) | @Override
    method getDescription (line 61) | @Override
    method perform (line 66) | @Override
    method orientationLandscape (line 77) | public static ViewAction orientationLandscape(Activity activity) {
    method orientationPortrait (line 81) | public static ViewAction orientationPortrait(Activity activity) {

FILE: News-Android-App/src/androidTest/java/helper/RecyclerViewAssertions.java
  class RecyclerViewAssertions (line 10) | public class RecyclerViewAssertions implements ViewAssertion {
    method RecyclerViewAssertions (line 14) | public RecyclerViewAssertions(int expectedPos) {
    method check (line 18) | @Override

FILE: News-Android-App/src/androidTest/java/screengrab/ScreenshotTest.java
  class ScreenshotTest (line 32) | @RunWith(JUnit4.class)
    method setUp (line 53) | @Before
    method testTakeScreenshots (line 68) | @Test
    method testAudioPodcast (line 117) | @Test
    method testVideoPodcast (line 162) | @Test
    method openFeed (line 205) | private void openFeed(int groupPosition, int childPosition) {
    method openDrawer (line 209) | private void openDrawer() {
    method closeDrawer (line 215) | private void closeDrawer() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/AddFolderDialogFragment.java
  class AddFolderDialogFragment (line 29) | public class AddFolderDialogFragment extends DialogFragment {
    method newInstance (line 35) | static AddFolderDialogFragment newInstance() {
    method onCreate (line 45) | @Override
    method onCreateView (line 54) | @Override
    method setActivity (line 114) | public void setActivity(Activity parentActivity) {
    method showProgress (line 119) | public void showProgress(final boolean show) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/Constants.java
  class Constants (line 8) | public class Constants {
    method isNextCloud (line 23) | protected static boolean isNextCloud(SharedPreferences prefs) {
    method extractVersionNumberFromString (line 32) | private static int[] extractVersionNumberFromString(String appVersion) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/DirectoryChooserActivity.java
  class DirectoryChooserActivity (line 9) | public class DirectoryChooserActivity extends net.rdrei.android.dirchoos...
    method onCreate (line 11) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/FolderOptionsDialogFragment.java
  class FolderOptionsDialogFragment (line 36) | public class FolderOptionsDialogFragment extends DialogFragment {
    method newInstance (line 49) | static FolderOptionsDialogFragment newInstance(long folderId, String d...
    method onCreate (line 61) | @Override
    method onCreateView (line 79) | @Override
    method setActivity (line 105) | public void setActivity(Activity parentActivity) {
    method showProgress (line 110) | public void showProgress(final boolean show) {
    method showRenameFolderView (line 123) | private void showRenameFolderView(final long folderId, final String fo...
    method showRemoveFolderView (line 176) | private void showRemoveFolderView(final long folderId) {
    type MenuAction (line 232) | interface MenuAction {
      method execute (line 233) | void execute();

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/BlockingExpandableListView.java
  class BlockingExpandableListView (line 7) | public class BlockingExpandableListView extends ExpandableListView {
    method BlockingExpandableListView (line 11) | public BlockingExpandableListView(Context context, AttributeSet attrs) {
    method setBlockLayoutChildren (line 15) | public void setBlockLayoutChildren(boolean block) {
    method layoutChildren (line 19) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java
  class PodcastArrayAdapter (line 21) | public class PodcastArrayAdapter extends ArrayAdapter<PodcastItem> {
    method PodcastArrayAdapter (line 26) | public PodcastArrayAdapter(Context context, PodcastItem[] values) {
    method getView (line 32) | @SuppressLint("SetTextI18n")
    method playPodcast (line 105) | private void playPodcast() {
    class ViewHolder (line 110) | static class ViewHolder {
      method ViewHolder (line 113) | public ViewHolder(@NonNull PodcastRowBinding binding) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastFeedArrayAdapter.java
  class PodcastFeedArrayAdapter (line 19) | public class PodcastFeedArrayAdapter extends ArrayAdapter<PodcastFeedIte...
    method PodcastFeedArrayAdapter (line 24) | public PodcastFeedArrayAdapter(Context context, PodcastFeedItem[] valu...
    method getView (line 30) | @Override
    class ViewHolder (line 59) | static class ViewHolder {
      method ViewHolder (line 62) | public ViewHolder(@NonNull PodcastFeedRowBinding binding) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/SubscriptionExpandableListAdapter.java
  class SubscriptionExpandableListAdapter (line 64) | public class SubscriptionExpandableListAdapter extends BaseExpandableLis...
    type SPECIAL_FOLDERS (line 87) | public enum SPECIAL_FOLDERS  {
      method SPECIAL_FOLDERS (line 91) | SPECIAL_FOLDERS(int id) {
      method getValue (line 95) | public int getValue() {
      method getValueString (line 100) | public String getValueString() {
      method toString (line 104) | @Override
    method SubscriptionExpandableListAdapter (line 110) | public SubscriptionExpandableListAdapter(Context mContext, DatabaseCon...
    method getChild (line 128) | @Override
    method getChildId (line 134) | @Override
    method getChildView (line 139) | @Override
    class ChildHolder (line 179) | static class ChildHolder {
      method ChildHolder (line 182) | public ChildHolder(@NonNull SubscriptionListSubItemBinding binding) {
    method getChildrenCount (line 187) | @Override
    method getGroup (line 193) | @Override
    method getGroupCount (line 198) | @Override
    method getGroupId (line 203) | @Override
    type GroupViewType (line 208) | private enum GroupViewType { FOLDER, FEED }
    method getGroupType (line 210) | @Override
    method getGroupTypeCount (line 220) | @Override
    method getGroupView (line 225) | @Override
    class GroupHolder (line 348) | static class GroupHolder {
      method GroupHolder (line 351) | public GroupHolder(@NonNull SubscriptionListItemBinding binding) {
    method hasStableIds (line 357) | @Override
    method isChildSelectable (line 362) | @Override
    method notifyDataSetChangedAsync (line 367) | public void notifyDataSetChangedAsync() {
    method loadCategoriesAndItemsFromDatabase (line 374) | public Tuple<ArrayList<AbstractItem>, SparseArray<ArrayList<ConcreteFe...
    method ReloadAdapterAsync (line 434) | public void ReloadAdapterAsync() {
    method notifyCountDataSetChanged (line 438) | @SuppressLint("NewApi") // wrongly reports setSelectionFromTop is only...
    class ReloadAdapterAsyncTask (line 463) | private class ReloadAdapterAsyncTask extends AsyncTask<Void, Void, Tup...
      method doInBackground (line 465) | @Override
      method onPostExecute (line 475) | @Override
    class NotifyDataSetChangedAsyncTask (line 486) | private class NotifyDataSetChangedAsyncTask extends AsyncTask<Void, Vo...
      method doInBackground (line 493) | @Override
      method onPostExecute (line 512) | @Override
    method setHandlerListener (line 555) | public void setHandlerListener(ExpListTextClicked listener)
    method fireListTextClicked (line 559) | protected void fireListTextClicked(long idFeed, boolean isFolder, Long...
    method fireListTextLongClicked (line 564) | protected void fireListTextLongClicked(long idFeed, boolean isFolder, ...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/LoginDialogActivity.java
  class LoginDialogActivity (line 82) | public class LoginDialogActivity extends AppCompatActivity {
    method beforeTextChanged (line 89) | @Override
    method onTextChanged (line 94) | @Override
    method afterTextChanged (line 99) | @Override
    method onClick (line 119) | @Override
    method onStart (line 138) | @Override
    method onStop (line 144) | @Override
    method startSingleSignOn (line 150) | public void startSingleSignOn() {
    method startManualLogin (line 168) | public void startManualLogin() {
    method manualLogin (line 172) | public void manualLogin() {
    method onCreate (line 176) | @Override
    method onBackPressed (line 208) | @Override
    method buildPendingDialogWhileLoggingIn (line 219) | private ProgressDialog buildPendingDialogWhileLoggingIn() {
    method loginSingleSignOn (line 225) | private void loginSingleSignOn() {
    method attemptLogin (line 261) | @SuppressLint({"SetTextI18n"})
    method resetDatabase (line 350) | private void resetDatabase() {
    method finishLogin (line 356) | private void finishLogin(final ProgressDialog dialogLogin) {
    method ShowAlertDialog (line 416) | public static void ShowAlertDialog(String title, String text, Activity...
    method onActivityResult (line 432) | @Override
    method onRequestPermissionsResult (line 445) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java
  class NewFeedActivity (line 75) | public class NewFeedActivity extends AppCompatActivity {
    method convertStreamToString (line 90) | @NonNull
    method getStringFromFile (line 102) | public static String getStringFromFile(String filePath) throws Excepti...
    method onCreate (line 111) | @Override
    method showAlertDialog (line 178) | private void showAlertDialog(String text) {
    method validatePathOrThrowException (line 187) | private void validatePathOrThrowException(String path) {
    method openFilePicker (line 198) | private void openFilePicker() {
    method btnAddFeedClick (line 202) | public void btnAddFeedClick() {
    method importOpml (line 211) | public void importOpml() {
    method onActivityResult (line 215) | @Override
    method exportOpml (line 249) | public void exportOpml() {
    method exportOpmlFile (line 267) | private void exportOpmlFile() {
    method onRequestPermissionsResult (line 303) | @Override
    method truncate (line 320) | public static String truncate(String str, int len) {
    method isUrlValid (line 328) | private boolean isUrlValid(String url) {
    method attemptAddNewFeed (line 343) | public void attemptAddNewFeed() {
    method onOptionsItemSelected (line 423) | @Override
    method showProgress (line 438) | public void showProgress(final boolean show) {
    class ImportOpmlSubscriptionsTask (line 460) | public class ImportOpmlSubscriptionsTask extends AsyncTask<Void, List<...
      method ImportOpmlSubscriptionsTask (line 467) | ImportOpmlSubscriptionsTask(String urlToFile, Context context) {
      method onPreExecute (line 472) | @Override
      method doInBackground (line 486) | @Override
      method onProgressUpdate (line 562) | @Override
      method onPostExecute (line 578) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java
  class NewsDetailActivity (line 72) | public class NewsDetailActivity extends PodcastFragmentActivity {
    method onCreate (line 108) | @Override
    method onResume (line 219) | @Override
    method getPodcastSlidingUpPanelLayout (line 226) | @Override
    method toggleIncognitoMode (line 231) | private void toggleIncognitoMode() {
    method initFastActionBar (line 251) | private void initFastActionBar() {
    method onDestroy (line 294) | @Override
    method onPageSelected (line 302) | @Override
    method onPageScrolled (line 307) | @Override public void onPageScrolled(int arg0, float arg1, int arg2) { }
    method onPageScrollStateChanged (line 309) | @Override public void onPageScrollStateChanged(int arg0) { }
    method onKeyDown (line 313) | @Override
    method onKeyUp (line 342) | @Override
    method pageChanged (line 351) | private void pageChanged(int position) {
    method getNewsDetailFragmentAtPosition (line 378) | private NewsDetailFragment getNewsDetailFragmentAtPosition(int positio...
    method resumeVideoPlayersOnCurrentPage (line 384) | private void resumeVideoPlayersOnCurrentPage() {
    method stopVideoOnCurrentPage (line 392) | private void stopVideoOnCurrentPage() {
    method updateActionBarIcons (line 399) | public void updateActionBarIcons() {
    method onBackPressed (line 441) | @Override
    method onCreateOptionsMenu (line 447) | @Override
    method onOptionsItemSelected (line 494) | @Override
    method openInBrowser (line 533) | private void openInBrowser(int currentPosition) {
    method share (line 558) | private void share(int currentPosition) {
    method startTTS (line 586) | private void startTTS(int currentPosition) {
    method markRead (line 599) | private void markRead(int currentPosition) {
    method toggleRssItemStarredState (line 607) | public void toggleRssItemStarredState() {
    method isChromeDefaultBrowser (line 618) | private boolean isChromeDefaultBrowser() {
    method markItemAsReadOrUnread (line 626) | private void markItemAsReadOrUnread(RssItem item, boolean read) {
    method finish (line 634) | @Override
    method isIncognitoEnabled (line 642) | public boolean isIncognitoEnabled() {
    method setIncognitoEnabled (line 646) | public void setIncognitoEnabled(boolean enabled) {
    method initIncognitoMode (line 651) | public void initIncognitoMode() {
    method setLightStatusBar (line 694) | private void setLightStatusBar(@NonNull View view) {
    method clearLightStatusBar (line 702) | public static void clearLightStatusBar(@NonNull View view) {
    class SectionsPagerAdapter (line 716) | public class SectionsPagerAdapter extends FragmentStatePagerAdapter {
      method SectionsPagerAdapter (line 720) | public SectionsPagerAdapter(FragmentManager fm) {
      method getItem (line 732) | @NonNull
      method destroyItem (line 752) | @Override
      method getCount (line 759) | @Override
      method getPageTitle (line 765) | @Override
    method setBackgroundColorOfViewPager (line 771) | protected void setBackgroundColorOfViewPager(int backgroundColor) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java
  class NewsDetailFragment (line 69) | public class NewsDetailFragment extends Fragment implements RssItemToHtm...
    method NewsDetailFragment (line 88) | public NewsDetailFragment() { }
    method getSectionNumber (line 90) | public int getSectionNumber() {
    method onCreate (line 94) | @Override
    method onResume (line 104) | @Override
    method onPause (line 112) | @Override
    method onDestroy (line 118) | @Override
    method pauseCurrentPage (line 125) | public void pauseCurrentPage() {
    method resumeCurrentPage (line 130) | public void resumeCurrentPage() {
    method canNavigateBack (line 141) | public boolean canNavigateBack() {
    method navigateBack (line 150) | public void navigateBack() {
    method onCreateView (line 159) | @Override
    method setWebViewBackgroundColor (line 193) | private void setWebViewBackgroundColor(NewsDetailActivity ndActivity) {
    method syncIncognitoState (line 199) | protected void syncIncognitoState() {
    method startLoadRssItemToWebViewTask (line 251) | protected void startLoadRssItemToWebViewTask(NewsDetailActivity ndActi...
    method onRssItemParsed (line 264) | @Override
    method setSoftwareRenderModeForWebView (line 279) | private void setSoftwareRenderModeForWebView(String htmlPage, WebView ...
    method applyWebSettings (line 298) | private void applyWebSettings() {
    method init_webView (line 321) | @SuppressLint("SetJavaScriptEnabled")
    method addBottomPaddingForFastActions (line 392) | private void addBottomPaddingForFastActions(WebView view) {
    method loadURL (line 403) | public void loadURL(String url) {
    method onCreateContextMenu (line 440) | public void onCreateContextMenu(@NonNull ContextMenu menu, @NonNull Vi...
    method isLastPageRssItem (line 539) | private boolean isLastPageRssItem() {
    method isCurrentPageRssItem (line 549) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailImageDialogFragment.java
  class NewsDetailImageDialogFragment (line 54) | public class NewsDetailImageDialogFragment extends DialogFragment {
    type TYPE (line 57) | public enum TYPE { IMAGE, URL }
    method newInstanceImage (line 72) | static NewsDetailImageDialogFragment newInstanceImage(String dialogTit...
    method newInstanceUrl (line 89) | protected static NewsDetailImageDialogFragment newInstanceUrl(String d...
    method onCreate (line 101) | @Override
    method onStart (line 167) | @Override
    method showDownloadShowcase (line 173) | private void showDownloadShowcase() {
    method onCreateView (line 192) | @Override
    method onDestroyView (line 250) | @Override
    method copyToClipboard (line 257) | private void copyToClipboard(String label, String text) {
    method shareImage (line 265) | private void shareImage() {
    method shareLink (line 274) | private void shareLink() {
    method openLinkInBrowser (line 284) | private void openLinkInBrowser(URL url) {
    method getMimeTypeOfUri (line 291) | public static String getMimeTypeOfUri(String path) throws IOException {
    method downloadImage (line 306) | private void downloadImage(URL url) {
    method storeCachedImage (line 330) | private void storeCachedImage(String path) {
    method getFileNameFromPath (line 349) | private String getFileNameFromPath(String path, boolean web) {
    method haveStoragePermission (line 371) | public boolean haveStoragePermission() {
    method changeDownloadDir (line 389) | private void changeDownloadDir() {
    method setNewDownloadDir (line 402) | private void setNewDownloadDir(String path) {
    method getDownloadDir (line 412) | private Uri getDownloadDir(String filename) {
    method onActivityResult (line 424) | public void onActivityResult(int requestCode, int resultCode, Intent d...
    method unregisterImageDownloadReceiver (line 435) | private void unregisterImageDownloadReceiver() {
    method registerImageDownloadReceiver (line 442) | private void registerImageDownloadReceiver() {
    method isExternalStorageWritable (line 490) | public boolean isExternalStorageWritable() {
    type MenuAction (line 496) | interface MenuAction {
      method execute (line 497) | void execute();
    type MenuActionLongClick (line 499) | interface MenuActionLongClick extends MenuAction {
      method executeLongClick (line 500) | void executeLongClick();

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderApplication.java
  class NewsReaderApplication (line 10) | public class NewsReaderApplication extends Application {
    method onCreate (line 14) | @Override
    method initDaggerAppComponent (line 25) | public void initDaggerAppComponent() {
    method getAppComponent (line 37) | public AppComponent getAppComponent() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java
  class NewsReaderDetailFragment (line 95) | public class NewsReaderDetailFragment extends Fragment {
    method NewsReaderDetailFragment (line 131) | public NewsReaderDetailFragment() {
    method onAttach (line 134) | @Override
    method onDetach (line 140) | @Override
    method onNext (line 147) | @Override
    method onError (line 152) | @Override
    method onComplete (line 158) | @Override
    method getSortDirection (line 165) | public static SORT_DIRECTION getSortDirection(SharedPreferences prefs) {
    method getIdFeed (line 172) | public Long getIdFeed() {
    method getIdFolder (line 179) | public Long getIdFolder() {
    method getTitle (line 186) | public String getTitle() {
    method setTitle (line 190) | protected void setTitle(String title) {
    method setData (line 195) | protected void setData(Long idFeed, Long idFolder, String title, boole...
    method onResume (line 209) | @Override
    method updateMenuItemsState (line 228) | protected void updateMenuItemsState() {
    method notifyDataSetChangedOnAdapter (line 235) | protected void notifyDataSetChangedOnAdapter() {
    method refreshCurrentRssView (line 245) | protected void refreshCurrentRssView() {
    method initFastDoneAll (line 266) | protected void initFastDoneAll(View rootView) {
    method updateCurrentRssView (line 279) | public void updateCurrentRssView() {
    method getRecyclerView (line 284) | public RecyclerView getRecyclerView() {
    method getLayoutManager (line 288) | public LinearLayoutManager getLayoutManager() {
    method performSearch (line 292) | protected List<RssItem> performSearch(String searchString) {
    method loadRssItemsIntoView (line 304) | void loadRssItemsIntoView(List<RssItem> rssItems) {
    method onCreateView (line 328) | @Override
    method handleMarkAsReadScrollEvent (line 406) | private void handleMarkAsReadScrollEvent(int firstVisibleItem, int las...
    method onInflate (line 448) | @Override
    method updateSwipeDrawables (line 461) | private void updateSwipeDrawables(boolean forceUpdate) {
    method getLayoutId (line 480) | private int getLayoutId(String action) {
    method onViewStateRestored (line 492) | @Override
    method onSaveInstanceState (line 499) | @Override
    method getFirstVisibleScrollPosition (line 506) | public int getFirstVisibleScrollPosition() {
    class UpdateCurrentRssViewTask (line 511) | private class UpdateCurrentRssViewTask extends AsyncTask<Void, Void, L...
      method onPreExecute (line 513) | @Override
      method doInBackground (line 520) | @Override
      method onPostExecute (line 565) | @Override
    class RecyclerViewOnGestureListener (line 583) | private class RecyclerViewOnGestureListener extends GestureDetector.Si...
      method initEdgeDistance (line 587) | private void initEdgeDistance() {
      method onScroll (line 598) | @Override
    class NewsReaderItemTouchHelperCallback (line 638) | private class NewsReaderItemTouchHelperCallback extends ItemTouchHelpe...
      method NewsReaderItemTouchHelperCallback (line 639) | public NewsReaderItemTouchHelperCallback() {
      method getSwipeThreshold (line 643) | @Override
      method onMove (line 648) | @Override
      method onSwiped (line 653) | @Override
      method onChildDraw (line 694) | @Override
    class FastMarkReadMotionListener (line 730) | private class FastMarkReadMotionListener implements View.OnTouchListen...
      method FastMarkReadMotionListener (line 740) | public FastMarkReadMotionListener(View fabMarkAllAsRead) {
      method onTouch (line 745) | @Override
      method startUserInteractionProcess (line 772) | private void startUserInteractionProcess(View v, MotionEvent event) {
      method moveFAB (line 795) | private void moveFAB(View v, MotionEvent event) {
      method checkLocation (line 808) | private void checkLocation(MotionEvent evt) {
      method stopUserInteractionProcess (line 841) | private void stopUserInteractionProcess(View v) {
      method markAllAsReadForCurrentView (line 874) | private void markAllAsReadForCurrentView() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java
  class NewsReaderListActivity (line 140) | public class NewsReaderListActivity extends PodcastFragmentActivity impl...
    method onPostCreate (line 189) | @Override
    method isUserLoggedIn (line 206) | private boolean isUserLoggedIn() {
    method onPanelSlide (line 211) | @Override
    method onPanelStateChanged (line 215) | @Override
    method handleOnBackPressed (line 233) | @Override
    method onNext (line 245) | @Override
    method onError (line 250) | @Override
    method onComplete (line 255) | @Override
    method onRestoreInstanceState (line 261) | @Override
    method onSaveInstanceState (line 267) | @Override
    method saveInstanceState (line 273) | private void saveInstanceState(Bundle outState) {
    method restoreInstanceState (line 292) | private void restoreInstanceState(Bundle savedInstanceState) {
    method onConfigurationChanged (line 314) | @Override
    method showChangelogIfNecessary (line 322) | void showChangelogIfNecessary() {
    method adjustEdgeSizeOfDrawer (line 337) | private void adjustEdgeSizeOfDrawer() {
    method getEdgeSizeOfDrawer (line 353) | public int getEdgeSizeOfDrawer() {
    method initAccountManager (line 371) | private void initAccountManager() {
    method checkNotificationPermissions (line 407) | public void checkNotificationPermissions() {
    method reloadCountNumbersOfSlidingPaneAdapter (line 416) | public void reloadCountNumbersOfSlidingPaneAdapter() {
    method reloadSidebar (line 426) | public void reloadSidebar() {
    method updateCurrentRssView (line 434) | protected void updateCurrentRssView() {
    method switchToAllUnreadItemsFolder (line 441) | public void switchToAllUnreadItemsFolder() {
    method onEventMainThread (line 445) | @Subscribe(threadMode = ThreadMode.MAIN)
    method onEventMainThread (line 483) | @Subscribe(threadMode = ThreadMode.MAIN)
    method onEventMainThread (line 489) | @Subscribe(threadMode = ThreadMode.MAIN)
    method onCreate (line 496) | @Override
    method onResume (line 586) | @Override
    method getPodcastSlidingUpPanelLayout (line 597) | @Override
    method onRefresh (line 602) | @Override
    method syncFinishedHandler (line 610) | private boolean syncFinishedHandler() {
    method showSnackbarNewItems (line 651) | private void showSnackbarNewItems(int newItemsCount) {
    method onTopItemClicked (line 669) | @Override
    method onChildItemClicked (line 677) | @Override
    method onTopItemLongClicked (line 685) | @Override
    method onUserInfoUpdated (line 690) | @Override
    method onCreateFolderClicked (line 697) | @Override
    method onChildItemLongClicked (line 711) | @Override
    method startDialogFragment (line 716) | private void startDialogFragment(long id, Boolean isFolder) {
    method updateDetailFragmentTitle (line 758) | private void updateDetailFragmentTitle() {
    method UpdateItemList (line 797) | public void UpdateItemList() {
    method showSnackbarNoNewItems (line 808) | private void showSnackbarNoNewItems() {
    method startSync (line 817) | public void startSync()
    method updateButtonLayout (line 844) | public void updateButtonLayout()
    method updateDetailFragment (line 856) | private void updateDetailFragment(long id, Boolean folder, Long option...
    method getMenuItemDownloadMoreItems (line 893) | public MenuItem getMenuItemDownloadMoreItems() {
    method onPrepareOptionsMenu (line 897) | @Override
    method onCreateOptionsMenu (line 905) | @Override
    method syncMenuItemUnreadOnly (line 963) | private void syncMenuItemUnreadOnly() {
    method onOptionsItemSelected (line 969) | @Override
    method makeFABAwareSnackbar (line 1040) | private Snackbar makeFABAwareSnackbar(String text, int duration) {
    method checkAndStartDownloadWebPagesForOfflineReadingPermission (line 1054) | private void checkAndStartDownloadWebPagesForOfflineReadingPermission() {
    method startDownloadWebPagesForOfflineReading (line 1070) | private void startDownloadWebPagesForOfflineReading() {
    method DownloadMoreItems (line 1078) | private void DownloadMoreItems() {
    method downloadMoreItemsForFeed (line 1108) | @SuppressLint("CheckResult")
    method onActivityResult (line 1137) | @Override
    method onRequestPermissionsResult (line 1203) | @Override
    method ensureCorrectTheme (line 1216) | private void ensureCorrectTheme(Intent data) {
    method getSlidingListFragment (line 1231) | @VisibleForTesting
    method getNewsReaderDetailFragment (line 1236) | @VisibleForTesting
    method startLoginActivity (line 1241) | public void startLoginActivity() {
    method resetUiAndStartSync (line 1246) | private void resetUiAndStartSync() {
    method updateListView (line 1252) | private void updateListView() {
    method onClick (line 1256) | @Override
    method openRssItemInDetailedView (line 1295) | private void openRssItemInDetailedView(int position) {
    method openRssItemInCustomTab (line 1303) | private void openRssItemInCustomTab(Uri currentUrl) {
    method openRssItemInExternalBrowser (line 1312) | private void openRssItemInExternalBrowser(Uri currentUrl) {
    method prepareAccountMenuItem (line 1317) | private void prepareAccountMenuItem(MenuItem accountMenuItem) {
    method onLongClick (line 1352) | @Override
    method onQueryTextSubmit (line 1367) | @Override
    method onQueryTextChange (line 1373) | @Override
    method clearSearchViewFocus (line 1390) | public void clearSearchViewFocus() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListDialogFragment.java
  class NewsReaderListDialogFragment (line 37) | public class NewsReaderListDialogFragment extends DialogFragment {
    method newInstance (line 52) | static NewsReaderListDialogFragment newInstance(long feedId, String di...
    method onCreate (line 66) | @Override
    method onCreateView (line 92) | @Override
    method setActivity (line 130) | public void setActivity(Activity parentActivity) {
    method showProgress (line 136) | public void showProgress(final boolean show) {
    method showRenameFeedView (line 149) | private void showRenameFeedView(final long feedId, final String feedNa...
    method showRemoveFeedView (line 202) | private void showRemoveFeedView(final long feedId) {
    method showMoveFeedView (line 241) | private void showMoveFeedView(final long mFeedId) {
    method showOpenSettingsView (line 286) | private void showOpenSettingsView(final long feedId) {
    method showNotificationSettingsView (line 327) | private void showNotificationSettingsView(final long feedId) {
    method setOpenInForFeed (line 360) | private void setOpenInForFeed(Feed feed, Long openIn, Boolean checked) {
    method setNotificationChannelForFeed (line 368) | private void setNotificationChannelForFeed(Feed feed, String channel, ...
    type MenuAction (line 376) | interface MenuAction {
      method execute (line 377) | void execute();

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListFragment.java
  class NewsReaderListFragment (line 81) | public class NewsReaderListFragment extends Fragment implements OnCreate...
    method listViewNotifyDataSetChanged (line 99) | public void listViewNotifyDataSetChanged() {
    method reloadAdapter (line 103) | public void reloadAdapter() {
    method setRefreshing (line 107) | public void setRefreshing(boolean isRefreshing) {
    type Callbacks (line 124) | public interface Callbacks {
      method onChildItemClicked (line 128) | void onChildItemClicked(long idFeed, Long optional_folder_id);
      method onTopItemClicked (line 129) | void onTopItemClicked(long idFeed, boolean isFolder, Long onTopItemC...
      method onChildItemLongClicked (line 130) | void onChildItemLongClicked(long idFeed);
      method onTopItemLongClicked (line 131) | void onTopItemLongClicked(long idFeed, boolean isFolder);
      method onUserInfoUpdated (line 132) | void onUserInfoUpdated(OcsUser userInfo);
      method onCreateFolderClicked (line 133) | void onCreateFolderClicked();
    method NewsReaderListFragment (line 140) | public NewsReaderListFragment() {
    method onCreate (line 143) | @Override
    method onCreateView (line 149) | @Override
    method onAttach (line 190) | @Override
    method onDetach (line 203) | @Override
    method bindNavigationMenu (line 219) | private void bindNavigationMenu(View parent, LayoutInflater inflater) {
    method onTextClicked (line 251) | @Override
    method onTextLongClicked (line 256) | @Override
    method onChildClick (line 267) | @Override
    method startAsyncTaskGetUserInfo (line 300) | public void startAsyncTaskGetUserInfo() {
    method bindUserInfoToUI (line 348) | public void bindUserInfoToUI() {
    method fromString (line 374) | public static Object fromString(String s) throws IOException,
    method toString (line 385) | public static String toString(Serializable o) throws IOException {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderOPMLImportDialogFragment.java
  class NewsReaderOPMLImportDialogFragment (line 19) | public class NewsReaderOPMLImportDialogFragment extends DialogFragment {
    method newInstance (line 28) | static NewsReaderOPMLImportDialogFragment newInstance(boolean showOkBu...
    method onCreate (line 38) | @Override
    method onCreateView (line 46) | @Override
    method updateProgress (line 64) | public void updateProgress(final int current, final int max) {
    method setMessage (line 78) | public void setMessage(final String message) {
    method setVisibilityOkButton (line 88) | public void setVisibilityOkButton(final boolean show) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PiPVideoPlaybackActivity.java
  class PiPVideoPlaybackActivity (line 33) | public class PiPVideoPlaybackActivity extends AppCompatActivity {
    method onCreate (line 42) | @Override
    method onPictureInPictureModeChanged (line 67) | @Override
    method onStart (line 118) | @Override
    method onStop (line 135) | @Override
    method unregisterVideoViews (line 159) | public void unregisterVideoViews() {
    method onBackPressed (line 172) | @Override
    method onConnected (line 188) | @Override
    method onMetadataChanged (line 212) | @Override
    method onPlaybackStateChanged (line 218) | @Override
    method handleMetadataChange (line 224) | private void handleMetadataChange(MediaMetadataCompat metadata) {
    method createSurfaceView (line 258) | private SurfaceView createSurfaceView() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java
  class PodcastFragment (line 72) | public class PodcastFragment extends Fragment {
    method newInstance (line 93) | public static PodcastFragment newInstance() {
    method onCreate (line 97) | @Override
    method onResume (line 104) | @Override
    method onPause (line 111) | @Override
    method onStart (line 117) | @Override
    method onStop (line 128) | @Override
    method onAttach (line 141) | @Override
    method onDetach (line 147) | @Override
    method tryOpeningPictureinPictureMode (line 153) | protected void tryOpeningPictureinPictureMode() {
    method onEvent (line 168) | @Subscribe
    method onEvent (line 173) | @Subscribe
    method playPause (line 197) | protected void playPause() {
    method playPauseSlider (line 201) | protected void playPauseSlider() {
    method windForward (line 205) | protected void windForward() {
    method windBack (line 211) | protected void windBack() {
    method openSpeedMenu (line 215) | protected void openSpeedMenu() {
    method onPanelSlide (line 220) | @Override
    method onPanelStateChanged (line 224) | @Override
    method onCreateView (line 236) | @Override
    method onProgressChanged (line 285) | @Override
    method onStartTrackingTouch (line 295) | @Override
    method onStopTrackingTouch (line 301) | @Override
    method showPlaybackSpeedPicker (line 312) | private void showPlaybackSpeedPicker() {
    method onMetadataChanged (line 369) | @Override
    method onPlaybackStateChanged (line 375) | @Override
    method displayMetadata (line 383) | private void displayMetadata(MediaMetadataCompat metadata) {
    method displayPlaybackState (line 424) | private void displayPlaybackState(PlaybackStateCompat stateCompat) {
    method updateProgressBar (line 454) | private void updateProgressBar(@PlaybackStateCompat.State int state) {
    method onConnected (line 491) | @Override
    method onConnectionSuspended (line 517) | @Override
    method onConnectionFailed (line 523) | @Override
    method getCurrentPlaybackSpeed (line 532) | public void getCurrentPlaybackSpeed(final OnPlaybackSpeedCallback call...
    method onSessionReady (line 565) | @Override
    method onSessionDestroyed (line 571) | @Override
    method onSessionEvent (line 577) | @Override
    type OnPlaybackSpeedCallback (line 585) | public interface OnPlaybackSpeedCallback {
      method currentPlaybackReceived (line 586) | void currentPlaybackReceived(float playbackSpeed);

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragmentActivity.java
  class PodcastFragmentActivity (line 56) | public abstract class PodcastFragmentActivity extends AppCompatActivity ...
    method onCreate (line 68) | @Override
    method onPostCreate (line 87) | @Override
    method onStart (line 97) | @Override
    method onStop (line 104) | @Override
    method onUserLeaveHint (line 112) | @Override
    method onWindowFocusChanged (line 118) | @Override
    method onResume (line 134) | @Override
    method onPause (line 141) | @Override
    method getSlidingLayout (line 198) | public PodcastSlidingUpPanelLayout getSlidingLayout() {
    method handlePodcastBackPressed (line 202) | public boolean handlePodcastBackPressed() {
    method updatePodcastView (line 210) | protected void updatePodcastView() {
    method onEvent (line 227) | @Subscribe
    method onEvent (line 233) | @Subscribe
    method onEvent (line 239) | @Subscribe
    method collapsePodcastView (line 246) | private void collapsePodcastView() {
    method expandPodcastView (line 250) | private void expandPodcastView() {
    method onEvent (line 254) | @Subscribe
    method pxToDp (line 261) | public static int pxToDp(int px) {
    method dipToPx (line 265) | private float dipToPx(@SuppressWarnings("SameParameterValue") float di...
    method openMediaItem (line 269) | @VisibleForTesting
    method openPodcast (line 295) | @Override
    method removePodcastMedia (line 324) | public void removePodcastMedia(final RssItem rssItem, final Consumer<B...
    method pausePodcast (line 352) | @Override
    method openYoutube (line 358) | private void openYoutube(PodcastItem podcastItem) {
    method getVideoIdFromYoutubeUrl (line 374) | public String getVideoIdFromYoutubeUrl(String url){
    method getPodcastSlidingUpPanelLayout (line 385) | protected abstract PodcastSlidingUpPanelLayout getPodcastSlidingUpPane...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java
  class SettingsActivity (line 48) | public class SettingsActivity extends AppCompatActivity {
    method onCreate (line 111) | @Override
    method onPostCreate (line 128) | @Override
    method setupActionBar (line 138) | private void setupActionBar() {
    method onOptionsItemSelected (line 146) | @Override
    method onStart (line 155) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsFragment.java
  class SettingsFragment (line 73) | public class SettingsFragment extends PreferenceFragmentCompat {
    method onCreatePreferences (line 79) | @Override
    method bindPreferenceSummaryToValue (line 181) | private void bindPreferenceSummaryToValue(Preference preference) {
    method bindPreferenceBooleanToValue (line 193) | private void bindPreferenceBooleanToValue(Preference preference) {
    method bindDisplayPreferences (line 221) | private void bindDisplayPreferences(PreferenceFragmentCompat prefFrag)
    method bindGeneralPreferences (line 231) | private void bindGeneralPreferences(DialogPreference.TargetFragment pr...
    method migrateSyncIntervalValue (line 257) | private void migrateSyncIntervalValue() {
    method bindDataSyncPreferences (line 272) | private void bindDataSyncPreferences(final PreferenceFragmentCompat pr...
    method bindAboutPreferences (line 299) | private void bindAboutPreferences(final PreferenceFragmentCompat prefF...
    method bindPodcastPreferences (line 316) | private void bindPodcastPreferences(PreferenceFragmentCompat prefFrag)
    method checkForUnsycedChangesInDatabaseAndResetDatabase (line 322) | public void checkForUnsycedChangesInDatabaseAndResetDatabase(final Con...
    method openBugReport (line 348) | private void openBugReport() {
    method setAccountSyncInterval (line 393) | public static void setAccountSyncInterval(Context context, int minutes) {
    class ResetDatabaseAsyncTask (line 415) | public static class ResetDatabaseAsyncTask extends AsyncTask<Void, Voi...
      method ResetDatabaseAsyncTask (line 420) | public ResetDatabaseAsyncTask(Context context) {
      method onPreExecute (line 424) | @Override
      method doInBackground (line 436) | @Override
      method onPostExecute (line 447) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/VersionInfoDialogFragment.java
  class VersionInfoDialogFragment (line 47) | public class VersionInfoDialogFragment extends DialogFragment {
    method onCreateDialog (line 49) | @Override
    method onStart (line 78) | @Override
    method getVersionString (line 89) | public static String getVersionString(Activity activity) {
    method loadChangeLog (line 107) | private void loadChangeLog(ChangeLogFileListView clListView, final Pro...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java
  class NewsListRecyclerAdapter (line 44) | public class NewsListRecyclerAdapter extends RecyclerView.Adapter<Recycl...
    method NewsListRecyclerAdapter (line 72) | public NewsListRecyclerAdapter(FragmentActivity activity, RecyclerView...
    method getTotalItemCount (line 127) | public int getTotalItemCount() {
    method getCachedPages (line 134) | public int getCachedPages() {
    method setTotalItemCount (line 138) | public void setTotalItemCount(int totalItemCount) {
    method setCachedPages (line 144) | public void setCachedPages(int cachedPages) {
    method onEvent (line 169) | @Subscribe
    method onCreateViewHolder (line 177) | @NonNull
    method onBindViewHolder (line 279) | @Override
    method onViewDetachedFromWindow (line 302) | @Override
    method onViewAttachedToWindow (line 309) | @Override
    method changeReadStateOfItem (line 316) | public void changeReadStateOfItem(RssItemViewHolder viewHolder, boolea...
    method toggleReadStateOfItem (line 331) | public void toggleReadStateOfItem(RssItemViewHolder viewHolder) {
    method toggleStarredStateOfItem (line 337) | public void toggleStarredStateOfItem(RssItemViewHolder viewHolder) {
    method getItemViewType (line 352) | @Override
    method getItemCount (line 357) | @Override
    method getItemId (line 362) | @Override
    method refreshAdapterData (line 373) | private List<RssItem> refreshAdapterData() {
    method updateAdapterData (line 384) | public void updateAdapterData(List<RssItem> rssItems) {
    type IOnRefreshFinished (line 402) | public interface IOnRefreshFinished {
      method OnRefreshFinished (line 403) | void OnRefreshFinished();
    method refreshAdapterDataAsync (line 406) | public void refreshAdapterDataAsync(IOnRefreshFinished listener) {
    class RefreshDataAsyncTask (line 410) | private class RefreshDataAsyncTask extends AsyncTask<Void, Void, List<...
      method RefreshDataAsyncTask (line 414) | public RefreshDataAsyncTask(IOnRefreshFinished listener) {
      method onPreExecute (line 418) | @Override
      method doInBackground (line 425) | @Override
      method onPostExecute (line 438) | @Override
    class LoadMoreItemsAsyncTask (line 452) | private class LoadMoreItemsAsyncTask extends AsyncTask<Void, Void, Lis...
      method doInBackground (line 453) | @Override
      method onPostExecute (line 466) | @Override
    class ReloadAdapterAsyncTask (line 481) | private class ReloadAdapterAsyncTask extends AsyncTask<Void, Void, Cur...
      method doInBackground (line 483) | @Override
      method onPostExecute (line 499) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemViewHolder.java
  class RssItemViewHolder (line 42) | public abstract class RssItemViewHolder<T extends ViewBinding> extends R...
    method RssItemViewHolder (line 62) | RssItemViewHolder(
    method extractInitialFontSize (line 89) | private void extractInitialFontSize(TextView tv) {
    method scaleTextSize (line 102) | private void scaleTextSize(TextView tv, int initialTvSize, boolean hal...
    method scaleTextLines (line 125) | private static int scaleTextLines(SharedPreferences prefs) {
    method getImageViewFavIcon (line 133) | abstract protected ImageView getImageViewFavIcon();
    method getStar (line 135) | abstract protected ImageView getStar();
    method getPlayPausePodcastButton (line 137) | abstract protected ImageView getPlayPausePodcastButton();
    method getColorFeed (line 139) | abstract protected View getColorFeed();
    method getTextViewTitle (line 141) | abstract protected TextView getTextViewTitle();
    method getTextViewSummary (line 143) | abstract protected TextView getTextViewSummary();
    method getTextViewBody (line 145) | abstract protected TextView getTextViewBody();
    method getTextViewItemDate (line 147) | abstract protected TextView getTextViewItemDate();
    method getPlayPausePodcastWrapper (line 149) | abstract protected FrameLayout getPlayPausePodcastWrapper();
    method getPodcastDownloadProgress (line 151) | abstract protected ProgressBar getPodcastDownloadProgress();
    method bind (line 153) | @CallSuper
    method onClick (line 258) | @Override
    method setClickListener (line 263) | public void setClickListener(RecyclerItemClickListener clickListener) {
    method onLongClick (line 267) | @Override
    method setStarred (line 272) | public void setStarred(boolean isStarred) {
    method getRssItem (line 284) | public RssItem getRssItem() {
    method shouldStayUnread (line 288) | @SuppressWarnings("BooleanMethodIsAlwaysInverted")
    method setStayUnread (line 293) | public void setStayUnread(boolean shouldStayUnread) {
    method getBodyText (line 297) | private String getBodyText(String body, boolean limitLength) {
    method setFeedColor (line 319) | private void setFeedColor(int color) {
    method setReadState (line 325) | public void setReadState(boolean isRead) {
    method isPlaying (line 340) | public boolean isPlaying() {
    method setPlaying (line 344) | public void setPlaying(boolean playing) {
    method setDownloadPodcastProgressbar (line 356) | public void setDownloadPodcastProgressbar() {
    method onEvent (line 367) | @Subscribe

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadChangelogTask.java
  class DownloadChangelogTask (line 26) | public class DownloadChangelogTask extends AsyncTask<Void, Void, String> {
    method DownloadChangelogTask (line 44) | public DownloadChangelogTask(Context context,
    method doInBackground (line 53) | @Override
    method onPostExecute (line 68) | @Override
    method downloadChangelog (line 84) | private ArrayList<String> downloadChangelog() throws IOException {
    method convertToXML (line 112) | private String convertToXML(ArrayList<String> changelogArr) {
    method saveToTempFile (line 145) | private String saveToTempFile(String content, @SuppressWarnings("SameP...
    type Listener (line 156) | public interface Listener {
      method onSuccess (line 161) | void onSuccess();
      method onError (line 166) | void onError(IOException e);

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadImageHandler.java
  class DownloadImageHandler (line 35) | public class DownloadImageHandler {
    method DownloadImageHandler (line 41) | public DownloadImageHandler(String imageUrl) {
    method preloadSync (line 49) | public void preloadSync(RequestManager glide) {
    method NotifyDownloadFinished (line 64) | private void NotifyDownloadFinished(Bitmap bitmap) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/RssItemToHtmlTask.java
  class RssItemToHtmlTask (line 40) | public class RssItemToHtmlTask extends AsyncTask<Void, Void, String> {
    type Listener (line 60) | public interface Listener {
      method onRssItemParsed (line 65) | void onRssItemParsed(String htmlPage);
    method RssItemToHtmlTask (line 69) | public RssItemToHtmlTask(Context context, RssItem rssItem, Listener li...
    method doInBackground (line 78) | @Override
    method onPostExecute (line 83) | @Override
    method getHtmlPage (line 89) | public static String getHtmlPage(RequestManager glide, RssItem rssItem...
    method getHtmlPage (line 98) | public static String getHtmlPage(RequestManager glide, RssItem rssItem...
    method removeLineBreaksFromHtml (line 176) | @VisibleForTesting()
    method getSelectedTheme (line 206) | private static String getSelectedTheme() {
    method buildHeader (line 220) | private static String buildHeader(RssItem rssItem, String body_id, Str...
    method getCachedFavIcon (line 259) | private static String getCachedFavIcon(RequestManager glide, String fa...
    method getDescriptionWithCachedImages (line 302) | private static String getDescriptionWithCachedImages(RequestManager gl...
    method onLoadFailed (line 334) | @Override
    method onResourceReady (line 349) | @Override
    method replacePatternInText (line 357) | private static String replacePatternInText(Pattern pattern, String tex...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/AccountGeneral.java
  class AccountGeneral (line 7) | public class AccountGeneral {
    method getAccountType (line 27) | public static String getAccountType(Context context) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudAccountAuthenticator.java
  class OwnCloudAccountAuthenticator (line 18) | public class OwnCloudAccountAuthenticator extends AbstractAccountAuthent...
    method OwnCloudAccountAuthenticator (line 23) | public OwnCloudAccountAuthenticator(Context context) {
    method addAccount (line 30) | @Override
    method getAuthToken (line 45) | @Override
    method getAuthTokenLabel (line 109) | @Override
    method hasFeatures (line 119) | @Override
    method editProperties (line 126) | @Override
    method confirmCredentials (line 131) | @Override
    method updateCredentials (line 136) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudSyncAdapter.java
  class OwnCloudSyncAdapter (line 50) | public class OwnCloudSyncAdapter extends AbstractThreadedSyncAdapter {
    method OwnCloudSyncAdapter (line 59) | public OwnCloudSyncAdapter(Context context, boolean autoInitialize) {
    method onPerformSync (line 67) | @Override
    class NextcloudSyncResult (line 96) | private static class NextcloudSyncResult {
      method NextcloudSyncResult (line 101) | NextcloudSyncResult(List<Folder> folders, List<Feed> feeds, Boolean ...
    method sync (line 109) | private void sync() {
    method syncRssItems (line 184) | private void syncRssItems(final DatabaseConnectionOrm dbConn) {
    method throwException (line 222) | private void throwException(Throwable ex) {
    method updateNotification (line 232) | private void updateNotification() {
    method startFaviconDownload (line 246) | private void startFaviconDownload() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java
  class DatabaseConnectionOrm (line 49) | public class DatabaseConnectionOrm {
    type SORT_DIRECTION (line 68) | public enum SORT_DIRECTION { asc, desc }
    method resetDatabase (line 78) | public void resetDatabase() {
    method DatabaseConnectionOrm (line 85) | public DatabaseConnectionOrm(Context context) {
    method deleteOldAndInsertNewFolders (line 93) | public void deleteOldAndInsertNewFolders (final Folder... folder) {
    method deleteOldAndInsertNewFolders (line 100) | public void deleteOldAndInsertNewFolders (final Iterable<Folder> folde...
    method insertNewFolders (line 107) | public void insertNewFolders(final Iterable<Folder> folder) {
    method insertNewFeed (line 111) | public void insertNewFeed (Iterable<Feed> feeds) {
    method insertNewItems (line 115) | public void insertNewItems(Iterable<RssItem> items) {
    method getListOfFolders (line 119) | public List<Folder> getListOfFolders() {
    method getListOfFeeds (line 135) | public List<Feed> getListOfFeeds() {
    method getListOfFeedsWithUnreadItems (line 139) | public List<Feed> getListOfFeedsWithUnreadItems() {
    method getFolderById (line 153) | public Folder getFolderById(long folderId) {
    method getFolderByLabel (line 157) | public Folder getFolderByLabel(String label) {
    method getFeedById (line 161) | public Feed getFeedById(long feedId) {
    method getListOfFeedsWithFolders (line 165) | public List<Feed> getListOfFeedsWithFolders() {
    method getListOfFeedsWithoutFolders (line 169) | public List<Feed> getListOfFeedsWithoutFolders(boolean onlyWithUnreadR...
    method getAllFeedsWithUnreadRssItems (line 178) | public List<Feed> getAllFeedsWithUnreadRssItems() {
    method getAllFeedsWithUnreadRssItemsForFolder (line 184) | public List<Feed> getAllFeedsWithUnreadRssItemsForFolder(long folderId) {
    method getAllFeedsWithStarredRssItems (line 188) | public List<Feed> getAllFeedsWithStarredRssItems() {
    method getAllFeedsWithDownloadedPodcasts (line 193) | public List<Feed> getAllFeedsWithDownloadedPodcasts(Context context) {
    method getListOfFeedsWithAudioPodcasts (line 200) | public List<PodcastFeedItem> getListOfFeedsWithAudioPodcasts() {
    method getListOfAudioPodcastsForFeed (line 217) | public List<PodcastItem> getListOfAudioPodcastsForFeed(Context context...
    method areThereAnyUnsavedChangesInDatabase (line 230) | public boolean areThereAnyUnsavedChangesInDatabase() {
    method updateFeed (line 238) | public void updateFeed(Feed feed) {
    method getLowestRssItemIdUnread (line 243) | public long getLowestRssItemIdUnread() {
    method getLowestRssItemIdByFeed (line 251) | public RssItem getLowestRssItemIdByFeed(long idFeed) {
    method getRssItemById (line 255) | public RssItem getRssItemById(long rssItemId) {
    method change_readUnreadStateOfItem (line 265) | public void change_readUnreadStateOfItem(List<String> itemIds, boolean...
    method changeStarrUnstarrStateOfItem (line 277) | public void changeStarrUnstarrStateOfItem(List<String> itemIds, boolea...
    method updateIsReadOfRssItem (line 284) | public void updateIsReadOfRssItem(String ITEM_ID, Boolean isRead) {
    method updateIsStarredOfRssItem (line 293) | public void updateIsStarredOfRssItem(String ITEM_ID, Boolean isStarred) {
    method markAllItemsAsReadForCurrentView (line 302) | public int markAllItemsAsReadForCurrentView() {
    method getRssItemsIdsFromList (line 339) | public List<String> getRssItemsIdsFromList(List<RssItem> rssItemList) {
    method getAllNewReadRssItems (line 347) | public List<RssItem> getAllNewReadRssItems() {
    method getAllNewUnreadRssItems (line 351) | public List<RssItem> getAllNewUnreadRssItems() {
    method getAllNewStarredRssItems (line 355) | public List<RssItem> getAllNewStarredRssItems() {
    method getAllNewUnstarredRssItems (line 359) | public List<RssItem> getAllNewUnstarredRssItems() {
    method getAllUnreadRssItemsForWidget (line 363) | public LazyList<RssItem> getAllUnreadRssItemsForWidget() {
    method getNotificationGroups (line 367) | public Set<String> getNotificationGroups() {
    method getAllUnreadRssItemsForNotificationGroup (line 377) | public QueryBuilder<RssItem> getAllUnreadRssItemsForNotificationGroup(...
    method markAllItemsAsRead (line 394) | public void markAllItemsAsRead() {
    method getAllUnreadRssItemsForDownloadWebPageService (line 405) | public LazyList<RssItem> getAllUnreadRssItemsForDownloadWebPageService...
    method getAllItemsWithIdHigher (line 409) | public LazyList<RssItem> getAllItemsWithIdHigher(long id) {
    method updateRssItem (line 417) | public void updateRssItem(RssItem rssItem) {
    class UpdateRssItemAsyncTask (line 422) | class UpdateRssItemAsyncTask extends AsyncTask<Void, Void, Void> {
      method UpdateRssItemAsyncTask (line 426) | UpdateRssItemAsyncTask(RssItem rssItem) {
      method doInBackground (line 430) | @Override
    method removeFeedById (line 455) | public void removeFeedById(final long feedId) {
    method renameFeedById (line 466) | public void renameFeedById(long feedId, String newTitle) {
    method getUrlsToFavIcons (line 472) | public SparseArray<String> getUrlsToFavIcons() {
    method getCurrentRssItemViewCount (line 481) | public long getCurrentRssItemViewCount() {
    method getCurrentRssItemView (line 486) | public List<RssItem> getCurrentRssItemView(int page) {
    method getAllRssItems (line 496) | public LazyList<RssItem> getAllRssItems() {
    method removeFolderById (line 508) | public void removeFolderById(final long folderId) {
    method renameFolderById (line 512) | public void renameFolderById(long folderId, String newLabel) {
    method ParsePodcastItemFromRssItem (line 527) | public static PodcastItem ParsePodcastItemFromRssItem(Context context,...
    method getAllItemsIdsForFeedSQL (line 553) | public String getAllItemsIdsForFeedSQL(long idFeed, boolean onlyUnread...
    method getAllItemsIdsForFeedSQLFilteredByTitle (line 569) | public String getAllItemsIdsForFeedSQLFilteredByTitle(final long feedI...
    method getAllItemsIdsForFeedSQLFilteredByBodySQL (line 576) | public String getAllItemsIdsForFeedSQLFilteredByBodySQL(final long fee...
    method getAllItemsIdsForFeedSQLFilteredByTitleAndBodySQL (line 583) | public String getAllItemsIdsForFeedSQLFilteredByTitleAndBodySQL(final ...
    method getSearchSQLForColumn (line 592) | private String getSearchSQLForColumn(String column, String searchStrin...
    method getLowestItemIdByFolder (line 596) | public Long getLowestItemIdByFolder(Long id_folder) {
    method getAllItemsIdsForFolderSQL (line 607) | public String getAllItemsIdsForFolderSQL(long ID_FOLDER, boolean onlyU...
    method getAllItemsIdsForFolderSQLSearch (line 637) | public String getAllItemsIdsForFolderSQLSearch(long ID_FOLDER, SORT_DI...
    method insertIntoRssCurrentViewTable (line 660) | public void insertIntoRssCurrentViewTable(String SQL_SELECT) {
    method getUnreadItemsCountForSpecificFolder (line 681) | public String getUnreadItemsCountForSpecificFolder(SPECIAL_FOLDERS spe...
    method getUnreadItemCountFeedFolder (line 699) | public SparseArray<String>[] getUnreadItemCountFeedFolder() {
    method getStarredItemCount (line 748) | public SparseArray<String> getStarredItemCount() {
    method getDownloadedPodcastsCount (line 757) | public int getDownloadedPodcastsCount(Context context) {
    method clearDatabaseOverSize (line 768) | public void clearDatabaseOverSize()
    method getLastModified (line 807) | public long getLastModified()
    method getLowestItemId (line 816) | public long getLowestItemId(boolean onlyStarred)
    method getHighestItemId (line 830) | public long getHighestItemId()
    method getLongValueBySQL (line 846) | public long getLongValueBySQL(String buildSQL)
    method getIntegerSparseArrayFromSQL (line 859) | public SparseArray<Integer> getIntegerSparseArrayFromSQL(String buildS...
    method getStringSparseArrayFromSQL (line 878) | public SparseArray<String> getStringSparseArrayFromSQL(String buildSQL...
    method join (line 898) | public static String join(Collection<?> col, String delim) {
    method clearSessionCache (line 910) | public void clearSessionCache() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseHelperOrm.java
  class DatabaseHelperOrm (line 30) | public class DatabaseHelperOrm {
    method getDaoSession (line 33) | public static DaoSession getDaoSession(Context context, String DATABAS...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/DatabaseOrmGenerator.java
  class DatabaseOrmGenerator (line 10) | public class DatabaseOrmGenerator {
    method main (line 19) | public static void main(String[] args) throws Exception {
    method validateSchemas (line 41) | public static void validateSchemas(List<SchemaVersion> versions)

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/LastestVersion.java
  class LastestVersion (line 7) | public class LastestVersion extends SchemaVersion {
    method LastestVersion (line 14) | public LastestVersion(boolean current) {
    method addEntitysToSchema (line 21) | @SuppressWarnings("unused") // id properties (folderId, etc.) need to ...
    method getVersionNumber (line 89) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/SchemaVersion.java
  class SchemaVersion (line 5) | public abstract class SchemaVersion {
    method SchemaVersion (line 18) | public SchemaVersion(boolean current) {
    method getSchema (line 32) | protected Schema getSchema() {
    method isCurrent (line 39) | public boolean isCurrent() {
    method getVersionNumber (line 46) | public abstract int getVersionNumber();

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemView.java
  class CurrentRssItemView (line 10) | public class CurrentRssItemView {
    method CurrentRssItemView (line 18) | public CurrentRssItemView() {
    method CurrentRssItemView (line 21) | public CurrentRssItemView(long id) {
    method CurrentRssItemView (line 25) | public CurrentRssItemView(long id, long rssItemId) {
    method getId (line 30) | public long getId() {
    method setId (line 34) | public void setId(long id) {
    method getRssItemId (line 38) | public long getRssItemId() {
    method setRssItemId (line 42) | public void setRssItemId(long rssItemId) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemViewDao.java
  class CurrentRssItemViewDao (line 15) | public class CurrentRssItemViewDao extends AbstractDao<CurrentRssItemVie...
    method dropTable (line 22) | public static void dropTable(SQLiteDatabase db, boolean ifExists) {
    method CurrentRssItemViewDao (line 28) | public CurrentRssItemViewDao(DaoConfig config) {
    method CurrentRssItemViewDao (line 32) | public CurrentRssItemViewDao(DaoConfig config, DaoSession daoSession) {
    method createTable (line 37) | public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
    method bindValues (line 47) | @Override
    method readEntity (line 57) | @Override
    method readKey (line 69) | @Override
    class Properties (line 78) | public static class Properties {
    method readEntity (line 86) | @Override
    method updateKeyAfterInsert (line 95) | @Override
    method getKey (line 104) | @Override
    method isEntityUpdateable (line 116) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoMaster.java
  class DaoMaster (line 16) | public class DaoMaster extends AbstractDaoMaster {
    method createAllTables (line 20) | public static void createAllTables(SQLiteDatabase db, boolean ifNotExi...
    method dropAllTables (line 28) | public static void dropAllTables(SQLiteDatabase db, boolean ifExists) {
    class OpenHelper (line 35) | public static abstract class OpenHelper extends SQLiteOpenHelper {
      method OpenHelper (line 37) | public OpenHelper(Context context, String name, CursorFactory factor...
      method onCreate (line 41) | @Override
    class DevOpenHelper (line 49) | public static class DevOpenHelper extends OpenHelper {
      method DevOpenHelper (line 50) | public DevOpenHelper(Context context, String name, CursorFactory fac...
      method onUpgrade (line 54) | @Override
    method DaoMaster (line 62) | public DaoMaster(SQLiteDatabase db) {
    method newSession (line 70) | public DaoSession newSession() {
    method newSession (line 74) | public DaoSession newSession(IdentityScopeType type) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoSession.java
  class DaoSession (line 19) | public class DaoSession extends AbstractDaoSession {
    method DaoSession (line 31) | public DaoSession(SQLiteDatabase db, IdentityScopeType type, Map<Class...
    method clear (line 58) | public void clear() {
    method getFolderDao (line 65) | public FolderDao getFolderDao() {
    method getFeedDao (line 69) | public FeedDao getFeedDao() {
    method getRssItemDao (line 73) | public RssItemDao getRssItemDao() {
    method getCurrentRssItemViewDao (line 77) | public CurrentRssItemViewDao getCurrentRssItemViewDao() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/Feed.java
  class Feed (line 14) | public class Feed {
    method Feed (line 40) | public Feed() {
    method Feed (line 43) | public Feed(long id) {
    method Feed (line 47) | public Feed(long id, Long folderId, String feedTitle, String faviconUr...
    method __setDaoSession (line 59) | public void __setDaoSession(DaoSession daoSession) {
    method getId (line 64) | public long getId() {
    method setId (line 68) | public void setId(long id) {
    method getFolderId (line 72) | public Long getFolderId() {
    method setFolderId (line 76) | public void setFolderId(Long folderId) {
    method getFeedTitle (line 81) | public String getFeedTitle() {
    method setFeedTitle (line 86) | public void setFeedTitle(String feedTitle) {
    method getFaviconUrl (line 90) | public String getFaviconUrl() {
    method setFaviconUrl (line 94) | public void setFaviconUrl(String faviconUrl) {
    method getLink (line 98) | public String getLink() {
    method setLink (line 102) | public void setLink(String link) {
    method getAvgColour (line 106) | public String getAvgColour() {
    method setAvgColour (line 110) | public void setAvgColour(String avgColour) {
    method getNotificationChannel (line 114) | public String getNotificationChannel() {
    method setNotificationChannel (line 118) | public void setNotificationChannel(String notificationChannel) {
    method getOpenIn (line 122) | public Long getOpenIn() {
    method setOpenIn (line 126) | public void setOpenIn(Long openIn) {
    method getFolder (line 133) | public Folder getFolder() {
    method setFolder (line 149) | public void setFolder(Folder folder) {
    method getRssItemList (line 158) | public List<RssItem> getRssItemList() {
    method resetRssItemList (line 175) | public synchronized void resetRssItemList() {
    method delete (line 180) | public void delete() {
    method update (line 188) | public void update() {
    method refresh (line 196) | public void refresh() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FeedDao.java
  class FeedDao (line 21) | public class FeedDao extends AbstractDao<Feed, Long> {
    method createTable (line 26) | public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
    method FeedDao (line 46) | public FeedDao(DaoConfig config) {
    method FeedDao (line 50) | public FeedDao(DaoConfig config, DaoSession daoSession) {
    method dropTable (line 58) | public static void dropTable(SQLiteDatabase db, boolean ifExists) {
    method bindValues (line 66) | @Override
    method attachEntity (line 103) | @Override
    method readKey (line 112) | @Override
    method readEntity (line 120) | @Override
    method readEntity (line 138) | @Override
    method loadCurrentDeep (line 150) | protected Feed loadCurrentDeep(Cursor cursor, boolean lock) {
    method updateKeyAfterInsert (line 163) | @Override
    method getKey (line 172) | @Override
    method isEntityUpdateable (line 182) | @Override
    method _queryFolder_FeedList (line 188) | public List<Feed> _queryFolder_FeedList(Long folderId) {
    method getSelectDeep (line 203) | protected String getSelectDeep() {
    method loadAllDeepFromCursor (line 218) | public List<Feed> loadAllDeepFromCursor(Cursor cursor) {
    method loadDeep (line 240) | public Feed loadDeep(Long key) {
    class Properties (line 271) | public static class Properties {
    method loadDeepAllAndCloseCursor (line 282) | protected List<Feed> loadDeepAllAndCloseCursor(Cursor cursor) {
    method queryDeep (line 292) | public List<Feed> queryDeep(String where, String... selectionArg) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/Folder.java
  class Folder (line 14) | public class Folder {
    method Folder (line 31) | public Folder() {
    method Folder (line 34) | public Folder(long id) {
    method Folder (line 38) | public Folder(long id, String label) {
    method __setDaoSession (line 44) | public void __setDaoSession(DaoSession daoSession) {
    method getId (line 49) | public long getId() {
    method setId (line 53) | public void setId(long id) {
    method getLabel (line 58) | public String getLabel() {
    method setLabel (line 63) | public void setLabel(String label) {
    method getFeedList (line 68) | public List<Feed> getFeedList() {
    method resetFeedList (line 85) | public synchronized void resetFeedList() {
    method delete (line 90) | public void delete() {
    method update (line 98) | public void update() {
    method refresh (line 106) | public void refresh() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FolderDao.java
  class FolderDao (line 15) | public class FolderDao extends AbstractDao<Folder, Long> {
    method readKey (line 22) | @Override
    method FolderDao (line 30) | public FolderDao(DaoConfig config) {
    method FolderDao (line 34) | public FolderDao(DaoConfig config, DaoSession daoSession) {
    method createTable (line 40) | public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
    method dropTable (line 48) | public static void dropTable(SQLiteDatabase db, boolean ifExists) {
    method bindValues (line 54) | @Override
    method attachEntity (line 61) | @Override
    method readEntity (line 70) | @Override
    class Properties (line 83) | public static class Properties {
    method readEntity (line 91) | @Override
    method updateKeyAfterInsert (line 100) | @Override
    method getKey (line 109) | @Override
    method isEntityUpdateable (line 121) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItem.java
  class RssItem (line 13) | public class RssItem implements HasId<Long> {
    method RssItem (line 53) | public RssItem() {
    method RssItem (line 56) | public RssItem(long id) {
    method RssItem (line 60) | public RssItem(long id, long feedId, String link, String title, String...
    method __setDaoSession (line 84) | public void __setDaoSession(DaoSession daoSession) {
    method getId (line 89) | public Long getId() {
    method setId (line 93) | public void setId(long id) {
    method getFeedId (line 97) | public long getFeedId() {
    method setFeedId (line 101) | public void setFeedId(long feedId) {
    method getLink (line 105) | public String getLink() {
    method setLink (line 109) | public void setLink(String link) {
    method getTitle (line 113) | public String getTitle() {
    method setTitle (line 117) | public void setTitle(String title) {
    method getBody (line 121) | public String getBody() {
    method setBody (line 125) | public void setBody(String body) {
    method getRead (line 129) | public Boolean getRead() {
    method setRead (line 133) | public void setRead(Boolean read) {
    method getStarred (line 137) | public Boolean getStarred() {
    method setStarred (line 141) | public void setStarred(Boolean starred) {
    method getAuthor (line 146) | public String getAuthor() {
    method setAuthor (line 151) | public void setAuthor(String author) {
    method getGuid (line 156) | public String getGuid() {
    method setGuid (line 161) | public void setGuid(String guid) {
    method getGuidHash (line 166) | public String getGuidHash() {
    method setGuidHash (line 171) | public void setGuidHash(String guidHash) {
    method getFingerprint (line 176) | public String getFingerprint() {
    method setFingerprint (line 181) | public void setFingerprint(String fingerprint) {
    method getRead_temp (line 185) | public Boolean getRead_temp() {
    method setRead_temp (line 189) | public void setRead_temp(Boolean read_temp) {
    method getStarred_temp (line 193) | public Boolean getStarred_temp() {
    method setStarred_temp (line 197) | public void setStarred_temp(Boolean starred_temp) {
    method getLastModified (line 201) | public java.util.Date getLastModified() {
    method setLastModified (line 205) | public void setLastModified(java.util.Date lastModified) {
    method getPubDate (line 209) | public java.util.Date getPubDate() {
    method setPubDate (line 213) | public void setPubDate(java.util.Date pubDate) {
    method getEnclosureLink (line 217) | public String getEnclosureLink() {
    method setEnclosureLink (line 221) | public void setEnclosureLink(String enclosureLink) {
    method getEnclosureMime (line 225) | public String getEnclosureMime() {
    method setEnclosureMime (line 229) | public void setEnclosureMime(String enclosureMime) {
    method getMediaThumbnail (line 233) | public String getMediaThumbnail() {
    method setMediaThumbnail (line 237) | public void setMediaThumbnail(String mediaThumbnail) {
    method getMediaDescription (line 241) | public String getMediaDescription() {
    method setMediaDescription (line 245) | public void setMediaDescription(String mediaDescription) {
    method getRtl (line 249) | public Boolean getRtl() {
    method setRtl (line 253) | public void setRtl(Boolean rtl) {
    method getFeed (line 258) | public Feed getFeed() {
    method setFeed (line 274) | public void setFeed(Feed feed) {
    method delete (line 286) | public void delete() {
    method update (line 294) | public void update() {
    method refresh (line 302) | public void refresh() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java
  class RssItemDao (line 21) | public class RssItemDao extends AbstractDao<RssItem, Long> {
    method bindValues (line 26) | @Override
    method RssItemDao (line 111) | public RssItemDao(DaoConfig config) {
    method RssItemDao (line 115) | public RssItemDao(DaoConfig config, DaoSession daoSession) {
    method createTable (line 121) | public static void createTable(SQLiteDatabase db, boolean ifNotExists) {
    method dropTable (line 150) | public static void dropTable(SQLiteDatabase db, boolean ifExists) {
    method readKey (line 158) | @Override
    method attachEntity (line 163) | @Override
    method readEntity (line 172) | @Override
    method loadCurrentDeep (line 199) | protected RssItem loadCurrentDeep(Cursor cursor, boolean lock) {
    method readEntity (line 212) | @Override
    method updateKeyAfterInsert (line 239) | @Override
    method getKey (line 248) | @Override
    method isEntityUpdateable (line 260) | @Override
    method _queryFeed_RssItemList (line 268) | public List<RssItem> _queryFeed_RssItemList(long feedId) {
    method getSelectDeep (line 283) | protected String getSelectDeep() {
    class Properties (line 301) | public static class Properties {
    method loadDeep (line 324) | public RssItem loadDeep(Long key) {
    method loadAllDeepFromCursor (line 354) | public List<RssItem> loadAllDeepFromCursor(Cursor cursor) {
    method loadDeepAllAndCloseCursor (line 376) | protected List<RssItem> loadDeepAllAndCloseCursor(Cursor cursor) {
    method queryDeep (line 386) | public List<RssItem> queryDeep(String where, String... selectionArg) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/di/ApiModule.java
  class ApiModule (line 26) | @Module
    method ApiModule (line 31) | public ApiModule(Application application) {
    method providesSharedPreferences (line 36) | @Provides
    method providesSharedPreferencesFileName (line 47) | @Provides
    method providesDatabaseFileName (line 55) | @Provides
    method provideGson (line 78) | @Provides
    method provideOkHttpClient (line 86) | @Provides
    method providePostDelayHandler (line 93) | @Provides
    method provideMTM (line 113) | @Provides
    method provideAPI (line 119) | @Provides

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/di/ApiProvider.java
  class ApiProvider (line 32) | public class ApiProvider {
    method ApiProvider (line 45) | public ApiProvider(MemorizingTrustManager mtm, SharedPreferences sp, C...
    method initApi (line 58) | public void initApi(@NonNull NextcloudAPI.ApiConnectedListener apiConn...
    method initRetrofitApi (line 86) | private void initRetrofitApi(HttpUrl baseUrl, OkHttpClient client) {
    method initSsoApi (line 98) | protected void initSsoApi(final NextcloudAPI.ApiConnectedListener call...
    method getNewsAPI (line 109) | public NewsAPI getNewsAPI() {
    method getServerAPI (line 113) | public OcsAPI getServerAPI() {
    method setAPI (line 117) | @VisibleForTesting

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/di/AppComponent.java
  type AppComponent (line 29) | @Singleton
    method injectActivity (line 33) | void injectActivity(NewsReaderListActivity activity);
    method injectActivity (line 34) | void injectActivity(NewsDetailActivity activity);
    method injectActivity (line 35) | void injectActivity(PodcastFragmentActivity activity);
    method injectActivity (line 36) | void injectActivity(NewFeedActivity activity);
    method injectActivity (line 37) | void injectActivity(SettingsActivity activity);
    method injectActivity (line 38) | void injectActivity(LoginDialogActivity activity);
    method injectFragment (line 40) | void injectFragment(NewsReaderListDialogFragment fragment);
    method injectFragment (line 41) | void injectFragment(NewsReaderListFragment fragment);
    method injectFragment (line 42) | void injectFragment(SettingsFragment fragment);
    method injectFragment (line 43) | void injectFragment(NewsDetailFragment fragment);
    method injectFragment (line 44) | void injectFragment(NewsReaderDetailFragment fragment);
    method injectFragment (line 45) | void injectFragment(FolderOptionsDialogFragment fragment);
    method injectFragment (line 46) | void injectFragment(AddFolderDialogFragment fragment);
    method injectService (line 48) | void injectService(SyncItemStateService service);
    method injectService (line 49) | void injectService(OwnCloudSyncAdapter ownCloudSyncAdapter);
    method injectWidget (line 51) | void injectWidget(WidgetProvider widgetProvider);
    method injectGlideModule (line 53) | void injectGlideModule(NextcloudGlideModule glideModule);
    method injectDatabaseConnection (line 55) | void injectDatabaseConnection(DatabaseConnectionOrm databaseConnection...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/CollapsePodcastView.java
  class CollapsePodcastView (line 3) | public class CollapsePodcastView {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/ExitPlayback.java
  class ExitPlayback (line 3) | public class ExitPlayback {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/ExpandPodcastView.java
  class ExpandPodcastView (line 3) | public class ExpandPodcastView {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/NewPodcastPlaybackListener.java
  class NewPodcastPlaybackListener (line 3) | public class NewPodcastPlaybackListener {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/PodcastCompletedEvent.java
  class PodcastCompletedEvent (line 3) | public class PodcastCompletedEvent {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/RegisterVideoOutput.java
  class RegisterVideoOutput (line 6) | public class RegisterVideoOutput {
    method RegisterVideoOutput (line 8) | public RegisterVideoOutput(SurfaceView surfaceView, View parentResizab...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/SeekPodcast.java
  class SeekPodcast (line 3) | public class SeekPodcast {
    method SeekPodcast (line 7) | public SeekPodcast(double milliSeconds) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/SpeedPodcast.java
  class SpeedPodcast (line 4) | public class SpeedPodcast {
    method SpeedPodcast (line 6) | public SpeedPodcast(float playbackSpeed) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/TogglePlayerStateEvent.java
  class TogglePlayerStateEvent (line 3) | public class TogglePlayerStateEvent {
    type State (line 5) | public enum State { Toggle, Play, Pause }
    method TogglePlayerStateEvent (line 8) | public TogglePlayerStateEvent() { }
    method TogglePlayerStateEvent (line 10) | public TogglePlayerStateEvent(State state) {
    method getState (line 14) | public State getState() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/WindPodcast.java
  class WindPodcast (line 3) | public class WindPodcast {
    method WindPodcast (line 7) | public WindPodcast(double milliSeconds) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AppCompatPreferenceActivity.java
  class AppCompatPreferenceActivity (line 41) | public abstract class AppCompatPreferenceActivity extends PreferenceActi...
    method onCreate (line 45) | @Override
    method onPostCreate (line 52) | @Override
    method getSupportActionBar (line 58) | public ActionBar getSupportActionBar() {
    method setSupportActionBar (line 62) | public void setSupportActionBar(@Nullable Toolbar toolbar) {
    method getMenuInflater (line 66) | @Override
    method setContentView (line 71) | @Override
    method setContentView (line 76) | @Override
    method setContentView (line 81) | @Override
    method addContentView (line 86) | @Override
    method onPostResume (line 91) | @Override
    method onTitleChanged (line 97) | @Override
    method onConfigurationChanged (line 103) | @Override
    method onStop (line 109) | @Override
    method onDestroy (line 115) | @Override
    method invalidateOptionsMenu (line 121) | public void invalidateOptionsMenu() {
    method getDelegate (line 125) | private AppCompatDelegate getDelegate() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AsyncTaskHelper.java
  class AsyncTaskHelper (line 5) | public class AsyncTaskHelper {
    method StartAsyncTask (line 6) | @SafeVarargs

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AutoResizeTextView.java
  class AutoResizeTextView (line 38) | public class AutoResizeTextView extends AppCompatTextView {
    type OnTextResizeListener (line 44) | public interface OnTextResizeListener {
      method onTextResize (line 45) | void onTextResize(TextView textView, float oldSize, float newSize);
    method AutoResizeTextView (line 76) | public AutoResizeTextView(Context context) {
    method AutoResizeTextView (line 81) | public AutoResizeTextView(Context context, AttributeSet attrs) {
    method AutoResizeTextView (line 86) | public AutoResizeTextView(Context context, AttributeSet attrs, int def...
    method onTextChanged (line 94) | @Override
    method onSizeChanged (line 104) | @Override
    method setOnResizeListener (line 115) | public void setOnResizeListener(OnTextResizeListener listener) {
    method setTextSize (line 122) | @Override
    method setTextSize (line 131) | @Override
    method setLineSpacing (line 140) | @Override
    method setMaxTextSize (line 151) | public void setMaxTextSize(float maxTextSize) {
    method getMaxTextSize (line 161) | public float getMaxTextSize() {
    method setMinTextSize (line 169) | public void setMinTextSize(float minTextSize) {
    method getMinTextSize (line 179) | public float getMinTextSize() {
    method setAddEllipsis (line 187) | public void setAddEllipsis(boolean addEllipsis) {
    method getAddEllipsis (line 195) | public boolean getAddEllipsis() {
    method resetTextSize (line 202) | public void resetTextSize() {
    method onLayout (line 212) | @Override
    method resizeText (line 226) | public void resizeText() {
    method resizeText (line 237) | @SuppressLint("SetTextI18n")
    method getTextHeight (line 306) | private int getTextHeight(CharSequence source, TextPaint paint, int wi...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ColorHelper.java
  class ColorHelper (line 11) | public class ColorHelper {
    method getCssColor (line 12) | @SuppressLint("DefaultLocale")
    method getColorsFromAttributes (line 23) | public static int[] getColorsFromAttributes(Context context, int... at...
    method getColorFromAttribute (line 34) | public static int getColorFromAttribute(Context context, int attr) {
    method getFeedColor (line 42) | public static int getFeedColor(Context context, Feed item) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DateTimeFormatter.java
  class DateTimeFormatter (line 10) | public class DateTimeFormatter {
    method getTimeAgo (line 17) | public static String getTimeAgo(Date date) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java
  class FavIconHandler (line 48) | public class FavIconHandler {
    method FavIconHandler (line 55) | public FavIconHandler(Context context) {
    method loadFavIconForFeed (line 61) | public <T extends Drawable> void loadFavIconForFeed(@Nullable String f...
    method isSVG (line 82) | boolean isSVG(String url) {
    method loadFavIconForFeed (line 94) | public void loadFavIconForFeed(String favIconUrl, ImageView imgView, i...
    method getResourceIdForRightDefaultFeedIcon (line 99) | public static int getResourceIdForRightDefaultFeedIcon() {
    method preCacheFavIcon (line 107) | public void preCacheFavIcon(final Feed feed) throws IllegalStateExcept...
    method UpdateAvgColorOfFeed (line 142) | private void UpdateAvgColorOfFeed(long feedId, Bitmap bitmap, Context ...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconUtils.java
  class FavIconUtils (line 7) | public class FavIconUtils {
    method fixFavIconUrl (line 11) | public static String fixFavIconUrl(String favIconUrl) {
    method decodeSpecialChars (line 32) | protected static String decodeSpecialChars(String favIconUrl) throws U...
    method fixSvgIcons (line 67) | protected static String fixSvgIcons(String favIconUrl) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/GsonConfig.java
  class GsonConfig (line 22) | public class GsonConfig {
    method GetGson (line 24) | public static Gson GetGson() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageDownloadFinished.java
  type ImageDownloadFinished (line 27) | public interface ImageDownloadFinished {
    method DownloadFinished (line 28) | void DownloadFinished(Bitmap bitmap);

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java
  class ImageHandler (line 36) | public class ImageHandler {
    method getImageLinksFromText (line 43) | public static List<String> getImageLinksFromText(String articleUrl, St...
    method fixBrokenImageLinksInArticle (line 70) | public static String fixBrokenImageLinksInArticle(String articleUrl, S...
    method fixBrokenHrefInArticle (line 74) | public static String fixBrokenHrefInArticle(String articleUrl, String ...
    method fixBrokenLinkInArticle (line 78) | public static String fixBrokenLinkInArticle(String articleUrl, String ...
    method sliceLastPathOfUrl (line 182) | private static String sliceLastPathOfUrl(String url) {
    method getFileName (line 194) | private static String getFileName(String url) {
    method clearCache (line 204) | public static void clearCache(Context context)

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NetworkConnection.java
  class NetworkConnection (line 28) | public class NetworkConnection {
    method isNetworkAvailable (line 29) | public static boolean isNetworkAvailable(Context context) {
    method isWLANConnected (line 36) | public static boolean isWLANConnected(Context context) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NewsFileUtils.java
  class NewsFileUtils (line 42) | public class NewsFileUtils {
    method copyFile (line 59) | public static void copyFile(FileInputStream fromFile, FileOutputStream...
    method deletePodcastFile (line 80) | public static boolean deletePodcastFile(Context context, String finger...
    method clearPodcastCache (line 91) | public static boolean clearPodcastCache(Context context) {
    method clearWebArchiveCache (line 101) | public static void clearWebArchiveCache(Context context) {
    method getCacheDirPath (line 119) | public static String getCacheDirPath(Context context) {
    method getPathPodcasts (line 124) | public static String getPathPodcasts(Context context) {
    method getWebPageArchiveStorage (line 128) | public static File getWebPageArchiveStorage(Context context) {
    method isExternalStorageWritable (line 132) | public static boolean isExternalStorageWritable() {
    method deleteDirectory (line 149) | public static void deleteDirectory(final File directory) throws IOExce...
    method verifiedListFiles (line 170) | private static File[] verifiedListFiles(final File directory) throws I...
    method cleanDirectory (line 195) | public static void cleanDirectory(final File directory) throws IOExcep...
    method forceDelete (line 227) | public static void forceDelete(final File file) throws IOException {
    method getDownloadedPodcastsFingerprints (line 243) | public static String[] getDownloadedPodcastsFingerprints(Context conte...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationActionReceiver.java
  class NotificationActionReceiver (line 20) | public class NotificationActionReceiver extends BroadcastReceiver {
    method onReceive (line 23) | @RequiresApi(api = Build.VERSION_CODES.O)

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationActionReceiverDownloadWebPage.java
  class NotificationActionReceiverDownloadWebPage (line 14) | public class NotificationActionReceiverDownloadWebPage extends Broadcast...
    method onReceive (line 17) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/OpmlXmlParser.java
  class OpmlXmlParser (line 23) | public class OpmlXmlParser {
    method GenerateOPML (line 28) | public static String GenerateOPML(Context context) {
    method GenerateXMLForFeed (line 80) | private static void GenerateXMLForFeed(XmlSerializer serializer, Feed ...
    method ReadFeed (line 95) | public static HashMap<String, String> ReadFeed(XmlPullParser parser) t...
    class Entry (line 114) | private static class Entry {
      method Entry (line 115) | public Entry(String folderName, String feedUrl) {
    method readFolder (line 125) | private static HashMap<String, String> readFolder(XmlPullParser parser...
    method ReadOutline (line 161) | private static Entry ReadOutline(XmlPullParser parser) {
    method Skip (line 173) | private static void Skip(XmlPullParser parser) throws XmlPullParserExc...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/PostDelayHandler.java
  class PostDelayHandler (line 31) | public class PostDelayHandler {
    method PostDelayHandler (line 38) | public PostDelayHandler(Context context) {
    method stopRunningPostDelayHandler (line 45) | public void stopRunningPostDelayHandler() {
    method delayTimer (line 51) | public void delayTimer() {
    method delayOnExitTimer (line 58) | public void delayOnExitTimer() {
    method delay (line 66) | private void delay(final int time) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/Search.java
  class Search (line 16) | public class Search {
    method PerformSearch (line 22) | public static List<RssItem> PerformSearch(Context context, Long idFold...
    method getFeedSQLStatement (line 43) | private static String getFeedSQLStatement(final long idFeed,
    method getFolderSQLStatement (line 60) | private static String getFolderSQLStatement(final long ID_FOLDER,

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/StopWatch.java
  class StopWatch (line 14) | public class StopWatch {
    method start (line 19) | public void start() {
    method stop (line 24) | public void stop() {
    method pause (line 28) | public void pause() {
    method resume (line 32) | public void resume() {
    method getElapsedTimeMili (line 38) | public long getElapsedTimeMili() {
    method getElapsedTimeSecs (line 47) | public long getElapsedTimeSecs() {
    method getElapsedTimeMin (line 56) | public long getElapsedTimeMin() {
    method getElapsedTimeHour (line 65) | public long getElapsedTimeHour() {
    method toString (line 73) | public String toString() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ThemeChooser.java
  class ThemeChooser (line 36) | public class ThemeChooser {
    type THEME (line 40) | public enum THEME { LIGHT, DARK, OLED }
    method ThemeChooser (line 52) | private ThemeChooser() { }
    method chooseTheme (line 54) | public static void chooseTheme(Activity act) {
    method afterOnCreate (line 88) | public static void afterOnCreate(Activity act) {
    method isAutoThemeSelectionEnabled (line 116) | public static boolean isAutoThemeSelectionEnabled() {
    method themeRequiresRestartOfUI (line 122) | public static boolean themeRequiresRestartOfUI() {
    method isDarkTheme (line 129) | public static boolean isDarkTheme(Context context) {
    method isOledMode (line 154) | public static boolean isOledMode(boolean forceReloadCache) {
    method getSelectedTheme (line 161) | public static THEME getSelectedTheme() {
    method getSelectedThemeFromPreferences (line 165) | private static int getSelectedThemeFromPreferences(boolean forceReload...
    method init (line 172) | public static void init(SharedPreferences prefs) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ThemeUtils.java
  class ThemeUtils (line 41) | public class ThemeUtils {
    method ThemeUtils (line 45) | private ThemeUtils() {}
    method colorizeToolbar (line 52) | public static void colorizeToolbar(Toolbar toolbarView, @ColorInt int ...
    method colorizeToolbarForeground (line 75) | public static void colorizeToolbarForeground(Toolbar toolbarView, @Col...
    method changeStatusBarColor (line 111) | @RequiresApi(api = Build.VERSION_CODES.KITKAT)

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/interfaces/ExpListTextClicked.java
  type ExpListTextClicked (line 24) | public interface ExpListTextClicked {
    method onTextClicked (line 25) | void onTextClicked(long idFeed, boolean isFolder, Long optional_folder...
    method onTextLongClicked (line 26) | void onTextLongClicked(long idFeed, boolean isFolder, Long optional_fo...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/interfaces/IPlayPausePodcastClicked.java
  type IPlayPausePodcastClicked (line 5) | public interface IPlayPausePodcastClicked {
    method openPodcast (line 6) | void openPodcast(RssItem rssItem);
    method pausePodcast (line 7) | void pausePodcast();

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/AbstractItem.java
  class AbstractItem (line 24) | public abstract class AbstractItem {
    method AbstractItem (line 29) | AbstractItem(long id_database, String header, Long idFolder) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/ConcreteFeedItem.java
  class ConcreteFeedItem (line 24) | public class ConcreteFeedItem extends AbstractItem {
    method ConcreteFeedItem (line 29) | public ConcreteFeedItem(String header, Long folder_id, long feedId, St...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/CurrentRssViewDataHolder.java
  class CurrentRssViewDataHolder (line 7) | public class CurrentRssViewDataHolder {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/FolderSubscribtionItem.java
  class FolderSubscribtionItem (line 24) | public class FolderSubscribtionItem extends AbstractItem {
    method FolderSubscribtionItem (line 26) | public FolderSubscribtionItem(String headerFolder, Long idFolder, long...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/MediaItem.java
  class MediaItem (line 5) | public abstract class MediaItem implements Serializable {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/NextcloudNewsVersion.java
  class NextcloudNewsVersion (line 7) | public class NextcloudNewsVersion {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/NextcloudStatus.java
  class NextcloudStatus (line 7) | public class NextcloudStatus {
    class Warnings (line 12) | static class Warnings {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/OcsUser.java
  class OcsUser (line 13) | public class OcsUser implements Serializable {
    method OcsUser (line 19) | public OcsUser() { }
    method OcsUser (line 21) | public OcsUser(String id, String displayName) {
    method getId (line 26) | public String getId() {
    method setId (line 30) | public void setId(String id) {
    method getDisplayName (line 34) | public String getDisplayName() {
    method setDisplayName (line 38) | public void setDisplayName(String displayName) {
    method getAvatarUrl (line 42) | public @Nullable String getAvatarUrl(@Nullable String ownCloudRootPath) {
    method equals (line 50) | @Override
    method hashCode (line 61) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastFeedItem.java
  class PodcastFeedItem (line 5) | public class PodcastFeedItem {
    method PodcastFeedItem (line 7) | public PodcastFeedItem(Feed feed, int podcastCount) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java
  class PodcastItem (line 3) | public class PodcastItem extends MediaItem {
    method PodcastItem (line 5) | public PodcastItem() {
    method PodcastItem (line 9) | public PodcastItem(long itemId, String author, String title, String li...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/TTSItem.java
  class TTSItem (line 3) | public class TTSItem extends MediaItem {
    method TTSItem (line 5) | public TTSItem(long itemId, String author, String title, String text, ...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/Tuple.java
  class Tuple (line 4) | public class Tuple<E, T> {
    method Tuple (line 7) | public Tuple(E key, T value) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/notification/NextcloudNotificationManager.java
  class NextcloudNotificationManager (line 53) | public class NextcloudNotificationManager {
    method showNotificationDownloadSingleImageComplete (line 58) | public static void showNotificationDownloadSingleImageComplete(Context...
    method buildNotificationDownloadImageService (line 99) | public static NotificationCompat.Builder buildNotificationDownloadImag...
    method buildNotificationDownloadWebPageService (line 116) | public static NotificationCompat.Builder buildNotificationDownloadWebP...
    method showNotificationImageDownloadLimitReached (line 134) | public static void showNotificationImageDownloadLimitReached(Context c...
    method buildPodcastNotification (line 165) | public static NotificationCompat.Builder buildPodcastNotification(Cont...
    method getPlayPauseAction (line 235) | private static NotificationCompat.Action getPlayPauseAction(Context co...
    method buildDownloadPodcastNotification (line 245) | public static NotificationCompat.Builder buildDownloadPodcastNotificat...
    method showUnreadRssItemsNotification (line 263) | public static void showUnreadRssItemsNotification(Context context, Sha...
    method isUnreadRssCountNotificationVisible (line 333) | public static boolean isUnreadRssCountNotificationVisible(Context cont...
    method getNotificationManagerAndCreateChannel (line 357) | private static NotificationManager getNotificationManagerAndCreateChan...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/FeedItemTags.java
  type FeedItemTags (line 24) | public enum FeedItemTags {
    method FeedItemTags (line 34) | FeedItemTags(String segment) {
    method toString (line 38) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/InsertIntoDatabase.java
  class InsertIntoDatabase (line 33) | public class InsertIntoDatabase {
    method InsertFoldersIntoDatabase (line 36) | public static void InsertFoldersIntoDatabase(List<Folder> folderList, ...
    method InsertFeedsIntoDatabase (line 68) | public static void InsertFeedsIntoDatabase(List<Feed> feeds, DatabaseC...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/OnAsyncTaskCompletedListener.java
  type OnAsyncTaskCompletedListener (line 25) | public interface OnAsyncTaskCompletedListener {
    method onAsyncTaskCompleted (line 26) | void onAsyncTaskCompleted(final Exception task_result);

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/IHandleJsonObject.java
  type IHandleJsonObject (line 9) | public interface IHandleJsonObject {
    method performAction (line 10) | boolean performAction(JsonObject jObj);

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/InsertRssItemIntoDatabase.java
  class InsertRssItemIntoDatabase (line 36) | class InsertRssItemIntoDatabase {
    method parseItem (line 40) | static RssItem parseItem(JsonObject e) {
    method getStringOrEmpty (line 147) | private static String getStringOrEmpty(String key, JsonObject jObj) {
    method getStringOrDefault (line 151) | private static String getStringOrDefault(String key, String defaultVal...
    method getBooleanOrDefault (line 159) | @SuppressWarnings("SameParameterValue")

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemIds.java
  class ItemIds (line 10) | public class ItemIds {
    method ItemIds (line 13) | public ItemIds(Iterable<String> items) {
    method getItems (line 19) | public Set<Long> getItems() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemMap.java
  class ItemMap (line 15) | public class ItemMap {
    method ItemMap (line 18) | public ItemMap(Iterable<String> itemIds, DatabaseConnectionOrm dbConn) {
    method getItems (line 29) | public Set<Map<String, Object>> getItems() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemStateSync.java
  class ItemStateSync (line 22) | public class ItemStateSync {
    method PerformItemStateSync (line 26) | public static void PerformItemStateSync(NewsAPI newsApi, DatabaseConne...
    method partitionBasedOnSize (line 63) | static <T> Collection<List<T>> partitionBasedOnSize(List<T> inputList,...
    method executeRequest (line 70) | private static void executeRequest(ExecuteRequestCallable<Response> da...
    method PerformTagExecution (line 87) | private static void PerformTagExecution(List<String> itemIds, FeedItem...
    type ExecuteRequestCallable (line 120) | interface ExecuteRequestCallable<T> {
      method call (line 121) | T call() throws IOException;
    type OnSuccessCallable (line 124) | interface OnSuccessCallable<T> {
      method call (line 125) | void call();

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/NewsAPI.java
  type NewsAPI (line 32) | public interface NewsAPI {
    method status (line 36) | @GET("status")
    method version (line 39) | @GET("version")
    method folders (line 43) | @GET("folders")
    method feeds (line 47) | @GET("feeds")
    method createFolder (line 50) | @POST("folders")
    method createFolderObservable (line 53) | @POST("folders")
    method createFeed (line 56) | @POST("feeds")
    method renameFeed (line 60) | @PUT("feeds/{feedId}/rename")
    method renameFolder (line 63) | @PUT("folders/{folderId}")
    method moveFeed (line 67) | @PUT("feeds/{feedId}/move")
    method deleteFeed (line 71) | @DELETE("feeds/{feedId}")
    method deleteFolder (line 74) | @DELETE("folders/{folderId}")
    method items (line 79) | @GET("items")
    method updatedItems (line 89) | @GET("items/updated")
    method markItemsRead (line 98) | @PUT("items/read/multiple")
    method markItemsUnread (line 101) | @PUT("items/unread/multiple")
    method markItemsStarred (line 104) | @PUT("items/star/multiple")
    method markItemsUnstarred (line 107) | @PUT("items/unstar/multiple")

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/NextcloudNewsDeserializer.java
  class NextcloudNewsDeserializer (line 22) | public class NextcloudNewsDeserializer<T> implements JsonDeserializer<Li...
    method NextcloudNewsDeserializer (line 28) | public NextcloudNewsDeserializer(String key, Class<T> type) {
    method deserialize (line 35) | @Override
    method parseFolder (line 54) | private Folder parseFolder(JsonObject e) {
    method parseFeed (line 58) | private Feed parseFeed(JsonObject e) {
    method getNullAsEmptyString (line 86) | private String getNullAsEmptyString(JsonElement jsonElement) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/NextcloudServerDeserializer.java
  class NextcloudServerDeserializer (line 17) | public class NextcloudServerDeserializer<T> implements JsonDeserializer<...
    method NextcloudServerDeserializer (line 23) | public NextcloudServerDeserializer(String key, Class<T> type) {
    method deserialize (line 30) | @Override
    method parseOcsUser (line 38) | private static OcsUser parseOcsUser(JsonObject obj) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/OcsAPI.java
  type OcsAPI (line 7) | public interface OcsAPI {
    method user (line 11) | @GET("cloud/user?format=json")

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/RssItemObservable.java
  class RssItemObservable (line 36) | public class RssItemObservable implements Publisher<Integer> {
    method RssItemObservable (line 44) | public RssItemObservable(DatabaseConnectionOrm dbConn, NewsAPI newsApi...
    method subscribe (line 50) | @Override
    method events (line 60) | public static Observable<RssItem> events(final BufferedSource source) {
    method getMaxIdFromItems (line 94) | private static long getMaxIdFromItems(List<RssItem> buffer) {
    method performDatabaseBatchInsert (line 104) | public static boolean performDatabaseBatchInsert(DatabaseConnectionOrm...
    method sync (line 111) | public void sync(Subscriber<? super Integer> subscriber) throws IOExce...
    method getJsonObjectFromReader (line 218) | private static JsonObject getJsonObjectFromReader(JsonReader jsonReade...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/Types.java
  type Types (line 7) | public enum Types {
    method Types (line 18) | private Types(final String text) {
    method toString (line 25) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java
  class DownloadImagesService (line 51) | public class DownloadImagesService extends JobIntentService {
    type DownloadMode (line 56) | public enum DownloadMode { FAVICONS_ONLY, PICTURES_ONLY, FAVICONS_AND_...
    method enqueueWork (line 77) | public static void enqueueWork(Context context, Intent work) {
    method onCreate (line 83) | @Override
    method onDestroy (line 98) | @Override
    method onHandleWork (line 110) | @Override
    method downloadImages (line 152) | private void downloadImages(List<String> linksToImages) {
    method updateNotificationProgress (line 172) | private void updateNotificationProgress(int remainingImagesCount) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadWebPageService.java
  class DownloadWebPageService (line 48) | public class DownloadWebPageService extends Service {
    method onCreate (line 74) | @Override
    method onDestroy (line 87) | @Override
    method onBind (line 95) | @Override
    method initNotification (line 100) | private void initNotification() {
    method onEvent (line 110) | @Subscribe
    method runOnMainThreadAndWait (line 117) | private void runOnMainThreadAndWait(final Runnable runnable) throws In...
    method delayedRunOnMainThread (line 130) | private void delayedRunOnMainThread(Runnable runnable, @SuppressWarnin...
    method downloadWebPages (line 141) | private void downloadWebPages() {
    method startDownloadingQueue (line 167) | private void startDownloadingQueue(BlockingQueue<Runnable> downloadWor...
    class DownloadWebPage (line 190) | class DownloadWebPage implements Runnable {
      method DownloadWebPage (line 196) | DownloadWebPage(String url) {
      method run (line 201) | @Override
      method initWebView (line 217) | private void initWebView() {
      method loadUrlInWebViewAndWait (line 229) | private void loadUrlInWebViewAndWait() {
    class DownloadImageWebViewChromeClient (line 242) | static class DownloadImageWebViewChromeClient extends WebChromeClient {
      method onConsoleMessage (line 243) | @Override
    class DownloadImageWebViewClient (line 250) | class DownloadImageWebViewClient extends WebViewClient {
      method DownloadImageWebViewClient (line 255) | DownloadImageWebViewClient(Object lock) {
      method onReceivedError (line 259) | @Override
      method onPageFinished (line 266) | public void onPageFinished(final WebView view, final String url) {
      method saveWebArchive (line 281) | private void saveWebArchive(final WebView view, final String url) {
    method updateNotificationProgress (line 296) | private synchronized void updateNotificationProgress() {
    method getWebPageArchiveFileForUrl (line 316) | public static File getWebPageArchiveFileForUrl(Context context, String...
    method getWebPageArchiveFilename (line 320) | public static String getWebPageArchiveFilename(String url) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudSyncService.java
  class OwnCloudSyncService (line 10) | public class OwnCloudSyncService extends Service {
    method onCreate (line 18) | @Override
    method onBind (line 32) | @Override
    method isSyncRunning (line 43) | public static boolean isSyncRunning() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastDownloadService.java
  class PodcastDownloadService (line 37) | public class PodcastDownloadService extends IntentService {
    method startPodcastDownload (line 55) | public static void startPodcastDownload(Context context, PodcastItem p...
    method PodcastDownloadService (line 64) | public PodcastDownloadService() {
    method onHandleIntent (line 70) | @Override
    method handleActionDownload (line 87) | private void handleActionDownload(PodcastItem podcast) {
    method getUrlToPodcastFile (line 106) | public static String getUrlToPodcastFile(Context context, String finge...
    method downloadPodcast (line 116) | private void downloadPodcast(PodcastItem podcast, Context context) {
    method calculateNetworkSpeed (line 201) | private float calculateNetworkSpeed(int byteCountSinceLastProgress, lo...
    method formatFloat (line 214) | private String formatFloat(float val) {
    class DownloadProgressUpdate (line 221) | public static class DownloadProgressUpdate {
      method DownloadProgressUpdate (line 222) | public DownloadProgressUpdate(PodcastItem podcast) {
    method PodcastAlreadyCached (line 228) | public static boolean PodcastAlreadyCached(Context context, String pod...

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java
  class PodcastPlaybackService (line 69) | public class PodcastPlaybackService extends MediaBrowserServiceCompat {
    method getCurrentlyPlayingPodcast (line 129) | public MediaItem getCurrentlyPlayingPodcast() {
    method isActive (line 136) | public boolean isActive() {
    method onGetRoot (line 143) | @Nullable
    method onLoadChildren (line 156) | @Override
    method onUnbind (line 210) | @Override
    method onCreate (line 216) | @Override
    method onDestroy (line 259) | @Override
    method onStartCommand (line 297) | @Override
    method updateMetadata (line 339) | private void updateMetadata(MediaItem mediaItem) {
    method podcastStatusUpdated (line 373) | @Override
    method podcastCompleted (line 381) | @Override
    method endCurrentMediaPlayback (line 391) | private void endCurrentMediaPlayback() {
    method onEvent (line 411) | @Subscribe
    method onEvent (line 416) | @Subscribe
    method isPlaying (line 436) | private boolean isPlaying() {
    method onEvent (line 440) | @Subscribe
    method onEvent (line 451) | @Subscribe
    method onEvent (line 459) | @Subscribe
    method onEvent (line 466) | @Subscribe
    method onEvent (line 471) | @Subscribe
    method play (line 480) | public void play() {
    method pause (line 490) | public void pause() {
    method requestAudioFocus (line 500) | private void requestAudioFocus() {
    method abandonAudioFocus (line 516) | private void abandonAudioFocus() {
    method startProgressUpdates (line 540) | private void startProgressUpdates() {
    method stopProgressUpdates (line 546) | private void stopProgressUpdates() {
    method getPlaybackSpeed (line 554) | public float getPlaybackSpeed() {
    method syncMediaAndPlaybackStatus (line 558) | public void syncMediaAndPlaybackStatus() {
    method buildPlaybackActions (line 593) | private long buildPlaybackActions(int playbackState, boolean mediaLoad...
    method onCallStateChanged (line 606) | @Override
    class CustomTelephonyCallback (line 623) | @RequiresApi(Build.VERSION_CODES.S)
      method onCallStateChanged (line 626) | @Override
    class MediaSessionCallback (line 635) | private final class MediaSessionCallback extends MediaSessionCompat.Ca...
      method onPlayFromMediaId (line 636) | @Override
      method onPlay (line 653) | @Override
      method onPause (line 659) | @Override
      method onPlayFromSearch (line 665) | @Override
      method onCommand (line 701) | @Override
      method onSeekTo (line 720) | @Override
      method onSkipToNext (line 726) | @Override
      method onSkipToPrevious (line 746) | @Override
      method onMediaButtonEvent (line 766) | @Override
    method startPlayingPodcastItem (line 791) | private void startPlayingPodcastItem(PodcastItem podcastItem) {
    method getAllPodcastItems (line 797) | private List<PodcastItem> getAllPodcastItems() {
    method initMediaSessions (line 807) | private void initMediaSessions() {
    method getCurrentlyPlayedMediaType (line 830) | private PlaybackService.VideoType getCurrentlyPlayedMediaType() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/SyncItemStateService.java
  class SyncItemStateService (line 42) | public class SyncItemStateService extends JobIntentService {
    method enqueueWork (line 55) | public static void enqueueWork(Context context, Intent work) {
    method onCreate (line 59) | @Override
    method onHandleWork (line 65) | @Override
    method isMyServiceRunning (line 83) | public static boolean isMyServiceRunning(Context context) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/podcast/MediaPlayerPlaybackService.java
  class MediaPlayerPlaybackService (line 21) | public class MediaPlayerPlaybackService extends PlaybackService {
    method MediaPlayerPlaybackService (line 26) | public MediaPlayerPlaybackService(final Context context, PodcastStatus...
    method destroy (line 64) | @Override
    method play (line 71) | @Override
    method pause (line 88) | @Override
    method playbackSpeedChanged (line 96) | @Override
    method seekTo (line 103) | @Override
    method getCurrentPosition (line 111) | @Override
    method getTotalDuration (line 119) | @Override
    method getVideoType (line 127) | @Override
    method getVideoWidth (line 146) | public long getVideoWidth() {
    method setVideoView (line 150) | public void setVideoView(SurfaceView surfaceView) {
    method surfaceChanged (line 172) | public void surfaceChanged(SurfaceHolder holder, int format, int surfa...
    method surfaceCreated (line 179) | public void surfaceCreated(SurfaceHolder holder) {
    method surfaceDestroyed (line 186) | public void surfaceDestroyed(SurfaceHolder holder)

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/podcast/PlaybackService.java
  class PlaybackService (line 11) | public abstract class PlaybackService {
    type VideoType (line 13) | public enum VideoType { None, Video, VideoType, YouTube }
    type PodcastStatusListener (line 19) | public interface PodcastStatusListener {
      method podcastStatusUpdated (line 20) | void podcastStatusUpdated();
      method podcastCompleted (line 21) | void podcastCompleted();
    method PlaybackService (line 24) | public PlaybackService(PodcastStatusListener podcastStatusListener, Me...
    method destroy (line 29) | public abstract void destroy();
    method play (line 30) | public abstract void play();
    method pause (line 31) | public abstract void pause();
    method playbackSpeedChanged (line 32) | public abstract void playbackSpeedChanged(float currentPlaybackSpeed);
    method seekTo (line 35) | public void seekTo(int position) { }
    method getCurrentPosition (line 36) | public int getCurrentPosition() { return 0; }
    method getTotalDuration (line 37) | public int getTotalDuration() { return 0; }
    method getVideoType (line 38) | public VideoType getVideoType() { return VideoType.None; }
    method getMediaItem (line 40) | public MediaItem getMediaItem() {
    method getStatus (line 44) | public @PlaybackStateCompat.State int getStatus() {
    method setStatus (line 48) | protected void setStatus(@PlaybackStateCompat.State int status) {
    method podcastCompleted (line 53) | protected void podcastCompleted() {
    method isMediaLoaded (line 57) | public boolean isMediaLoaded() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/podcast/TTSPlaybackService.java
  class TTSPlaybackService (line 18) | public class TTSPlaybackService extends PlaybackService implements TextT...
    method TTSPlaybackService (line 21) | public TTSPlaybackService(Context context, PodcastStatusListener podca...
    method destroy (line 46) | @Override
    method play (line 53) | @Override
    method pause (line 58) | @Override
    method playbackSpeedChanged (line 66) | @Override
    method onInit (line 71) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/MTMDecision.java
  class MTMDecision (line 27) | class MTMDecision {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/MemorizingDialogFragment.java
  class MemorizingDialogFragment (line 40) | public class MemorizingDialogFragment extends DialogFragment
    method MemorizingDialogFragment (line 48) | public MemorizingDialogFragment() {
    method onCreate (line 52) | @Override
    method onResume (line 66) | @Override
    method sendDecision (line 78) | void sendDecision(int decision) {
    method onClick (line 89) | public void onClick(DialogInterface dialog, int btnId) {
    method onCancel (line 105) | public void onCancel(@NonNull DialogInterface dialog) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/MemorizingTrustManager.java
  class MemorizingTrustManager (line 80) | public class MemorizingTrustManager implements X509TrustManager {
    method MemorizingTrustManager (line 116) | public MemorizingTrustManager(Context m) {
    method getInstanceList (line 153) | public static X509TrustManager[] getInstanceList(Context c) {
    method bindDisplayActivity (line 169) | public void bindDisplayActivity(Activity act) {
    method unbindDisplayActivity (line 181) | public void unbindDisplayActivity(Activity act) {
    method setKeyStoreFile (line 197) | public static void setKeyStoreFile(String dirname, String filename) {
    method getCertificates (line 208) | public Enumeration<String> getCertificates() {
    method getCertificate (line 224) | public Certificate getCertificate(String alias) {
    method deleteCertificate (line 246) | public void deleteCertificate(String alias) throws KeyStoreException {
    method keyStoreUpdated (line 251) | void keyStoreUpdated() {
    method getTrustManager (line 280) | X509TrustManager getTrustManager(KeyStore ks) {
    method loadAppKeyStore (line 298) | KeyStore loadAppKeyStore() {
    method storeCert (line 317) | void storeCert(X509Certificate[] chain) {
    method isCertKnown (line 341) | private boolean isCertKnown(X509Certificate cert) {
    method isExpiredException (line 349) | private boolean isExpiredException(Throwable e) {
    method checkCertTrusted (line 358) | public void checkCertTrusted(X509Certificate[] chain, String authType,...
    method checkClientTrusted (line 391) | public void checkClientTrusted(X509Certificate[] chain, String authType)
    method checkServerTrusted (line 397) | public void checkServerTrusted(X509Certificate[] chain, String authType)
    method getAcceptedIssuers (line 403) | public X509Certificate[] getAcceptedIssuers()
    method createDecisionId (line 409) | private int createDecisionId(MTMDecision d) {
    method hexString (line 419) | private static String hexString(byte[] data) {
    method certHash (line 429) | private static String certHash(final X509Certificate cert, String dige...
    method certChainMessage (line 441) | private String certChainMessage(final X509Certificate[] chain, Certifi...
    method startActivityNotification (line 464) | void startActivityNotification(Intent intent, String certName) {
    method getUI (line 484) | Context getUI() {
    method interact (line 488) | void interact(final X509Certificate[] chain, CertificateException cause)
    method interactResult (line 538) | public static void interactResult(Intent i) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/OkHttpSSLClient.java
  class OkHttpSSLClient (line 40) | public class OkHttpSSLClient {
    method GetSslClient (line 42) | public static OkHttpClient GetSslClient(HttpUrl baseUrl, String userna...
    method HandleExceptions (line 91) | public static <T extends Throwable> T HandleExceptions(T ex) {
    method systemDefaultTrustManager (line 102) | private static X509TrustManager systemDefaultTrustManager() {
    method intercept (line 120) | @NonNull

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/AnimatingProgressBar.java
  class AnimatingProgressBar (line 14) | public class AnimatingProgressBar extends ProgressBar {
    method AnimatingProgressBar (line 37) | public AnimatingProgressBar(Context context, AttributeSet attrs, int d...
    method AnimatingProgressBar (line 41) | public AnimatingProgressBar(Context context, AttributeSet attrs) {
    method AnimatingProgressBar (line 45) | public AnimatingProgressBar(Context context) {
    method isAnimate (line 49) | public boolean isAnimate() {
    method setAnimate (line 53) | public void setAnimate(boolean animate) {
    method setMax (line 57) | @Override
    method getMax (line 62) | @Override
    method getProgress (line 67) | @Override
    method getSecondaryProgress (line 72) | @Override
    method setProgress (line 77) | @Override
    method setSecondaryProgress (line 96) | @Override
    method onDetachedFromWindow (line 115) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java
  class PodcastNotification (line 18) | public class PodcastNotification {
    method PodcastNotification (line 37) | public PodcastNotification(Context context, MediaSessionCompat session) {
    method updateStateOfNotification (line 46) | @Subscribe
    method cancel (line 112) | public void cancel()
    method createPodcastNotification (line 124) | public void createPodcastNotification() {
    method getNotification (line 162) | public Notification getNotification() {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java
  class PodcastSlidingUpPanelLayout (line 11) | public class PodcastSlidingUpPanelLayout extends SlidingUpPanelLayout {
    method PodcastSlidingUpPanelLayout (line 12) | public PodcastSlidingUpPanelLayout(Context context) {
    method PodcastSlidingUpPanelLayout (line 16) | public PodcastSlidingUpPanelLayout(Context context, AttributeSet attrs) {
    method PodcastSlidingUpPanelLayout (line 20) | public PodcastSlidingUpPanelLayout(Context context, AttributeSet attrs...
    method setSlideableView (line 27) | public void setSlideableView(View view) {
    method setDragView (line 31) | @Override
    method isDragViewHit (line 38) | private boolean isDragViewHit(int x, int y) {
    method expand (line 62) | public static void expand(final View v) {
    method collapse (line 88) | public static void collapse(final View v) {

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/widget/WidgetNewsViewsFactory.java
  class WidgetNewsViewsFactory (line 47) | public class WidgetNewsViewsFactory implements RemoteViewsService.Remote...
    method WidgetNewsViewsFactory (line 56) | public WidgetNewsViewsFactory(Context context, Intent intent) {
    method onCreate (line 65) | @Override
    method onDestroy (line 75) | @Override
    method getCount (line 85) | @Override
    method getViewAt (line 100) | @SuppressLint("SimpleDateFormat")
    method getLoadingView (line 178) | @Override
    method getViewTypeCount (line 186) | @Override
    method getItemId (line 191) | @Override
    method hasStableIds (line 199) | @Override
    method onDataSetChanged (line 207) | @Override

FILE: News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/widget/WidgetProvider.java
  class WidgetProvider (line 49) | public class WidgetProvider extends AppWidgetProvider {
    method UpdateWidget (line 65) | public static void UpdateWidget(Context context) {
    method onReceive (line 85) | @Override
    method onDeleted (line 156) | @Override
    method onUpdate (line 184) | @Override
    method updateAppWidget (line 202) | public static void updateAppWidget(Context context, AppWidgetManager a...
    method inject (line 244) | private void inject(Context context) {

FILE: News-Android-App/src/test/java/de/luhmer/owncloudnewsreader/junit_tests/ImageHandlerTest.java
  class ImageHandlerTest (line 8) | public class ImageHandlerTest {
    method testHref_CASE_MISSING_PROTOCOL (line 10) | @Test
    method testHref_CASE_ABSOLUTE_URL (line 23) | @Test
    method testHref_CASE_RELATIVE_FILE_END (line 36) | @Test
    method testHref_CASE_RELATIVE_PARENT (line 49) | @Test
    method testHref_CASE_RELATIVE_ADD_HOST (line 62) | @Test
    method testHref_CASE_RELATIVE_DOMAIN_OR_FILE (line 75) | @Test
    method testHref_CASE_RELATIVE_DOMAIN_SUBPATH (line 88) | @Test
    method testImg_CASE_MISSING_PROTOCOL (line 101) | @Test
Condensed preview — 480 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (2,664K chars).
[
  {
    "path": ".editorconfig",
    "chars": 35,
    "preview": "[*.{kt,kts}]\nmax_line_length = 120\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 116,
    "preview": "# These are supported funding model platforms\n\ncustom: https://www.paypal.com/donate?hosted_button_id=5TJ6LTEVTDF5J\n"
  },
  {
    "path": ".github/dependabot.yml",
    "chars": 242,
    "preview": "version: 2\nupdates:\n- package-ecosystem: gradle\n  directory: \"/\"\n  schedule:\n    interval: daily\n  open-pull-requests-li"
  },
  {
    "path": ".github/workflows/analysis.yml",
    "chars": 1024,
    "preview": "name: Analysis\n\n# Declare default permissions as read only.\npermissions: read-all\n\non: [push, pull_request]\njobs:\n  dete"
  },
  {
    "path": ".github/workflows/ci.yml",
    "chars": 1941,
    "preview": "name: Android CI\n\non: [push, pull_request]\njobs:\n  validation:\n    name: Validate Gradle Wrapper\n    runs-on: ubuntu-lat"
  },
  {
    "path": ".github/workflows/codeql.yml",
    "chars": 641,
    "preview": "name: CodeQL\n\non:\n  push:\n    branches-ignore:\n      - 'dependabot/**'\n  pull_request:\njobs:\n  codeql:\n    name: CodeQL "
  },
  {
    "path": ".gitignore",
    "chars": 571,
    "preview": "/local.properties\n/.idea/workspace.xml\n.DS_Store\n\n# built application files\n*.apk\n*.ap_\n\n# files for the dex VM\n*.dex\n\n#"
  },
  {
    "path": ".tx/config",
    "chars": 3479,
    "preview": "[main]\nhost = https://www.transifex.com\n\n[o:nextcloud:p:nextcloud:r:android-news]\nfile_filter = News-Android-App/src/mai"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 68460,
    "preview": "0.9.9.95\n---------------------\n- Dependency updates\n- Fixed - <a href=\"https://github.com/nextcloud/news-android/pull/16"
  },
  {
    "path": "COPYING-AGPL.md",
    "chars": 34519,
    "preview": "                    GNU AFFERO GENERAL PUBLIC LICENSE\n                       Version 3, 19 November 2007\n\n Copyright (C)"
  },
  {
    "path": "COPYING-README.md",
    "chars": 220,
    "preview": "Files in the ownCloud News Reader Android App Repo are licensed under the Affero General Public License version 3,\nthe t"
  },
  {
    "path": "Gemfile",
    "chars": 46,
    "preview": "source \"https://rubygems.org\"\n\ngem \"fastlane\"\n"
  },
  {
    "path": "NEWS-POLICY.md",
    "chars": 2248,
    "preview": "# Nextcloud News Android [News Policy](https://support.google.com/googleplay/android-developer/answer/9935326)\n\nThe \"Nex"
  },
  {
    "path": "News-Android-App/.gitignore",
    "chars": 7,
    "preview": "/build\n"
  },
  {
    "path": "News-Android-App/build.gradle",
    "chars": 9753,
    "preview": "plugins {\n    id 'com.android.application'\n    id 'com.google.devtools.ksp'\n    id 'io.gitlab.arturbosch.detekt' version"
  },
  {
    "path": "News-Android-App/config/detekt/detekt.yml",
    "chars": 9575,
    "preview": "build:\n  maxIssues: 0\n  weights:\n  # complexity: 2\n  # LongParameterList: 1\n  # style: 1\n  # comments: 1\n\nprocessors:\n  "
  },
  {
    "path": "News-Android-App/proguard-rules.pro",
    "chars": 4174,
    "preview": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /o"
  },
  {
    "path": "News-Android-App/proguard-test.pro",
    "chars": 1045,
    "preview": "# proguard-test.pro:\n-include proguard-rules.pro\n-keepattributes SourceFile,LineNumberTable\n\n\n\n-dontwarn androidx.test.e"
  },
  {
    "path": "News-Android-App/remove_invalid_languages.sh",
    "chars": 175,
    "preview": "git rm -r src/main/res/values-ach/\ngit rm -r src/main/res/values-ady/\ngit rm -r src/main/res/values-nds/\ngit rm -r src/m"
  },
  {
    "path": "News-Android-App/src/androidTest/AndroidManifest.xml",
    "chars": 715,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:tools=\"http://schemas.android.com/tools\"\n    xmlns:android=\"http:"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/CustomTestRunner.java",
    "chars": 758,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.app.Application;\nimport android.content.Context;\n\nimport androidx."
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/TestApplication.java",
    "chars": 664,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport de.luhmer.owncloudnewsreader.di.DaggerTestComponent;\nimport de.luhmer.ownc"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestApiModule.java",
    "chars": 4723,
    "preview": "package de.luhmer.owncloudnewsreader.di;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestApiProvider.java",
    "chars": 9304,
    "preview": "package de.luhmer.owncloudnewsreader.di;\n\nimport static org.mockito.ArgumentMatchers.any;\nimport static de.luhmer.ownclo"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/di/TestComponent.java",
    "chars": 564,
    "preview": "package de.luhmer.owncloudnewsreader.di;\n\nimport javax.inject.Singleton;\n\nimport dagger.Component;\nimport de.luhmer.ownc"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/helper/Utils.java",
    "chars": 1267,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\n"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/DownloadWebPageServiceTest.java",
    "chars": 3116,
    "preview": "package de.luhmer.owncloudnewsreader.tests;\n\nimport androidx.test.filters.LargeTest;\nimport androidx.test.rule.ActivityT"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NewFeedTests.java",
    "chars": 5190,
    "preview": "package de.luhmer.owncloudnewsreader.tests;\n\n\nimport static androidx.test.espresso.Espresso.onView;\nimport static androi"
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NewsReaderListActivityUiTests.java",
    "chars": 13372,
    "preview": "package de.luhmer.owncloudnewsreader.tests;\n\nimport android.content.SharedPreferences;\nimport android.os.Bundle;\nimport "
  },
  {
    "path": "News-Android-App/src/androidTest/java/de/luhmer/owncloudnewsreader/tests/NightModeTest.java",
    "chars": 7430,
    "preview": "package de.luhmer.owncloudnewsreader.tests;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android"
  },
  {
    "path": "News-Android-App/src/androidTest/java/helper/CustomMatchers.java",
    "chars": 5484,
    "preview": "package helper;\n\nimport android.app.Activity;\nimport android.content.Context;\nimport android.graphics.Bitmap;\nimport and"
  },
  {
    "path": "News-Android-App/src/androidTest/java/helper/OrientationChangeAction.java",
    "chars": 2961,
    "preview": "/*\n * The MIT License (MIT)\n *\n * Copyright (c) 2015 - Nathan Barraille\n *\n * Permission is hereby granted, free of char"
  },
  {
    "path": "News-Android-App/src/androidTest/java/helper/RecyclerViewAssertions.java",
    "chars": 955,
    "preview": "package helper;\n\nimport android.view.View;\n\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.rec"
  },
  {
    "path": "News-Android-App/src/androidTest/java/screengrab/ScreenshotTest.java",
    "chars": 6499,
    "preview": "package screengrab;\n\nimport androidx.core.view.GravityCompat;\nimport androidx.test.filters.LargeTest;\nimport androidx.te"
  },
  {
    "path": "News-Android-App/src/dev/res/drawable/ic_launcher_foreground.xml",
    "chars": 2002,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:wi"
  },
  {
    "path": "News-Android-App/src/dev/res/values/strings.xml",
    "chars": 318,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <string name=\"app_name\" translatable=\"false\">News Dev</string>\n  "
  },
  {
    "path": "News-Android-App/src/main/AndroidManifest.xml",
    "chars": 11908,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:to"
  },
  {
    "path": "News-Android-App/src/main/assets/web.css",
    "chars": 4824,
    "preview": ":root {\n    --fontsize-body: 1.1em;\n    --fontsize-header: 1.1em;\n    --fontsize-subscript: 0.7em;\n}\n\n/*\n@font-face {\n  "
  },
  {
    "path": "News-Android-App/src/main/java/com/bumptech/glide/samples/svg/SvgDecoder.kt",
    "chars": 1275,
    "preview": "package com.bumptech.glide.samples.svg\n\nimport com.bumptech.glide.load.Options\nimport com.bumptech.glide.load.ResourceDe"
  },
  {
    "path": "News-Android-App/src/main/java/com/bumptech/glide/samples/svg/SvgDrawableTranscoder.kt",
    "chars": 838,
    "preview": "package com.bumptech.glide.samples.svg\n\nimport android.graphics.Picture\nimport android.graphics.drawable.PictureDrawable"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/AddFolderDialogFragment.java",
    "chars": 4758,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.animation.AnimatorListenerAdapter;\nimport android.app.Activity;\nim"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/Constants.java",
    "chars": 1728,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.content.SharedPreferences;\n\nimport java.util.regex.Matcher;\nimport"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/DirectoryChooserActivity.java",
    "chars": 442,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\n\n/**\n * Created by"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/FolderOptionsDialogFragment.java",
    "chars": 9431,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.animation.AnimatorListenerAdapter;\nimport android.app.Activity;\nim"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/LazyLoadingLinearLayoutManager.kt",
    "chars": 760,
    "preview": "package de.luhmer.owncloudnewsreader\n\nimport android.content.Context\nimport androidx.recyclerview.widget.LinearLayoutMan"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/BlockingExpandableListView.java",
    "chars": 635,
    "preview": "package de.luhmer.owncloudnewsreader.ListView;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastArrayAdapter.java",
    "chars": 4308,
    "preview": "package de.luhmer.owncloudnewsreader.ListView;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/PodcastFeedArrayAdapter.java",
    "chars": 2207,
    "preview": "package de.luhmer.owncloudnewsreader.ListView;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimpo"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ListView/SubscriptionExpandableListAdapter.java",
    "chars": 22969,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/LoginDialogActivity.java",
    "chars": 18355,
    "preview": "/*\n * Android ownCloud News\n *\n * @author David Luhmer\n * @copyright 2013 David Luhmer david-dev@live.de\n *\n * This libr"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewFeedActivity.java",
    "chars": 23996,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport static android.content.pm.PackageManager.PERMISSION_GRANTED;\nimport static"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailActivity.java",
    "chars": 25386,
    "preview": "/*\n* Android ownCloud News\n *\n * @author David Luhmer\n * @copyright 2013 David Luhmer david-dev@live.de\n * <p>\n * This l"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailFragment.java",
    "chars": 21193,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsDetailImageDialogFragment.java",
    "chars": 21450,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport static androidx.core.content.PermissionChecker.checkSelfPermission;\n\nimpor"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderApplication.java",
    "chars": 1124,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.app.Application;\n\nimport de.luhmer.owncloudnewsreader.di.ApiModule"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderDetailFragment.java",
    "chars": 36573,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListActivity.java",
    "chars": 51424,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListDialogFragment.java",
    "chars": 15443,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.animation.AnimatorListenerAdapter;\nimport android.app.Activity;\nim"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderListFragment.java",
    "chars": 14405,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/NewsReaderOPMLImportDialogFragment.java",
    "chars": 3104,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport android.os.Bundle;\nimport android.util.Log;\nimport android.view.LayoutInfl"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PiPVideoPlaybackActivity.java",
    "chars": 9947,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport static de.luhmer.owncloudnewsreader.services.PodcastPlaybackService.CURREN"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragment.java",
    "chars": 24016,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport static android.media.MediaMetadata.METADATA_KEY_MEDIA_ID;\nimport static de"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/PodcastFragmentActivity.java",
    "chars": 15476,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport static de.luhmer.owncloudnewsreader.Constants.MIN_NEXTCLOUD_FILES_APP_VERS"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsActivity.java",
    "chars": 7034,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/SettingsFragment.java",
    "chars": 20937,
    "preview": "package de.luhmer.owncloudnewsreader;\n\nimport static de.luhmer.owncloudnewsreader.Constants.USER_INFO_STRING;\nimport sta"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/VersionInfoDialogFragment.java",
    "chars": 4234,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/HasId.kt",
    "chars": 83,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\ninterface HasId<T> {\n    val id: T\n}\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/NewsListRecyclerAdapter.java",
    "chars": 19142,
    "preview": "package de.luhmer.owncloudnewsreader.adapter;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressBarWebChromeClient.kt",
    "chars": 1118,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.util.Log\nimport android.webkit.ConsoleMessage\nimport androi"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/ProgressViewHolder.kt",
    "chars": 276,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport androidx.recyclerview.widget.RecyclerView\nimport de.luhmer.owncloud"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RecyclerItemClickListener.kt",
    "chars": 260,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\ninterface RecyclerItemClickListener {\n    fun onClick(\n        vh: RssItem"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemCardViewHolder.kt",
    "chars": 1785,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport android.view.View\nimport a"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemFullTextViewHolder.kt",
    "chars": 561,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport com.bumptech.glide.Request"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemHeadlineThumbnailViewHolder.kt",
    "chars": 3609,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport android.view.View\nimport a"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemHeadlineViewHolder.kt",
    "chars": 1792,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport android.view.View\nimport a"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemTextViewHolder.kt",
    "chars": 1792,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport android.view.View\nimport a"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemThumbnailViewHolder.kt",
    "chars": 3436,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport android.view.View\nimport a"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemViewHolder.java",
    "chars": 14267,
    "preview": "package de.luhmer.owncloudnewsreader.adapter;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/adapter/RssItemWebViewHolder.kt",
    "chars": 2364,
    "preview": "package de.luhmer.owncloudnewsreader.adapter\n\nimport android.content.SharedPreferences\nimport android.widget.FrameLayout"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadChangelogTask.java",
    "chars": 5670,
    "preview": "package de.luhmer.owncloudnewsreader.async_tasks;\n\nimport android.content.Context;\nimport android.database.DataSetObserv"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/DownloadImageHandler.java",
    "chars": 2008,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/async_tasks/RssItemToHtmlTask.java",
    "chars": 14865,
    "preview": "package de.luhmer.owncloudnewsreader.async_tasks;\n\nimport static de.luhmer.owncloudnewsreader.NewsDetailActivity.INCOGNI"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/AccountGeneral.java",
    "chars": 780,
    "preview": "package de.luhmer.owncloudnewsreader.authentication;\n\nimport android.content.Context;\n\nimport de.luhmer.owncloudnewsread"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudAccountAuthenticator.java",
    "chars": 5813,
    "preview": "package de.luhmer.owncloudnewsreader.authentication;\n\nimport android.accounts.AbstractAccountAuthenticator;\nimport andro"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/authentication/OwnCloudSyncAdapter.java",
    "chars": 10554,
    "preview": "package de.luhmer.owncloudnewsreader.authentication;\n\nimport android.accounts.Account;\nimport android.content.AbstractTh"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/chrometabs/KeepAliveService.kt",
    "chars": 1033,
    "preview": "// Copyright 2015 Google Inc. All Rights Reserved.\n//\n// Licensed under the Apache License, Version 2.0 (the \"License\");"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseConnectionOrm.java",
    "chars": 40943,
    "preview": "package de.luhmer.owncloudnewsreader.database;\n\nimport static de.luhmer.owncloudnewsreader.ListView.SubscriptionExpandab"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/DatabaseHelperOrm.java",
    "chars": 2145,
    "preview": "/*\n* Android ownCloud News\n *\n * @author David Luhmer\n * @copyright 2013 David Luhmer david-dev@live.de\n *\n * This libra"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/DatabaseOrmGenerator.java",
    "chars": 2279,
    "preview": "package de.luhmer.owncloudnewsreader.database.generator;\n\nimport java.util.ArrayList;\nimport java.util.HashSet;\nimport j"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/LastestVersion.java",
    "chars": 3061,
    "preview": "package de.luhmer.owncloudnewsreader.database.generator;\n\nimport de.greenrobot.daogenerator.Entity;\nimport de.greenrobot"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/generator/SchemaVersion.java",
    "chars": 1182,
    "preview": "package de.luhmer.owncloudnewsreader.database.generator;\n\nimport de.greenrobot.daogenerator.Schema;\n\npublic abstract cla"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemView.java",
    "chars": 999,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\n// THIS CODE IS GENERATED BY greenDAO, EDIT ONLY INSIDE THE \"KEEP\""
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/CurrentRssItemViewDao.java",
    "chars": 3339,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQL"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoMaster.java",
    "chars": 2808,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport android.content.Context;\nimport android.database.sqlite.SQL"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/DaoSession.java",
    "chars": 2591,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport android.database.sqlite.SQLiteDatabase;\n\nimport java.util.M"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/Feed.java",
    "chars": 5755,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport java.util.List;\n\nimport de.greenrobot.dao.DaoException;\n\n//"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FeedDao.java",
    "chars": 10310,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQL"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/Folder.java",
    "chars": 3287,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport java.util.List;\n\nimport de.greenrobot.dao.DaoException;\n\n//"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/FolderDao.java",
    "chars": 3304,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQL"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItem.java",
    "chars": 8271,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport de.greenrobot.dao.DaoException;\nimport de.luhmer.owncloudne"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/database/model/RssItemDao.java",
    "chars": 15944,
    "preview": "package de.luhmer.owncloudnewsreader.database.model;\n\nimport android.database.Cursor;\nimport android.database.sqlite.SQL"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/di/ApiModule.java",
    "chars": 3495,
    "preview": "package de.luhmer.owncloudnewsreader.di;\n\nimport android.app.Application;\nimport android.content.Context;\nimport android"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/di/ApiProvider.java",
    "chars": 4648,
    "preview": "package de.luhmer.owncloudnewsreader.di;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimpo"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/di/AppComponent.java",
    "chars": 2385,
    "preview": "package de.luhmer.owncloudnewsreader.di;\n\nimport javax.inject.Singleton;\n\nimport dagger.Component;\nimport de.luhmer.ownc"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/CollapsePodcastView.java",
    "chars": 91,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class CollapsePodcastView {\n}\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/ExitPlayback.java",
    "chars": 84,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class ExitPlayback {\n}\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/ExpandPodcastView.java",
    "chars": 89,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class ExpandPodcastView {\n}\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/NewPodcastPlaybackListener.java",
    "chars": 98,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class NewPodcastPlaybackListener {\n}\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/PodcastCompletedEvent.java",
    "chars": 93,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class PodcastCompletedEvent {\n}\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/PodcastFeedClicked.kt",
    "chars": 104,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast\n\nclass PodcastFeedClicked(\n    val position: Int,\n)\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/RegisterVideoOutput.java",
    "chars": 412,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\nimport android.view.SurfaceView;\nimport android.view.View;\n\npublic"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/SeekPodcast.java",
    "chars": 212,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class SeekPodcast {\n\n    public double milliSeconds;\n\n    p"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/SpeedPodcast.java",
    "chars": 217,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\n\npublic class SpeedPodcast {\n\n    public SpeedPodcast(float playba"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/StartDownloadPodcast.kt",
    "chars": 168,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast\n\nimport de.luhmer.owncloudnewsreader.model.PodcastItem\n\nclass StartD"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/TogglePlayerStateEvent.java",
    "chars": 369,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class TogglePlayerStateEvent {\n\n    public enum State { Tog"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/events/podcast/WindPodcast.java",
    "chars": 212,
    "preview": "package de.luhmer.owncloudnewsreader.events.podcast;\n\npublic class WindPodcast {\n\n    public double milliSeconds;\n\n    p"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AppCompatPreferenceActivity.java",
    "chars": 3716,
    "preview": "\n\n/*\n * Copyright (C) 2014 The Android Open Source Project\n *\n * Licensed under the Apache License, Version 2.0 (the \"Li"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AsyncTaskHelper.java",
    "chars": 338,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.os.AsyncTask;\n\npublic class AsyncTaskHelper {\n    @SafeVara"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/AutoResizeTextView.java",
    "chars": 10455,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\n/**\n *            DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE\n *          "
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ColorHelper.java",
    "chars": 1685,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.annotation.SuppressLint;\nimport android.content.Context;\nim"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DatabaseUtils.kt",
    "chars": 2050,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/DateTimeFormatter.java",
    "chars": 1455,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.content.Context;\n\nimport java.util.Calendar;\nimport java.ut"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconHandler.java",
    "chars": 5966,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/FavIconUtils.java",
    "chars": 2544,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport java.io.UnsupportedEncodingException;\nimport java.net.URLDecoder;\ni"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ForegroundListener.kt",
    "chars": 1054,
    "preview": "package de.luhmer.owncloudnewsreader.helper\n\nimport android.app.Activity\nimport android.app.Application.ActivityLifecycl"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/GsonConfig.java",
    "chars": 1742,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport com.google.gson.Gson;\nimport com.google.gson.GsonBuilder;\nimport co"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageDownloadFinished.java",
    "chars": 917,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ImageHandler.java",
    "chars": 10095,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NetworkConnection.java",
    "chars": 1717,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NewsFileUtils.java",
    "chars": 8963,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NextcloudGlideModule.kt",
    "chars": 2693,
    "preview": "package de.luhmer.owncloudnewsreader.helper\n\nimport android.content.Context\nimport android.content.SharedPreferences\nimp"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationActionReceiver.java",
    "chars": 1648,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.app.NotificationManager;\nimport android.content.BroadcastRe"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/NotificationActionReceiverDownloadWebPage.java",
    "chars": 944,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.content.BroadcastReceiver;\nimport android.content.Context;\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/OpmlXmlParser.java",
    "chars": 6565,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.content.Context;\nimport android.util.Log;\nimport android.ut"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/PostDelayHandler.java",
    "chars": 2710,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/Search.java",
    "chars": 3890,
    "preview": "package de.luhmer.owncloudnewsreader.helper;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/StopWatch.java",
    "chars": 2099,
    "preview": "/*\nCopyright (c) 2005, Corey Goldberg\n\nStopWatch.java is free software; you can redistribute it and/or modify\nit under t"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ThemeChooser.java",
    "chars": 6873,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/ThemeUtils.java",
    "chars": 4428,
    "preview": "/*\n* Android ownCloud News\n *\n * @author David Luhmer\n * @copyright 2019 David Luhmer david-dev@live.de\n *\n * This libra"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/helper/URLConnectionReader.kt",
    "chars": 688,
    "preview": "@file:JvmName(\"URLConnectionReader\")\n\npackage de.luhmer.owncloudnewsreader.helper\n\nimport java.io.BufferedReader\nimport "
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/interfaces/ExpListTextClicked.java",
    "chars": 1003,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/interfaces/IPlayPausePodcastClicked.java",
    "chars": 221,
    "preview": "package de.luhmer.owncloudnewsreader.interfaces;\n\nimport de.luhmer.owncloudnewsreader.database.model.RssItem;\n\npublic in"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/AbstractItem.java",
    "chars": 1098,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/ConcreteFeedItem.java",
    "chars": 1183,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/CurrentRssViewDataHolder.java",
    "chars": 233,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\nimport java.util.List;\n\nimport de.luhmer.owncloudnewsreader.database.model."
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/FolderSubscribtionItem.java",
    "chars": 1065,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/MediaItem.java",
    "chars": 261,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\nimport java.io.Serializable;\n\npublic abstract class MediaItem implements Se"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/NextcloudNewsVersion.java",
    "chars": 154,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\n/**\n * Created by david on 26.05.17.\n */\n\npublic class NextcloudNewsVersion"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/NextcloudStatus.java",
    "chars": 261,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\n/**\n * Created by david on 26.05.17.\n */\n\npublic class NextcloudStatus {\n\n "
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/OcsUser.java",
    "chars": 1723,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\nimport android.net.Uri;\n\nimport androidx.annotation.Nullable;\n\nimport java."
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastFeedItem.java",
    "chars": 326,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\nimport de.luhmer.owncloudnewsreader.database.model.Feed;\n\npublic class Podc"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/PodcastItem.java",
    "chars": 1020,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\npublic class PodcastItem extends MediaItem {\n\n    public PodcastItem() {\n\n "
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/TTSItem.java",
    "chars": 358,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\npublic class TTSItem extends MediaItem {\n\n    public TTSItem(long itemId, S"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/model/Tuple.java",
    "chars": 243,
    "preview": "package de.luhmer.owncloudnewsreader.model;\n\n// TODO replace with Pair\npublic class Tuple<E, T> {\n    public final E key"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/notification/NextcloudNotificationManager.java",
    "chars": 18349,
    "preview": "package de.luhmer.owncloudnewsreader.notification;\n\nimport static android.app.Notification.EXTRA_NOTIFICATION_ID;\nimport"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/providers/OwnCloudSyncProvider.kt",
    "chars": 1314,
    "preview": "package de.luhmer.owncloudnewsreader.providers\n\nimport android.content.ContentProvider\nimport android.content.ContentVal"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/FeedItemTags.java",
    "chars": 1146,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/InsertIntoDatabase.java",
    "chars": 3438,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/OnAsyncTaskCompletedListener.java",
    "chars": 909,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/IHandleJsonObject.java",
    "chars": 217,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport com.google.gson.JsonObject;\n\n/**\n * Created by david on 2"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/InsertRssItemIntoDatabase.java",
    "chars": 6656,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemIds.java",
    "chars": 440,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport java.util.HashSet;\nimport java.util.Set;\n\n/**\n * Created "
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemMap.java",
    "chars": 929,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport java.util.HashMap;\nimport java.util.HashSet;\nimport java."
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/ItemStateSync.java",
    "chars": 5069,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport android.util.Log;\n\nimport java.io.IOException;\nimport jav"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/NewsAPI.java",
    "chars": 3120,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport com.nextcloud.android.sso.api.EmptyResponse;\n\nimport java"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/NextcloudNewsDeserializer.java",
    "chars": 2867,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport com.google.gson.JsonArray;\nimport com.google.gson.JsonDes"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/NextcloudServerDeserializer.java",
    "chars": 1709,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport com.google.gson.JsonDeserializationContext;\nimport com.go"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/OcsAPI.java",
    "chars": 320,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport de.luhmer.owncloudnewsreader.model.OcsUser;\nimport io.rea"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/RssItemObservable.java",
    "chars": 10972,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\nimport android.content.SharedPreferences;\nimport android.util.Lo"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/reader/nextcloud/Types.java",
    "chars": 464,
    "preview": "package de.luhmer.owncloudnewsreader.reader.nextcloud;\n\n/**\n * Created by david on 24.05.17.\n */\n\npublic enum Types {\n\n "
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadImagesService.java",
    "chars": 6698,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/DownloadWebPageService.java",
    "chars": 12161,
    "preview": "package de.luhmer.owncloudnewsreader.services;\n\nimport android.app.NotificationManager;\nimport android.app.PendingIntent"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudAuthenticatorService.kt",
    "chars": 733,
    "preview": "package de.luhmer.owncloudnewsreader.services\n\nimport android.app.Service\nimport android.content.Intent\nimport android.o"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/OwnCloudSyncService.java",
    "chars": 1555,
    "preview": "package de.luhmer.owncloudnewsreader.services;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport androi"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastDownloadService.java",
    "chars": 8784,
    "preview": "package de.luhmer.owncloudnewsreader.services;\n\nimport android.app.DownloadManager;\nimport android.app.IntentService;\nim"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/PodcastPlaybackService.java",
    "chars": 32482,
    "preview": "package de.luhmer.owncloudnewsreader.services;\n\nimport static android.view.KeyEvent.KEYCODE_MEDIA_STOP;\nimport static de"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/SyncItemStateService.java",
    "chars": 2919,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/events/StopWebArchiveDownloadEvent.kt",
    "chars": 88,
    "preview": "package de.luhmer.owncloudnewsreader.services.events\n\nclass StopWebArchiveDownloadEvent\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/events/SyncFailedEvent.kt",
    "chars": 171,
    "preview": "package de.luhmer.owncloudnewsreader.services.events\n\n/**\n * Created by David on 26.08.2016.\n */\nclass SyncFailedEvent(\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/events/SyncFinishedEvent.kt",
    "chars": 121,
    "preview": "package de.luhmer.owncloudnewsreader.services.events\n\n/**\n * Created by David on 26.08.2016.\n */\nclass SyncFinishedEvent"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/events/SyncStartedEvent.kt",
    "chars": 120,
    "preview": "package de.luhmer.owncloudnewsreader.services.events\n\n/**\n * Created by David on 26.08.2016.\n */\nclass SyncStartedEvent\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/podcast/MediaPlayerPlaybackService.java",
    "chars": 6286,
    "preview": "package de.luhmer.owncloudnewsreader.services.podcast;\n\nimport android.content.Context;\nimport android.media.MediaPlayer"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/podcast/PlaybackService.java",
    "chars": 1874,
    "preview": "package de.luhmer.owncloudnewsreader.services.podcast;\n\nimport android.support.v4.media.session.PlaybackStateCompat;\n\nim"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/services/podcast/TTSPlaybackService.java",
    "chars": 2978,
    "preview": "package de.luhmer.owncloudnewsreader.services.podcast;\n\nimport android.content.Context;\nimport android.speech.tts.TextTo"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/MTMDecision.java",
    "chars": 1539,
    "preview": "package de.luhmer.owncloudnewsreader.ssl;\n\n/* MemorizingTrustManager - a TrustManager which asks the user about invalid\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/MemorizingDialogFragment.java",
    "chars": 3765,
    "preview": "package de.luhmer.owncloudnewsreader.ssl;\n\n/* MemorizingTrustManager - a TrustManager which asks the user about invalid\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/MemorizingTrustManager.java",
    "chars": 18005,
    "preview": "package de.luhmer.owncloudnewsreader.ssl;\n\n/* MemorizingTrustManager - a TrustManager which asks the user about invalid\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/OkHttpSSLClient.java",
    "chars": 5949,
    "preview": "package de.luhmer.owncloudnewsreader.ssl;\n\nimport android.annotation.SuppressLint;\nimport android.content.SharedPreferen"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/ssl/TLSSocketFactory.kt",
    "chars": 2121,
    "preview": "package de.luhmer.owncloudnewsreader.ssl\n\nimport java.io.IOException\nimport java.net.InetAddress\nimport java.net.Socket\n"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/AnimatingProgressBar.java",
    "chars": 3865,
    "preview": "package de.luhmer.owncloudnewsreader.view;\n\nimport android.animation.ValueAnimator;\nimport android.content.Context;\nimpo"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/ChangeLogFileListView.kt",
    "chars": 828,
    "preview": "package de.luhmer.owncloudnewsreader.view\n\nimport android.content.Context\nimport android.util.AttributeSet\nimport it.gma"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastNotification.java",
    "chars": 6960,
    "preview": "package de.luhmer.owncloudnewsreader.view;\n\nimport android.app.Notification;\nimport android.app.NotificationManager;\nimp"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/view/PodcastSlidingUpPanelLayout.java",
    "chars": 3493,
    "preview": "package de.luhmer.owncloudnewsreader.view;\n\nimport android.content.Context;\nimport android.util.AttributeSet;\nimport and"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/widget/WidgetNewsViewsFactory.java",
    "chars": 7400,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/widget/WidgetProvider.java",
    "chars": 10336,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/java/de/luhmer/owncloudnewsreader/widget/WidgetService.kt",
    "chars": 1054,
    "preview": "/*\n* Android ownCloud News\n*\n* @author David Luhmer\n* @copyright 2013 David Luhmer david-dev@live.de\n*\n* This library is"
  },
  {
    "path": "News-Android-App/src/main/res/anim/all_read_success.xml",
    "chars": 594,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<set xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <scale\n     "
  },
  {
    "path": "News-Android-App/src/main/res/anim/slide_in_left.xml",
    "chars": 870,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright 2015 Google Inc. All Rights Reserved.\n\n     Licensed under the Apa"
  },
  {
    "path": "News-Android-App/src/main/res/anim/slide_in_right.xml",
    "chars": 869,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright 2015 Google Inc. All Rights Reserved.\n\n     Licensed under the Apa"
  },
  {
    "path": "News-Android-App/src/main/res/anim/slide_out_left.xml",
    "chars": 870,
    "preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!-- Copyright 2015 Google Inc. All Rights Reserved.\n\n     Licensed under the Apa"
  }
]

// ... and 280 more files (download for full content)

About this extraction

This page contains the full source code of the owncloud/News-Android-App GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 480 files (2.3 MB), approximately 641.3k tokens, and a symbol index with 1531 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!